123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606 |
- // Abstract Syntax tree for the MUESLI interpreter
- package muesli
- import (
- "fmt"
- "strings"
- )
- type AstBasicMetaKind string
- type AstMetaKindNone AstBasicMetaKind
- type AstMetaKindProgram AstBasicMetaKind
- type AstMetaKindStatements AstBasicMetaKind
- type AstMetaKindStatement AstBasicMetaKind
- type AstMetaKindClosed AstBasicMetaKind
- type AstMetaKindSet AstBasicMetaKind
- type AstMetaKindGet AstBasicMetaKind
- type AstMetaKindTarget AstBasicMetaKind
- type AstMetaKindCommand AstBasicMetaKind
- type AstMetaKindArguments AstBasicMetaKind
- type AstMetaKindArgument AstBasicMetaKind
- type AstMetaKindExpression AstBasicMetaKind
- type AstMetaKindBlock AstBasicMetaKind
- type AstMetaKindParenthesis AstBasicMetaKind
- type AstMetaKindList AstBasicMetaKind
- type AstMetaKindCapture AstBasicMetaKind
- type AstMetaKindWordValue AstBasicMetaKind
- type AstMetaKindWord AstBasicMetaKind
- type AstMetaKindType AstBasicMetaKind
- type AstMetaKindValue AstBasicMetaKind
- type AstMetaKindEnd AstBasicMetaKind
- type AstMetaKindError AstBasicMetaKind
- type AstMetaKindFlatten AstBasicMetaKind
- /** The actual types are defined as constants, the meta types are used to be able to have different behavior for them.*/
- const (
- AstKindNone = AstMetaKindNone("None")
- AstKindProgram = AstMetaKindProgram("Program")
- AstKindStatements = AstMetaKindStatements("Statements")
- AstKindStatement = AstMetaKindStatement("Statement")
- // AstKindClosed = AstMetaKindClosed("Closed")
- AstKindSet = AstMetaKindSet("Set")
- AstKindGet = AstMetaKindGet("Get")
- AstKindTarget = AstMetaKindTarget("Target")
- AstKindCommand = AstMetaKindCommand("Command")
- AstKindArguments = AstMetaKindArguments("Arguments")
- // AstKindArgument = AstMetaKindArgument("Argument")
- // AstKindExpression = AstMetaKindExpression("Expression")
- AstKindBlock = AstMetaKindBlock("Block")
- AstKindParenthesis = AstMetaKindParenthesis("Parenthesis")
- AstKindList = AstMetaKindList("List")
- // AstKindCapture = AstMetaKindCapture("Capture")
- AstKindWordValue = AstMetaKindWordValue("WordValue")
- AstKindWord = AstMetaKindWord("Word")
- AstKindType = AstMetaKindType("Type")
- AstKindValue = AstMetaKindValue("Value")
- AstKindEnd = AstMetaKindEnd("End")
- AstKindError = AstMetaKindError("Error")
- // AstKindFlatten is a special ast kind that insruct the parser not to generate a token
- AstKindFlatten = AstMetaKindFlatten("Flatten")
- )
- func (astkind AstBasicMetaKind) String() string {
- return string(astkind)
- }
- func (astkind AstBasicMetaKind) Run(vm *VM, ast Ast, val ...Value) []Value {
- return []Value{}
- }
- func (astkind AstMetaKindNone) String() string { return "AstNone " }
- func (astkind AstMetaKindProgram) String() string { return "AstProgram " }
- func (astkind AstMetaKindStatements) String() string { return "AstStatements " }
- func (astkind AstMetaKindStatement) String() string { return "AstStatement " }
- func (astkind AstMetaKindClosed) String() string { return "AstClosed " }
- func (astkind AstMetaKindSet) String() string { return "AstSet " }
- func (astkind AstMetaKindGet) String() string { return "AstGet " }
- func (astkind AstMetaKindTarget) String() string { return "AstTarget " }
- func (astkind AstMetaKindCommand) String() string { return "AstCommand " }
- func (astkind AstMetaKindArguments) String() string { return "AstArguments " }
- func (astkind AstMetaKindArgument) String() string { return "AstArgument " }
- func (astkind AstMetaKindExpression) String() string { return "AstExpression " }
- func (astkind AstMetaKindBlock) String() string { return "AstBlock " }
- func (astkind AstMetaKindParenthesis) String() string { return "AstParenthesis" }
- func (astkind AstMetaKindList) String() string { return "AstList " }
- func (astkind AstMetaKindCapture) String() string { return "AstCapture " }
- func (astkind AstMetaKindWordValue) String() string { return "AstWordValue " }
- func (astkind AstMetaKindWord) String() string { return "AstWord " }
- func (astkind AstMetaKindType) String() string { return "AstType " }
- func (astkind AstMetaKindValue) String() string { return "AstValue " }
- func (astkind AstMetaKindEnd) String() string { return "AstEnd " }
- func (astkind AstMetaKindError) String() string { return "AstError " }
- func (astkind AstMetaKindFlatten) String() string { return "AstFlatten " }
- func (astkind AstMetaKindNone) Run(vm *VM, ast Ast, val ...Value) []Value { return ReturnEmpty() }
- func (astkind AstMetaKindProgram) Run(vm *VM, ast Ast, val ...Value) []Value {
- return []Value{vm.RunChildrenLastResult(ast, val...)}
- }
- func (astkind AstMetaKindStatements) Run(vm *VM, ast Ast, val ...Value) []Value {
- return []Value{vm.RunChildrenLastResult(ast, val...)}
- }
- func (astkind AstMetaKindStatement) Run(vm *VM, ast Ast, val ...Value) []Value {
- return vm.RunChildren(ast, val...)
- }
- func (astkind AstMetaKindClosed) Run(vm *VM, ast Ast, val ...Value) []Value {return ReturnEmpty() }
- func (astkind AstMetaKindSet) Run(vm *VM, ast Ast, val ...Value) []Value {
- values := vm.RunChildren(ast, val...)
- if len(values) < 2 {
- return Fail(fmt.Errorf("set needs at least 2 arguments: received %v", values))
- }
- target := values[0].String()
- value := values[1]
- if target == "(" || target == "$" {
- if len(values) < 3 {
- return Fail(fmt.Errorf("indirect get needs results: received %v", values))
- }
- target = values[1].String()
- value = values[2]
- }
- // log.Printf("(astkind AstMetaKindSet) Run: %v %v", target, value)
- vm.Register(target, value)
- return Ok(value)
- }
- func (astkind AstMetaKindGet) Run(vm *VM, ast Ast, val ...Value) []Value {
- targets := vm.RunChildren(ast, val...)
- target := targets[0].String()
- if target == "(" || target == "$" {
- if len(targets) < 2 {
- return Fail(fmt.Errorf("indirect get needs results: received %v", targets))
- }
- target = targets[1].String()
- }
- // log.Printf("(astkind AstMetaKindGet) Run: target %s", target)
- return Ok(vm.Lookup(target))
- }
- func (astkind AstMetaKindTarget) Run(vm *VM, ast Ast, val ...Value) []Value {
- values := vm.RunChildren(ast, val...)
- values = append([]Value{ast.Value()}, values...)
- return values
- }
- func (astkind AstMetaKindCommand) Run(vm *VM, ast Ast, val ...Value) []Value {
- commandName := ast.Value()
- arguments := vm.RunChildren(ast, val...)
- // log.Printf("Command execute: %s %v", commandName.String(), arguments)
- return vm.CallNamed(commandName.String(), arguments...)
- }
- func (astkind AstMetaKindArguments) Run(vm *VM, ast Ast, val ...Value) []Value {
- return vm.RunChildren(ast, val...)
- }
- func (astkind AstMetaKindArgument) Run(vm *VM, ast Ast, val ...Value) []Value {
- panic("AstMetaKindArgument")
- return []Value{vm.RunChildrenFirstResult(ast, val...)}
- }
- func (astkind AstMetaKindExpression) Run(vm *VM, ast Ast, val ...Value) []Value {
- panic("AstMetaKindExpression")
- return []Value{vm.RunChildrenLastResult(ast, val...)}
- }
- func (astkind AstMetaKindBlock) Run(vm *VM, ast Ast, val ...Value) []Value {
- // A block is not executed. It results in an anonymous runnable.
- ast.Display()
- return Ok(NewBlockValue(&ast))
- }
- func (astkind AstMetaKindParenthesis) Run(vm *VM, ast Ast, val ...Value) []Value {
- return []Value{vm.RunChildrenLastResult(ast, val...)}
- }
- func (astkind AstMetaKindList) Run(vm *VM, ast Ast, val ...Value) []Value {
- result := vm.RunChildren(ast, val...)
- list := &ListValue{List:result}
- return []Value{list}
- }
- func (astkind AstMetaKindCapture) Run(vm *VM, ast Ast, val ...Value) []Value {
- return vm.RunChildren(ast, val...)
- }
- func (astkind AstMetaKindWordValue) Run(vm *VM, ast Ast, val ...Value) []Value {
- return []Value{ast.Value()}
- }
- func (astkind AstMetaKindWord) Run(vm *VM, ast Ast, val ...Value) []Value {
- return []Value{ast.Value()}
- }
- func (astkind AstMetaKindType) Run(vm *VM, ast Ast, val ...Value) []Value {
- return []Value{ast.Value()}
- }
- func (astkind AstMetaKindValue) Run(vm *VM, ast Ast, val ...Value) []Value {
- return []Value{ast.Value()}
- }
- func (astkind AstMetaKindEnd) Run(vm *VM, ast Ast, val ...Value) []Value {
- return []Value{EmptyValue{}}
- }
- func (astkind AstMetaKindError) Run(vm *VM, ast Ast, val ...Value) []Value {
- return []Value{ast.Value()}
- }
- func (astkind AstMetaKindFlatten) Run(vm *VM, ast Ast, val ...Value) []Value {
- return ReturnEmpty()
- }
- type AstKind interface {
- String() string
- Run(vm *VM, ast Ast, val ...Value) []Value
- }
- /*
- func (Ast Ast) String() string {
- switch astkind {
- case AstMetaKindProgram:
- return "AstMetaKindProgram"
- case AstMetaKindStatements:
- return "AstMetaKindStatements"
- case AstMetaKindStatement:
- return "AstMetaKindStatement"
- case AstMetaKindSet:
- return "AstMetaKindSet"
- case AstMetaKindGet:
- return "AstMetaKindGet"
- case AstMetaKindTarget:
- return "AstMetaKindTarget"
- case AstMetaKindCommand:
- return "AstMetaKindCommand"
- case AstMetaKindArguments:
- return "AstMetaKindArguments"
- case AstMetaKindArgument:
- return "AstMetaKindArgument"
- case AstMetaKindExpression:
- return "AstMetaKindExpression"
- case AstMetaKindBlock:
- return "AstMetaKindBlock"
- case AstMetaKindParenthesis:
- return "AstMetaKindParenthesis"
- case AstMetaKindList:
- return "AstMetaKindList"
- case AstMetaKindCapture:
- return "AstMetaKindCapture"
- case AstMetaKindWordValue:
- return "AstMetaKindWordValue"
- case AstMetaKindWord:
- return "AstMetaKindWord"
- case AstMetaKindType:
- return "AstMetaKindType"
- case AstMetaKindValue:
- return "AstMetaKindValue"
- case AstMetaKindEnd:
- return "AstMetaKindEnd"
- case AstMetaKindError:
- return "AstMetaKindError"
- default:
- return "Unknown AstMetaKind"
- }
- }
- */
- /*
- func AstAppendChild(parent Ast, child Ast) Ast {
- basicParent := parent.(*Ast)
- return basicParent.AppendChild(child)
- }
- func AstNewChild(parent Ast, kind AstMetaKind, token Token) Ast {
- basicParent := parent.(*Ast)
- return basicParent.NewChild(kind, token)
- }
- */
- /* AST node kind */
- type Ast struct {
- AstKind
- parent *Ast
- children []*Ast
- token Token
- }
- func (ast Ast) Value() Value {
- return ast.token.Value
- }
- func NewAst(kind AstKind, parent *Ast, children []*Ast, token Token) *Ast {
- ast := &Ast{AstKind: kind, parent: parent, token: token}
- return ast.AppendChildren(children...)
- }
- func (ast *Ast) AppendChildren(children ...*Ast) *Ast {
- for _, child := range children {
- ast.AppendChild(child)
- }
- return ast
- }
- func (ast *Ast) AppendChild(child * Ast) *Ast {
- child.SetParent(ast)
- ast.children = append(ast.children, child)
- return child
- }
- func (ast *Ast) NewChild(kind AstKind, token Token) *Ast {
- child := NewAst(kind, ast, make([]*Ast, 0), token)
- ast.AppendChild(child)
- return child
- }
- func (ast Ast) IsKind(astkind AstKind) bool {
- return ast.AstKind == astkind
- }
- func (ast Ast) IsError() bool {
- return ast.AstKind == AstKindError
- }
- func (ast Ast) IsNone() bool {
- return ast.AstKind == AstKindNone
- }
- func (ast Ast) IsFlatten() bool {
- return ast.AstKind == AstKindFlatten
- }
- func (ast Ast) Token() Token {
- return ast.token
- }
- func (ast Ast) Parent() *Ast {
- return ast.parent
- }
- func (ast Ast) Children() []*Ast {
- return ast.children
- }
- func (ast Ast) Kind() AstKind {
- return ast.AstKind
- }
- func (ast *Ast) SetParent(parent *Ast) {
- ast.parent = parent
- }
- func (ast Ast) Child(index int) *Ast {
- count := ast.CountChildren()
- if index < 0 || index > count {
- return nil
- }
- return ast.children[index]
- }
- func (ast Ast) Run(vm *VM, val ...Value) []Value {
- res := ast.AstKind.Run(vm, ast, val...)
- if vm != nil && vm.Tracer != nil {
- vm.Trace(*vm, ast, res...)
- }
- return res
- }
- func (ast *Ast) Walk(walker func(node *Ast) *Ast) *Ast {
- if found := walker(ast); found != nil {
- return found
- }
- for _, child := range ast.children {
- if found := child.Walk(walker); found != nil {
- return found
- }
- }
- return nil
- }
- func (ast Ast) String() string {
- return fmt.Sprintf("Ast %s: %s", ast.AstKind.String(), ast.token.String())
- }
- func (ast Ast) Display() {
- ast.Walk(func(node *Ast) *Ast {
- depth := node.Depth()
- fmt.Printf("%s", strings.Repeat("--", depth))
- if node != nil {
- fmt.Printf("Ast: %s\n", node.String())
- } else {
- fmt.Printf("Ast: nil node\n")
- }
- return nil
- })
- }
- func (ast Ast) Dump() string {
- result := ""
- ast.Walk(func(node *Ast) *Ast {
- depth := node.Depth()
- result += fmt.Sprintf("%s", strings.Repeat("--", depth))
- if node != nil {
- result += fmt.Sprintf("Ast: %s\n", node.String())
- } else {
- result += fmt.Sprintf("Ast: nil node\n")
- }
- return nil
- })
- return result
- }
- func (ast Ast) Depth() int {
- var depth int = 0
- parent := ast.Parent()
- for parent != nil {
- depth++
- parent = parent.Parent()
- }
- return depth
- }
- func (ast Ast) CountChildren() int {
- return len(ast.children)
- }
- func AstIsError(ast * Ast) bool {
- return ast.IsError()
- }
- func (ast Ast) 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)
- }
- func NewEmptyAst(astkind AstKind) *Ast {
- return NewAst(astkind, nil, EmptyAstArray(), NoToken())
- }
- func NewAstNone() *Ast {
- return NewEmptyAst(AstKindNone)
- }
- func NewAstWithToken(astkind AstKind, token Token) *Ast {
- return NewAst(astkind, nil, EmptyAstArray(), token)
- }
- // If AST has errors, return it as a merged error, otherwise returns nil
- func (ast *Ast) ToError() error {
- errlist := ast.Errors()
- if len(errlist) < 1 {
- return nil
- }
- sep := ""
- res := ""
- for _, err := range errlist {
- res = fmt.Sprintf("%s%s%s", res, sep, err)
- sep = "\n"
- }
- return fmt.Errorf("%s", res)
- }
- func (from Ast) Convert(to interface{}) error {
- switch toPtr := to.(type) {
- case *Ast:
- (*toPtr) = from
- default:
- return NewErrorValuef("Cannot convert Ast value %v to %v", from, to)
- }
- return nil
- }
- const TypeValueAst = TypeValue("Ast")
- func (ast Ast) Type() TypeValue {
- return TypeValueAst
- }
- /*
- type AstProgram struct{ Ast }
- type AstStatements struct{ Ast }
- type AstStatement struct{ Ast }
- type AstSet struct{ Ast }
- type AstGet struct{ Ast }
- type AstTarget struct{ Ast }
- type AstCommand struct{ Ast }
- type AstArguments struct{ Ast }
- type AstArgument struct{ Ast }
- type AstExpression struct{ Ast }
- type AstBlock struct{ Ast }
- type AstParenthesis struct{ Ast }
- type AstList struct{ Ast }
- type AstCapture struct{ Ast }
- type AstWordValue struct{ Ast }
- type AstWord struct{ Ast }
- type AstType struct{ Ast }
- type AstValue struct{ Ast }
- type AstEnd struct{ Ast }
- type AstError struct{ Ast }
- */
- var _ Ast = Ast{}
- /* The kind of an AST is also it's constructor function. This is so deep I'm almost
- getting scared. :) */
- // The type is defined as a constructor
- /*
- type AstMetaKind func(parent Ast, children []Ast, token Token) Ast
- type AstMetaKind2 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 AstMetaKindBasic = AstMetaKind(func(parent Ast, children []Ast, token Token) Ast { return NewBasicAst(parent, children, token) })
- var AstMetaKindProgram = AstMetaKind(NewAstProgram)
- var AstMetaKindProgram2 = AstMetaKind2(AstTypeProgramImp{})
- var AstMetaKindStatements = AstMetaKind(func(parent Ast, children []Ast, token Token) Ast {
- return &AstStatements{NewBasicAst(parent, children, token)}
- })
- var AstMetaKindStatement = AstMetaKind(func(parent Ast, children []Ast, token Token) Ast {
- return &AstStatement{NewBasicAst(parent, children, token)}
- })
- var AstMetaKindSet = AstMetaKind(func(parent Ast, children []Ast, token Token) Ast {
- return &AstSet{NewBasicAst(parent, children, token)}
- })
- var AstMetaKindGet = AstMetaKind(func(parent Ast, children []Ast, token Token) Ast {
- return &AstGet{NewBasicAst(parent, children, token)}
- })
- var AstMetaKindTarget = AstMetaKind(func(parent Ast, children []Ast, token Token) Ast {
- return &AstTarget{NewBasicAst(parent, children, token)}
- })
- var AstMetaKindCommand = AstMetaKind(func(parent Ast, children []Ast, token Token) Ast {
- return &AstCommand{NewBasicAst(parent, children, token)}
- })
- var AstMetaKindArguments = AstMetaKind(func(parent Ast, children []Ast, token Token) Ast {
- return &AstArguments{NewBasicAst(parent, children, token)}
- })
- var AstMetaKindArgument = AstMetaKind(func(parent Ast, children []Ast, token Token) Ast {
- return &AstArgument{NewBasicAst(parent, children, token)}
- })
- var AstMetaKindExpression = AstMetaKind(func(parent Ast, children []Ast, token Token) Ast {
- return &AstExpression{NewBasicAst(parent, children, token)}
- })
- var AstMetaKindBlock = AstMetaKind(func(parent Ast, children []Ast, token Token) Ast {
- return &AstBlock{NewBasicAst(parent, children, token)}
- })
- var AstMetaKindParenthesis = AstMetaKind(func(parent Ast, children []Ast, token Token) Ast {
- return &AstParenthesis{NewBasicAst(parent, children, token)}
- })
- var AstMetaKindList = AstMetaKind(func(parent Ast, children []Ast, token Token) Ast {
- return &AstList{NewBasicAst(parent, children, token)}
- })
- var AstMetaKindCapture = AstMetaKind(func(parent Ast, children []Ast, token Token) Ast {
- return &AstCapture{NewBasicAst(parent, children, token)}
- })
- var AstMetaKindWordValue = AstMetaKind(func(parent Ast, children []Ast, token Token) Ast {
- return &AstWordValue{NewBasicAst(parent, children, token)}
- })
- var AstMetaKindWord = AstMetaKind(func(parent Ast, children []Ast, token Token) Ast {
- return &AstWord{NewBasicAst(parent, children, token)}
- })
- var AstMetaKindType = AstMetaKind(func(parent Ast, children []Ast, token Token) Ast {
- return &AstType{NewBasicAst(parent, children, token)}
- })
- var AstMetaKindValue = AstMetaKind(func(parent Ast, children []Ast, token Token) Ast {
- return &AstValue{NewBasicAst(parent, children, token)}
- })
- var AstMetaKindEnd = AstMetaKind(func(parent Ast, children []Ast, token Token) Ast {
- return &AstEnd{NewBasicAst(parent, children, token)}
- })
- var AstMetaKindError = AstMetaKind(func(parent Ast, children []Ast, token Token) Ast {
- return &AstError{NewBasicAst(parent, children, token)}
- })
- */
|