|
@@ -6,6 +6,7 @@ import (
|
|
|
"strings"
|
|
|
)
|
|
|
|
|
|
+
|
|
|
type AstKind int
|
|
|
|
|
|
const (
|
|
@@ -30,8 +31,10 @@ const (
|
|
|
AstKindEnd
|
|
|
AstKindError
|
|
|
)
|
|
|
+*/
|
|
|
|
|
|
-func (astkind AstKind) String() string {
|
|
|
+
|
|
|
+func (BasicAst Ast) String() string {
|
|
|
switch astkind {
|
|
|
case AstKindProgram:
|
|
|
return "AstKindProgram"
|
|
@@ -77,118 +80,121 @@ func (astkind AstKind) String() string {
|
|
|
return "Unknown AstKind"
|
|
|
}
|
|
|
}
|
|
|
+*/
|
|
|
+
|
|
|
+type Ast interface {
|
|
|
+ Parent() Ast
|
|
|
+ Children() []Ast
|
|
|
+
|
|
|
+ Run(vm *VM, val ListValue) ListValue
|
|
|
+ String() string
|
|
|
+ Token() Token
|
|
|
+
|
|
|
+ NewChild(kind AstKind, token Token) Ast
|
|
|
+ */
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+func AstAppendChild(parent Ast, child Ast) Ast {
|
|
|
+ basicParent := parent.(*BasicAst)
|
|
|
+ return basicParent.AppendChild(child)
|
|
|
+}
|
|
|
+
|
|
|
+func AstNewChild(parent Ast, kind AstKind, token Token) Ast {
|
|
|
+ basicParent := parent.(*BasicAst)
|
|
|
+ return basicParent.NewChild(kind, token)
|
|
|
+}
|
|
|
+*/
|
|
|
|
|
|
|
|
|
-type Ast struct {
|
|
|
- Parent *Ast
|
|
|
- Child *Ast
|
|
|
- Before *Ast
|
|
|
- After *Ast
|
|
|
- AstKind
|
|
|
- *Token
|
|
|
+type BasicAst struct {
|
|
|
+ parent Ast
|
|
|
+ children []Ast
|
|
|
+ token Token
|
|
|
}
|
|
|
|
|
|
-func NewAst(kind AstKind, parent *Ast, token *Token) *Ast {
|
|
|
- child := &Ast{parent, nil, nil, nil, kind, token}
|
|
|
+var _ Ast = &BasicAst{}
|
|
|
+
|
|
|
+func NewAst(kind AstKind, parent Ast, children []Ast, token Token) Ast {
|
|
|
+ ast := kind(parent, children, token)
|
|
|
+ return ast
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+func (ast *BasicAst) AppendChild(child Ast) Ast {
|
|
|
+ ast.children = append(ast.children, child)
|
|
|
return child
|
|
|
}
|
|
|
|
|
|
-func (ast *Ast) LastSibling() *Ast {
|
|
|
- res := ast
|
|
|
- for res != nil && res.After != nil {
|
|
|
- res = res.After
|
|
|
- }
|
|
|
- return res
|
|
|
+func (ast *BasicAst) NewChild(kind AstKind, token Token) Ast {
|
|
|
+ child := NewAst(kind, ast, token)
|
|
|
+ ast.AppendChild(child)
|
|
|
+ return child
|
|
|
}
|
|
|
+*/
|
|
|
|
|
|
-func (ast *Ast) LastChild() *Ast {
|
|
|
- return ast.Child.LastSibling()
|
|
|
+func (ast BasicAst) IsError() bool {
|
|
|
+ return false
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-func (ast *Ast) Remove() *Ast {
|
|
|
- parent := ast.Parent
|
|
|
- before := ast.Before
|
|
|
- after := ast.After
|
|
|
- if before != nil {
|
|
|
- before.After = after
|
|
|
- }
|
|
|
- if after != nil {
|
|
|
- after.Before = before
|
|
|
- }
|
|
|
- if parent != nil {
|
|
|
-
|
|
|
- if ast == parent.Child {
|
|
|
- parent.Child = after
|
|
|
- }
|
|
|
- }
|
|
|
- ast.Parent = nil
|
|
|
- return ast
|
|
|
+func (ast AstError) IsError() bool {
|
|
|
+ return true
|
|
|
}
|
|
|
|
|
|
-func (ast *Ast) InsertSibling(sibling *Ast) *Ast {
|
|
|
- after := ast.After
|
|
|
- ast.After = sibling
|
|
|
- sibling.Before = ast
|
|
|
- sibling.After = after
|
|
|
- if after != nil {
|
|
|
- after.Before = sibling
|
|
|
- }
|
|
|
- sibling.Parent = ast.Parent
|
|
|
- return sibling
|
|
|
+func (ast BasicAst) Token() Token {
|
|
|
+ return ast.token
|
|
|
}
|
|
|
|
|
|
-func (ast *Ast) AppendSibling(sibling *Ast) *Ast {
|
|
|
- return ast.LastSibling().InsertSibling(sibling)
|
|
|
+func (ast BasicAst) Parent() Ast {
|
|
|
+ return ast.parent
|
|
|
}
|
|
|
|
|
|
-func (ast *Ast) AppendChild(child *Ast) *Ast {
|
|
|
- child.Parent = ast
|
|
|
- if ast.Child == nil {
|
|
|
- ast.Child = child
|
|
|
- } else {
|
|
|
- ast.Child.AppendSibling(child)
|
|
|
- }
|
|
|
- return child
|
|
|
+func (ast BasicAst) Children() []Ast {
|
|
|
+ return ast.children
|
|
|
+}
|
|
|
+
|
|
|
+func (ast *BasicAst) SetParent(parent Ast) {
|
|
|
+ ast.parent = parent
|
|
|
}
|
|
|
|
|
|
-func (ast *Ast) NewSibling(kind AstKind, token *Token) *Ast {
|
|
|
- sibling := NewAst(kind, ast.Parent, token)
|
|
|
- return ast.AppendSibling(sibling)
|
|
|
+func (ast BasicAst) Child(index int) Ast {
|
|
|
+ count := ast.CountChildren()
|
|
|
+ if index < 0 || index > count {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ return ast.children[index]
|
|
|
}
|
|
|
|
|
|
-func (ast *Ast) NewChild(kind AstKind, token *Token) *Ast {
|
|
|
- sibling := NewAst(kind, ast.Parent, token)
|
|
|
- return ast.AppendChild(sibling)
|
|
|
+func (ast BasicAst) Run(vm *VM, val ListValue) ListValue {
|
|
|
+ panic("Please implement Run for this node.")
|
|
|
+ return ListValue{}
|
|
|
}
|
|
|
|
|
|
-func (ast *Ast) Walk(walker func(node *Ast) *Ast) *Ast {
|
|
|
+func (ast *BasicAst) Walk(walker func(node Ast) Ast) Ast {
|
|
|
if found := walker(ast); found != nil {
|
|
|
return found
|
|
|
}
|
|
|
- if ast.Child != nil {
|
|
|
- if found := ast.Child.Walk(walker); found != nil {
|
|
|
- return found
|
|
|
- }
|
|
|
- }
|
|
|
- if ast.After != nil {
|
|
|
- if found := ast.After.Walk(walker); found != nil {
|
|
|
+ for _, child := range ast.children {
|
|
|
+ if found := child.(*BasicAst).Walk(walker); found != nil {
|
|
|
return found
|
|
|
}
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func (ast *Ast) String() string {
|
|
|
+func (ast BasicAst) String() string {
|
|
|
if ast.Token == nil {
|
|
|
- return fmt.Sprintf("Ast %s nil", ast.AstKind.String())
|
|
|
+ return fmt.Sprintf("BasicAst %s nil", ast.token.String())
|
|
|
}
|
|
|
- return fmt.Sprintf("Ast %s %v", ast.AstKind.String(), ast.Token.String())
|
|
|
+ return fmt.Sprintf("BasicAst %v", ast.token.String())
|
|
|
}
|
|
|
|
|
|
-func (ast *Ast) Display() {
|
|
|
- ast.Walk(func(node *Ast) *Ast {
|
|
|
- depth := node.Depth()
|
|
|
+func (ast BasicAst) Display() {
|
|
|
+ ast.Walk(func(node Ast) Ast {
|
|
|
+ bast := node.(*BasicAst)
|
|
|
+ depth := bast.Depth()
|
|
|
fmt.Printf(strings.Repeat("--", depth))
|
|
|
if node != nil {
|
|
|
fmt.Printf("Ast: %s\n", node.String())
|
|
@@ -199,36 +205,167 @@ func (ast *Ast) Display() {
|
|
|
})
|
|
|
}
|
|
|
|
|
|
-func (ast *Ast) Depth() int {
|
|
|
+func (ast BasicAst) Depth() int {
|
|
|
var depth int = 0
|
|
|
- parent := ast.Parent
|
|
|
+ parent := ast.parent
|
|
|
for parent != nil {
|
|
|
depth++
|
|
|
- parent = parent.Parent
|
|
|
+ parent = parent.Parent()
|
|
|
}
|
|
|
return depth
|
|
|
}
|
|
|
|
|
|
-func (ast *Ast) CountChildren() int {
|
|
|
- var count int = 0
|
|
|
- child := ast.Child
|
|
|
- for child != nil {
|
|
|
- count++
|
|
|
- child = child.After
|
|
|
- }
|
|
|
- return count
|
|
|
+func (ast BasicAst) CountChildren() int {
|
|
|
+ return len(ast.children)
|
|
|
}
|
|
|
|
|
|
-func (ast *Ast) Errors() []*Ast {
|
|
|
- res := make([]*Ast, 0)
|
|
|
- if ast == nil {
|
|
|
- return res
|
|
|
- }
|
|
|
- ast.Walk(func(node *Ast) *Ast {
|
|
|
- if node != nil && node.AstKind == AstKindError {
|
|
|
+func AstIsError(ast Ast) bool {
|
|
|
+ _, isError := ast.(*AstError)
|
|
|
+ return isError
|
|
|
+}
|
|
|
+
|
|
|
+func (ast BasicAst) Errors() []Ast {
|
|
|
+ res := make([]Ast, 0)
|
|
|
+ ast.Walk(func(node Ast) Ast {
|
|
|
+ if node != nil && ast.IsError() {
|
|
|
res = append(res, node)
|
|
|
}
|
|
|
return nil
|
|
|
})
|
|
|
return res
|
|
|
}
|
|
|
+
|
|
|
+func EmptyAstArray() []Ast {
|
|
|
+ return make([]Ast, 0)
|
|
|
+}
|
|
|
+
|
|
|
+type AstProgram struct{ BasicAst }
|
|
|
+type AstStatements struct{ BasicAst }
|
|
|
+type AstStatement struct{ BasicAst }
|
|
|
+type AstSet struct{ BasicAst }
|
|
|
+type AstGet struct{ BasicAst }
|
|
|
+type AstTarget struct{ BasicAst }
|
|
|
+type AstCommand struct{ BasicAst }
|
|
|
+type AstArguments struct{ BasicAst }
|
|
|
+type AstArgument struct{ BasicAst }
|
|
|
+type AstExpression struct{ BasicAst }
|
|
|
+type AstBlock struct{ BasicAst }
|
|
|
+type AstParenthesis struct{ BasicAst }
|
|
|
+type AstList struct{ BasicAst }
|
|
|
+type AstCapture struct{ BasicAst }
|
|
|
+type AstWordValue struct{ BasicAst }
|
|
|
+type AstWord struct{ BasicAst }
|
|
|
+type AstType struct{ BasicAst }
|
|
|
+type AstValue struct{ BasicAst }
|
|
|
+type AstEnd struct{ BasicAst }
|
|
|
+type AstError struct{ BasicAst }
|
|
|
+
|
|
|
+func (ast AstProgram) String() string { return "AstProgram " }
|
|
|
+func (ast AstStatements) String() string { return "AstStatements " }
|
|
|
+func (ast AstStatement) String() string { return "AstStatement " }
|
|
|
+func (ast AstSet) String() string { return "AstSet " }
|
|
|
+func (ast AstGet) String() string { return "AstGet " }
|
|
|
+func (ast AstTarget) String() string { return "AstTarget " }
|
|
|
+func (ast AstCommand) String() string { return "AstCommand " }
|
|
|
+func (ast AstArguments) String() string { return "AstArguments " }
|
|
|
+func (ast AstArgument) String() string { return "AstArgument " }
|
|
|
+func (ast AstExpression) String() string { return "AstExpression " }
|
|
|
+func (ast AstBlock) String() string { return "AstBlock " }
|
|
|
+func (ast AstParenthesis) String() string { return "AstParenthesis" }
|
|
|
+func (ast AstList) String() string { return "AstList " }
|
|
|
+func (ast AstCapture) String() string { return "AstCapture " }
|
|
|
+func (ast AstWordValue) String() string { return "AstWordValue " }
|
|
|
+func (ast AstWord) String() string { return "AstWord " }
|
|
|
+func (ast AstType) String() string { return "AstType " }
|
|
|
+func (ast AstValue) String() string { return "AstValue " }
|
|
|
+func (ast AstEnd) String() string { return "AstEnd " }
|
|
|
+func (ast AstError) String() string { return "AstError " }
|
|
|
+
|
|
|
+var _ Ast = AstProgram{}
|
|
|
+
|
|
|
+func NewBasicAst(parent Ast, children []Ast, token Token) BasicAst {
|
|
|
+ return BasicAst{parent, children, token}
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+getting scared. :) */
|
|
|
+
|
|
|
+type AstKind func(parent Ast, children []Ast, token Token) Ast
|
|
|
+
|
|
|
+type AstKind2 interface {
|
|
|
+ New(parent Ast, children []Ast, token Token) Ast
|
|
|
+}
|
|
|
+
|
|
|
+type AstTypeProgramImp struct{}
|
|
|
+
|
|
|
+func (ap AstTypeProgramImp) New(parent Ast, children []Ast, token Token) Ast {
|
|
|
+ return AstProgram{NewBasicAst(parent, children, token)}
|
|
|
+}
|
|
|
+
|
|
|
+func NewAstProgram(parent Ast, children []Ast, token Token) Ast {
|
|
|
+ return AstProgram{NewBasicAst(parent, children, token)}
|
|
|
+}
|
|
|
+
|
|
|
+var AstKindBasic = AstKind(func(parent Ast, children []Ast, token Token) Ast { return NewBasicAst(parent, children, token) })
|
|
|
+
|
|
|
+var AstKindProgram = AstKind(NewAstProgram)
|
|
|
+var AstKindProgram2 = AstKind2(AstTypeProgramImp{})
|
|
|
+
|
|
|
+var AstKindStatements = AstKind(func(parent Ast, children []Ast, token Token) Ast {
|
|
|
+ return &AstStatements{NewBasicAst(parent, children, token)}
|
|
|
+})
|
|
|
+
|
|
|
+var AstKindStatement = AstKind(func(parent Ast, children []Ast, token Token) Ast {
|
|
|
+ return &AstStatement{NewBasicAst(parent, children, token)}
|
|
|
+})
|
|
|
+var AstKindSet = AstKind(func(parent Ast, children []Ast, token Token) Ast {
|
|
|
+ return &AstSet{NewBasicAst(parent, children, token)}
|
|
|
+})
|
|
|
+var AstKindGet = AstKind(func(parent Ast, children []Ast, token Token) Ast {
|
|
|
+ return &AstGet{NewBasicAst(parent, children, token)}
|
|
|
+})
|
|
|
+var AstKindTarget = AstKind(func(parent Ast, children []Ast, token Token) Ast {
|
|
|
+ return &AstTarget{NewBasicAst(parent, children, token)}
|
|
|
+})
|
|
|
+var AstKindCommand = AstKind(func(parent Ast, children []Ast, token Token) Ast {
|
|
|
+ return &AstCommand{NewBasicAst(parent, children, token)}
|
|
|
+})
|
|
|
+var AstKindArguments = AstKind(func(parent Ast, children []Ast, token Token) Ast {
|
|
|
+ return &AstArguments{NewBasicAst(parent, children, token)}
|
|
|
+})
|
|
|
+var AstKindArgument = AstKind(func(parent Ast, children []Ast, token Token) Ast {
|
|
|
+ return &AstArgument{NewBasicAst(parent, children, token)}
|
|
|
+})
|
|
|
+var AstKindExpression = AstKind(func(parent Ast, children []Ast, token Token) Ast {
|
|
|
+ return &AstExpression{NewBasicAst(parent, children, token)}
|
|
|
+})
|
|
|
+var AstKindBlock = AstKind(func(parent Ast, children []Ast, token Token) Ast {
|
|
|
+ return &AstBlock{NewBasicAst(parent, children, token)}
|
|
|
+})
|
|
|
+var AstKindParenthesis = AstKind(func(parent Ast, children []Ast, token Token) Ast {
|
|
|
+ return &AstParenthesis{NewBasicAst(parent, children, token)}
|
|
|
+})
|
|
|
+var AstKindList = AstKind(func(parent Ast, children []Ast, token Token) Ast {
|
|
|
+ return &AstList{NewBasicAst(parent, children, token)}
|
|
|
+})
|
|
|
+var AstKindCapture = AstKind(func(parent Ast, children []Ast, token Token) Ast {
|
|
|
+ return &AstCapture{NewBasicAst(parent, children, token)}
|
|
|
+})
|
|
|
+var AstKindWordValue = AstKind(func(parent Ast, children []Ast, token Token) Ast {
|
|
|
+ return &AstWordValue{NewBasicAst(parent, children, token)}
|
|
|
+})
|
|
|
+var AstKindWord = AstKind(func(parent Ast, children []Ast, token Token) Ast {
|
|
|
+ return &AstWord{NewBasicAst(parent, children, token)}
|
|
|
+})
|
|
|
+var AstKindType = AstKind(func(parent Ast, children []Ast, token Token) Ast {
|
|
|
+ return &AstType{NewBasicAst(parent, children, token)}
|
|
|
+})
|
|
|
+var AstKindValue = AstKind(func(parent Ast, children []Ast, token Token) Ast {
|
|
|
+ return &AstValue{NewBasicAst(parent, children, token)}
|
|
|
+})
|
|
|
+var AstKindEnd = AstKind(func(parent Ast, children []Ast, token Token) Ast {
|
|
|
+ return &AstEnd{NewBasicAst(parent, children, token)}
|
|
|
+})
|
|
|
+var AstKindError = AstKind(func(parent Ast, children []Ast, token Token) Ast {
|
|
|
+ return &AstError{NewBasicAst(parent, children, token)}
|
|
|
+})
|