1
0
Fork 0
penny/ast/ast.go

613 lines
8.9 KiB
Go

package ast
import (
"strconv"
"github.com/localhots/penny/token"
)
// Basics
type (
IoNumber int
Word string
Attrib interface{}
)
func NewWord(word Attrib) (Word, error) {
lit := word.(*token.Token).Lit
return Word(lit), nil
}
func NewIoNumber(number Attrib) (IoNumber, error) {
lit := number.(*token.Token).Lit
n, err := strconv.Atoi(string(lit))
return IoNumber(n), err
}
// Assignment
type (
Assignment struct {
a, b Word
}
)
func NewAssignment(a, b Attrib) (*Assignment, error) {
return &Assignment{a.(Word), b.(Word)}, nil
}
// List
type (
List []*AndOr
)
func NewList(ao Attrib) (List, error) {
return List{ao.(*AndOr)}, nil
}
func AppendToList(list Attrib, el Attrib) (List, error) {
l := list.(List)
l = append(l, el.(*AndOr))
return l, nil
}
// AndOr
type (
Logic int
AndOrStmt []*AndOr
AndOr struct {
op Logic
p *Pipeline
}
)
const (
L_FIRST Logic = iota
L_AND
L_OR
)
func NewAndOr(p Attrib) (AndOrStmt, error) {
return AndOrStmt{&AndOr{L_FIRST, p.(*Pipeline)}}, nil
}
func AppendAnd(stmt Attrib, p Attrib) (AndOrStmt, error) {
pp := stmt.(AndOrStmt)
pp = append(pp, &AndOr{L_AND, p.(*Pipeline)})
return pp, nil
}
func AppendOr(stmt Attrib, p Attrib) (AndOrStmt, error) {
pp := stmt.(AndOrStmt)
pp = append(pp, &AndOr{L_OR, p.(*Pipeline)})
return pp, nil
}
// Pipeline
type (
Pipeline struct {
seq PipeSequence
inverse bool
}
)
func NewPipeline(seq Attrib, inverse bool) (*Pipeline, error) {
return &Pipeline{seq.(PipeSequence), inverse}, nil
}
// PipeSequence
type (
PipeSequence []Command
)
func NewPipeSequence(cmd Attrib) (PipeSequence, error) {
return PipeSequence{cmd.(*Command)}, nil
}
func AppendToPipeSequence(ps Attrib, cmd Attrib) (PipeSequence, error) {
ps1 := ps.(PipeSequence)
ps1 = append(ps1, cmd.(Command))
return ps1, nil
}
// Command
type (
Command interface{}
)
func NewCommand(cmd Attrib, rl Attrib) (Command, error) {
return Command(cmd), nil
}
// CompoundCommand
type (
CompoundCommand interface{}
)
func NewCompoundCommand(cmd Attrib) (CompoundCommand, error) {
return CompoundCommand(cmd), nil
}
// Subshell
type (
Subshell struct {
cc CompoundCommand
}
)
func NewSubshell(cc Attrib) (*Subshell, error) {
return &Subshell{cc.(CompoundCommand)}, nil
}
// CompoundList
type (
CompoundList struct {
term *Term
sep *Separator
}
)
func NewCompoundList(term Attrib, sep Attrib) (*CompoundList, error) {
return &CompoundList{term.(*Term), sep.(*Separator)}, nil
}
// Term
type (
Term []*TermItem
TermItem struct {
ao AndOrStmt
sep *Separator
}
)
func NewTerm(ao Attrib) (Term, error) {
return Term{&TermItem{ao.(AndOrStmt), nil}}, nil
}
func AppendToTerm(term Attrib, ao Attrib, sep Attrib) (Term, error) {
t := term.(Term)
t = append(t, &TermItem{ao.(AndOrStmt), sep.(*Separator)})
return t, nil
}
// ForClause
type (
ForClause struct {
name Name
wl Wordlist
dg *DoGroup
}
)
func NewForClause(name Attrib, wl Attrib, dg Attrib) (*ForClause, error) {
return &ForClause{
name: name.(Name),
wl: wl.(Wordlist),
dg: dg.(*DoGroup),
}, nil
}
// Name
type (
Name Word
)
func NewName(w Attrib) (Name, error) {
return Name(w.(Word)), nil
}
// Wordlist
type (
Wordlist []Word
)
func NewWordlist(w Attrib) (Wordlist, error) {
return Wordlist{w.(Word)}, nil
}
func AppendToWordlist(wl Attrib, w Attrib) (Wordlist, error) {
wl1 := wl.(Wordlist)
wl1 = append(wl1, w.(Word))
return wl1, nil
}
// CaseClause
type (
CaseClause struct {
word Word
cl CaseList
}
)
func NewCaseClause(word Attrib, cl Attrib) (*CaseClause, error) {
return &CaseClause{
word: word.(Word),
cl: cl.(CaseList),
}, nil
}
// CaseListNs
// CaseList
type (
CaseList []*CaseItem
)
func NewCaseList(ci Attrib) (CaseList, error) {
return CaseList{ci.(*CaseItem)}, nil
}
func AppendToCaseList(cl Attrib, ci Attrib) (CaseList, error) {
cl1 := cl.(CaseList)
cl1 = append(cl1, ci.(*CaseItem))
return cl1, nil
}
// CaseItemNs
// CaseItem
type (
CaseItem struct {
p Pattern
cl *CompoundList
}
)
func NewCaseItem(p Attrib, cl Attrib) (*CaseItem, error) {
return &CaseItem{
p: p.(Pattern),
cl: cl.(*CompoundList),
}, nil
}
// Pattern
type (
Pattern []Word
)
func NewPattern(w Attrib) (Pattern, error) {
return Pattern{w.(Word)}, nil
}
func AppendToPattern(p Attrib, w Attrib) (Pattern, error) {
p1 := p.(Pattern)
p1 = append(p1, w.(Word))
return p1, nil
}
// IfClause
// ElsePart
type (
IfClause struct {
cond *CompoundList
action *CompoundList
elsep *IfClause
}
)
func NewIfClause(cond Attrib, action Attrib, elsep Attrib) (*IfClause, error) {
return &IfClause{
cond: cond.(*CompoundList),
action: action.(*CompoundList),
elsep: elsep.(*IfClause),
}, nil
}
// WhileClause
type (
WhileClause struct {
cond *CompoundList
dg *DoGroup
}
)
func NewWhileClause(cond Attrib, dg Attrib) (*WhileClause, error) {
return &WhileClause{
cond: cond.(*CompoundList),
dg: dg.(*DoGroup),
}, nil
}
// UntilClause
type (
UntilClause struct {
cond *CompoundList
dg *DoGroup
}
)
func NewUntilClause(cond Attrib, dg Attrib) (*UntilClause, error) {
return &UntilClause{
cond: cond.(*CompoundList),
dg: dg.(*DoGroup),
}, nil
}
// FunctionDefinition
type (
FunctionDefinition struct {
name FunctionName
body *FunctionBody
}
)
func NewFunctionDefinition(name Attrib, body Attrib) (*FunctionDefinition, error) {
return &FunctionDefinition{
name: name.(FunctionName),
body: body.(*FunctionBody),
}, nil
}
// FunctionBody
type (
FunctionBody struct {
cc CompoundCommand
rl RedirectList
}
)
func NewFunctionBody(cc Attrib, rl Attrib) (*FunctionBody, error) {
return &FunctionBody{
cc: cc.(CompoundCommand),
rl: rl.(RedirectList),
}, nil
}
// FunctionName
type (
FunctionName Word
)
func NewFunctionName(w Attrib) (FunctionName, error) {
return FunctionName(w.(Word)), nil
}
// BraceGroup
type (
BraceGroup struct {
cl *CompoundList
}
)
func NewBraceGroup(cl Attrib) (*BraceGroup, error) {
return &BraceGroup{
cl: cl.(*CompoundList),
}, nil
}
// DoGroup
type (
DoGroup struct {
cl *CompoundList
}
)
func NewDoGroup(cl Attrib) (*DoGroup, error) {
return &DoGroup{cl.(*CompoundList)}, nil
}
// SimpleCommand
type (
SimpleCommand struct {
prefix *CmdPrefix
name Name
word Word
suffix *CmdSuffix
}
)
func NewSimpleCommand(prefix, name, word, suffix Attrib) (*SimpleCommand, error) {
return &SimpleCommand{
prefix: prefix.(*CmdPrefix),
name: name.(Name),
word: word.(Word),
suffix: suffix.(*CmdSuffix),
}, nil
}
// CmdName
type (
CmdName Word
)
func NewCmdName(w Attrib) (CmdName, error) {
return CmdName(w.(Word)), nil
}
// CmdWord
type (
CmdWord Word
)
func NewCmdWord(w Attrib) (CmdWord, error) {
return CmdWord(w.(Word)), nil
}
// CmdPrefix
type (
CmdPrefix struct {
assign *Assignment
redir *IoRedirect
prefix *CmdPrefix
}
)
func NewCmdPrefix(assign, redir, prefix Attrib) (*CmdPrefix, error) {
return &CmdPrefix{
assign: assign.(*Assignment),
redir: assign.(*IoRedirect),
prefix: prefix.(*CmdPrefix),
}, nil
}
// CmdSuffix
type (
CmdSuffix struct {
word Word
redir *IoRedirect
suffix *CmdSuffix
}
)
func NewCmdSuffix(word, redir, suffix Attrib) (*CmdSuffix, error) {
return &CmdSuffix{
word: word.(Word),
redir: redir.(*IoRedirect),
suffix: suffix.(*CmdSuffix),
}, nil
}
// RedirectList
type (
RedirectList []*IoRedirect
)
func NewRedirectList(redir Attrib) (RedirectList, error) {
return RedirectList{redir.(*IoRedirect)}, nil
}
func AppendToRedirectList(list Attrib, el Attrib) (RedirectList, error) {
l := list.(RedirectList)
l = append(l, el.(*IoRedirect))
return l, nil
}
// IoRedirect
type (
IoRedirect struct {
file *IoFile
num IoNumber
here *IoHere
}
)
func NewIoRedirect(file Attrib, num Attrib, here Attrib) (*IoRedirect, error) {
return &IoRedirect{
file: file.(*IoFile),
num: num.(IoNumber),
here: here.(*IoHere),
}, nil
}
// IoFile
type (
Redirection int
IoFile struct {
file Filename
redir Redirection
}
)
const (
R_STDIN Redirection = iota
R_INFD
R_STDOUT
R_OUTFD
R_APPEND
R_ORWFD
R_OUTSP
)
func NewIoFile(file Attrib, redir Redirection) (*IoFile, error) {
return &IoFile{
file: file.(Filename),
redir: redir,
}, nil
}
// Filename
type (
Filename Word
)
func NewFilename(w Attrib) (Filename, error) {
return Filename(w.(Word)), nil
}
// IoHere
type (
IoHere struct {
word Word
suppressTabs bool
}
)
func NewIoHere(w Attrib, st bool) (*IoHere, error) {
return &IoHere{
word: w.(Word),
suppressTabs: st,
}, nil
}
// HereEnd
type (
HereEnd Word
)
func NewHereEnd(w Attrib) (HereEnd, error) {
return HereEnd(w.(Word)), nil
}
// NewlineList
// Linebreak
// SeparatorOp
type (
SeparatorOp int
)
const (
S_AMP SeparatorOp = iota
S_SEMICOLON
)
// Separartor
type (
Separator struct {
s SeparatorOp
}
)
func NewSeparator(op Attrib) (*Separator, error) {
return &Separator{op.(SeparatorOp)}, nil
}
// SequentialSep