Browse Source

Working on AST and execution.

Beoran 5 years ago
parent
commit
425bb06389
8 changed files with 703 additions and 216 deletions
  1. 232 95
      ast.go
  2. 45 34
      lexer.go
  3. 5 5
      lexer_test.go
  4. 57 58
      parser.go
  5. 4 7
      parser_test.go
  6. 12 3
      token.go
  7. 41 14
      value.go
  8. 307 0
      vm.go

+ 232 - 95
ast.go

@@ -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
+	/* AppendChild(child Ast) Ast
+	NewChild(kind AstKind, token Token) Ast
+	*/
+
+	/* Make(parent Ast, 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)
+}
+*/
 
 /* AST node kind */
-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
 }
 
-/* Detaches, I.E removes this node and all it's children from the parent tree. */
-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 {
-		/* Special case if ast is the first child of it's parent. */
-		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}
+}
+
+/* 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 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)}
+})

+ 45 - 34
lexer.go

@@ -178,13 +178,14 @@ func (lexer *Lexer) Next() (rune, error) {
 	return r, nil
 }
 
-func (lexer *Lexer) NextIf(predicate func(rune) bool) (bool, error) {
+func (lexer *Lexer) DoIf(predicate func(rune) bool,
+	todo func(*Lexer) (rune, error)) (bool, error) {
 	r, err := lexer.Peek()
 	if err != nil {
 		return false, err
 	}
 	if predicate(r) {
-		r, err = lexer.Next()
+		r, err = todo(lexer)
 		if err != nil {
 			return true, err
 		}
@@ -193,19 +194,12 @@ func (lexer *Lexer) NextIf(predicate func(rune) bool) (bool, error) {
 	return false, nil
 }
 
+func (lexer *Lexer) NextIf(predicate func(rune) bool) (bool, error) {
+	return lexer.DoIf(predicate, (*Lexer).Next)
+}
+
 func (lexer *Lexer) SkipIf(predicate func(rune) bool) (bool, error) {
-	r, err := lexer.Peek()
-	if err != nil {
-		return false, err
-	}
-	if predicate(r) {
-		r, err = lexer.Skip()
-		if err != nil {
-			return true, err
-		}
-		return true, nil
-	}
-	return false, nil
+	return lexer.DoIf(predicate, (*Lexer).Skip)
 }
 
 func (lexer *Lexer) NextWhile(predicate func(rune) bool) (bool, error) {
@@ -237,13 +231,7 @@ func isComment(r rune) bool {
 }
 
 func (lexer *Lexer) SkipSpace() error {
-	r, err := lexer.Skip()
-	lexer.LogDebug("Skipping %c.", r)
-	if err != nil {
-		return err
-	}
-	for ; isSpace(r) && err == nil; r, err = lexer.Skip() {
-	}
+	_, err := lexer.SkipWhile(isSpace)
 	return err
 }
 
@@ -251,11 +239,12 @@ func (lexer *Lexer) SkipBlockComment() error {
 	var err error
 	var r rune
 	lexer.LogDebug("Skipping block comment.")
-	for block := 1; block > 0; {
-		r, err = lexer.Skip()
+	for block := 1; block > 0 && err == nil; {
+		_, err = lexer.Skip()
 		if err != nil {
 			return err
 		}
+		r, err = lexer.Peek()
 		if r == '{' {
 			block++
 		} else if r == '}' {
@@ -263,6 +252,7 @@ func (lexer *Lexer) SkipBlockComment() error {
 		}
 		lexer.LogDebug("Skipping block comment: %d", block)
 	}
+	_, err = lexer.Skip()
 	return err
 }
 
@@ -272,17 +262,23 @@ func (lexer *Lexer) SkipComment() error {
 	if err != nil {
 		return err
 	}
-	first := true
-	for r, err = lexer.Skip(); r != '\n' && err == nil; r, err = lexer.Skip() {
-		lexer.LogDebug("Skipping loop %c.", r)
-		if first && r == '{' {
-			first = false
-			return lexer.SkipBlockComment()
+	r, err = lexer.Peek()
+	if r == '{' {
+		return lexer.SkipBlockComment()
+	}
+
+	for r != '\n' && err == nil {
+		lexer.LogDebug("Skipping comment %c.", r)
+		_, err = lexer.Skip()
+		if err != nil {
+			return err
 		}
+		r, err = lexer.Peek()
 	}
 	if err != nil {
 		return err
 	}
+	_, err = lexer.Skip()
 	return err
 }
 
@@ -456,7 +452,7 @@ func (lexer *Lexer) LexLongString() Token {
 	return lexer.MakeToken(TokenKindString)
 }
 
-func (lexer *Lexer) LexWord() Token {
+func (lexer *Lexer) LexWordOrType(kind TokenKind) Token {
 	var err error
 	first := true
 
@@ -487,8 +483,17 @@ func (lexer *Lexer) LexWord() Token {
 	case "false":
 		return lexer.MakeBooleanToken(false)
 	default:
-		return lexer.MakeToken(TokenKindWord)
 	}
+
+	return lexer.MakeToken(kind)
+}
+
+func (lexer *Lexer) LexWord() Token {
+	return lexer.LexWordOrType(TokenKindWord)
+}
+
+func (lexer *Lexer) LexType() Token {
+	return lexer.LexWordOrType(TokenKindType)
 }
 
 func (lexer *Lexer) LexSymbol() Token {
@@ -515,6 +520,7 @@ func (lexer *Lexer) skipSpaceAndCommentAndPeek() (rune, error) {
 	if err != nil {
 		return r, err
 	}
+	i := 0
 	for isSpace(r) || isComment(r) {
 		if isSpace(r) {
 			err = lexer.SkipSpace()
@@ -524,8 +530,9 @@ func (lexer *Lexer) skipSpaceAndCommentAndPeek() (rune, error) {
 		if err != nil {
 			return r, err
 		}
-		lexer.LogDebug("Peeked again: >%c<", r)
-		r, err := lexer.Peek()
+		i++
+		r, err = lexer.Peek()
+		lexer.LogDebug("Peeked again: >%c< %v %v %d", r, isSpace(r), isComment(r), i)
 		if err != nil {
 			return r, err
 		}
@@ -584,7 +591,11 @@ func (lexer *Lexer) lex() Token {
 	}
 
 	if unicode.IsLetter(r) {
-		return lexer.LexWord()
+		if unicode.IsUpper(r) {
+			return lexer.LexType()
+		} else {
+			return lexer.LexWord()
+		}
 	}
 
 	return lexer.MakeErrorfToken("Unknown character: %c", r)

+ 5 - 5
lexer_test.go

@@ -67,12 +67,12 @@ func HelperLexTestSkip(input string, want rune, call func(*Lexer) error, test *t
 }
 
 func TestLexParts(test *testing.T) {
-	HelperLexTestSkip(" xyz", 'x', (*Lexer).SkipSpace, test)
+	HelperLexTestSkip(" abc", 'a', (*Lexer).SkipSpace, test)
 	HelperLexTestSkip("     xyz", 'x', (*Lexer).SkipSpace, test)
-	HelperLexTestSkip(" #  \nx", 'x', (*Lexer).SkipComment, test)
-	HelperLexTestSkip("#{}x", 'x', (*Lexer).SkipComment, test)
-	HelperLexTestSkip("#{{}{{}}}x", 'x', (*Lexer).SkipComment, test)
-	HelperLexTestSkip("    \tword\n", 'w', (*Lexer).SkipComment, test)
+	HelperLexTestSkip(" #  \nd", 'd', (*Lexer).SkipComment, test)
+	HelperLexTestSkip("#{}e", 'e', (*Lexer).SkipComment, test)
+	HelperLexTestSkip("#{{}{{}}}f", 'f', (*Lexer).SkipComment, test)
+	HelperLexTestSkip("    \tword\n", 'w', (*Lexer).SkipSpace, test)
 }
 
 func TestLex(test *testing.T) {

+ 57 - 58
parser.go

@@ -43,7 +43,7 @@ GETTER -> get word .
 
 type Parser struct {
 	Lexer   *Lexer
-	current *Token
+	current Token
 	LoggerWrapper
 }
 
@@ -53,7 +53,7 @@ func (parser *Parser) SetLogger(logger Logger) {
 
 func (parser *Parser) Advance() {
 	token := parser.Lexer.Lex()
-	parser.current = &token
+	parser.current = token
 	parser.LogDebug("Next token: %s\n", token.String())
 }
 
@@ -61,8 +61,8 @@ func (parser *Parser) Advance() {
 the token kinds given in kinds. In this case it will return the accepted
 token and advance the parser. Otherwise, if no token kind matches, the lexer
 does not advance and the current token remains the same, except if that was nil.*/
-func (parser *Parser) Accept(kinds ...TokenKind) *Token {
-	if parser.current == nil {
+func (parser *Parser) Accept(kinds ...TokenKind) Token {
+	if parser.current.IsNone() {
 		parser.Advance()
 	}
 
@@ -73,26 +73,27 @@ func (parser *Parser) Accept(kinds ...TokenKind) *Token {
 			return accepted
 		}
 	}
-	return nil
+	return NoToken()
 }
 
-func (parser *Parser) ParseMany(astkind AstKind, parsefunc func(*Parser) *Ast) *Ast {
-	ast := NewAst(astkind, nil, nil)
-	for sub := parsefunc(parser); sub != nil && sub.AstKind != AstKindError; sub = parsefunc(parser) {
-		ast.AppendChild(sub)
+func (parser *Parser) ParseMany(kind AstKind, parent Ast, parsefunc func(*Parser) Ast) Ast {
+	children := make([]Ast, 0)
+	for sub := parsefunc(parser); sub != nil && !AstIsError(sub); sub = parsefunc(parser) {
+		children = append(children, sub)
 	}
+	return NewAst(kind, parent, children, NoToken())
 	return ast
 }
 
-func (parser *Parser) NewAstError(message string) *Ast {
+func (parser *Parser) NewAstError(message string) Ast {
 	sv := StringValue(message + " at token " + parser.current.String())
 	pos := parser.current.Position
 	tok := NewToken(TokenKindError, sv, pos)
-	return NewAst(AstKindError, nil, &tok)
+	return NewAst(AstKindError, nil, EmptyAstArray(), tok)
 }
 
-func (parser *Parser) ParseAny(astkind AstKind, parsefuncs ...(func(*Parser) *Ast)) *Ast {
-	ast := NewAst(astkind, nil, nil)
+func (parser *Parser) ParseAny(astkind AstKind, parsefuncs ...(func(*Parser) Ast)) Ast {
+	ast := NewAst(astkind, nil, NoToken())
 	for _, parsefunc := range parsefuncs {
 		sub := parsefunc(parser)
 		if sub != nil {
@@ -103,7 +104,7 @@ func (parser *Parser) ParseAny(astkind AstKind, parsefuncs ...(func(*Parser) *As
 	return nil
 }
 
-func (parser *Parser) ParseRequireAny(astkind AstKind, parsefuncs ...(func(*Parser) *Ast)) *Ast {
+func (parser *Parser) ParseRequireAny(astkind AstKind, parsefuncs ...(func(*Parser) Ast)) Ast {
 	ast := parser.ParseAny(astkind, parsefuncs...)
 	if ast == nil {
 		err := parser.NewAstError("Unexpected token")
@@ -112,25 +113,26 @@ func (parser *Parser) ParseRequireAny(astkind AstKind, parsefuncs ...(func(*Pars
 	return ast
 }
 
-func (parser *Parser) ParseValue() *Ast {
+func (parser *Parser) ParseValue() Ast {
 	value := parser.Accept(TokenKindInteger, TokenKindString,
 		TokenKindBoolean, TokenKindFloat, TokenKindSymbol)
-	if value == nil {
+	if value.IsNone() {
 		return nil
 	}
 	return NewAst(AstKindValue, nil, value)
 }
 
-func (parser *Parser) ParseWordValue() *Ast {
+func (parser *Parser) ParseWordValue() Ast {
 	value := parser.Accept(TokenKindInteger, TokenKindString,
-		TokenKindBoolean, TokenKindFloat, TokenKindSymbol, TokenKindWord)
-	if value == nil {
+		TokenKindBoolean, TokenKindFloat, TokenKindSymbol,
+		TokenKindType, TokenKindWord)
+	if value.IsNone() {
 		return nil
 	}
 	return NewAst(AstKindWordValue, nil, value)
 }
 
-func (parser *Parser) ParseArgument() *Ast {
+func (parser *Parser) ParseArgument() Ast {
 	return parser.ParseAny(AstKindArgument,
 		(*Parser).ParseWordValue,
 		(*Parser).ParseGet,
@@ -140,22 +142,22 @@ func (parser *Parser) ParseArgument() *Ast {
 		(*Parser).ParseBlock)
 }
 
-func (parser *Parser) ParseArguments() *Ast {
+func (parser *Parser) ParseArguments() Ast {
 	return parser.ParseMany(AstKindArguments, (*Parser).ParseArgument)
 }
 
-func (parser *Parser) ParseList() *Ast {
+func (parser *Parser) ParseList() Ast {
 	op := parser.Accept(TokenKindOpenList)
-	if op == nil {
+	if op.IsNone() {
 		return nil
 	}
 
 	ast := NewAst(AstKindList, nil, op)
 	args := parser.ParseArguments()
-	if args.AstKind == AstKindError {
+	if AstIsError(args) {
 		return args
 	}
-	if cp := parser.Accept(TokenKindCloseList); cp == nil {
+	if cp := parser.Accept(TokenKindCloseList); cp.IsNone() {
 		return parser.NewAstError("expected closing brackets")
 	}
 
@@ -163,10 +165,10 @@ func (parser *Parser) ParseList() *Ast {
 	return ast
 }
 
-func (parser *Parser) ParseParenthesis() *Ast {
+func (parser *Parser) ParseParenthesis() Ast {
 	op := parser.Accept(TokenKindOpenParen)
 
-	if op == nil {
+	if op.IsNone() {
 		return nil
 	}
 
@@ -175,10 +177,10 @@ func (parser *Parser) ParseParenthesis() *Ast {
 	if expr == nil {
 		return parser.NewAstError("expected expression")
 	}
-	if expr.AstKind == AstKindError {
+	if AstIsError(expr) {
 		return expr
 	}
-	if cp := parser.Accept(TokenKindCloseParen); cp == nil {
+	if cp := parser.Accept(TokenKindCloseParen); cp.IsNone() {
 		return parser.NewAstError("expected closing parenthesis")
 	}
 
@@ -186,9 +188,9 @@ func (parser *Parser) ParseParenthesis() *Ast {
 	return ast
 }
 
-func (parser *Parser) ParseBlock() *Ast {
+func (parser *Parser) ParseBlock() Ast {
 	op := parser.Accept(TokenKindOpenBlock)
-	if op == nil {
+	if op.IsNone() {
 		return nil
 	}
 
@@ -197,10 +199,10 @@ func (parser *Parser) ParseBlock() *Ast {
 	if stats == nil {
 		return parser.NewAstError("expected expression")
 	}
-	if stats.AstKind == AstKindError {
+	if AstIsError(stats) {
 		return stats
 	}
-	if cp := parser.Accept(TokenKindCloseBlock); cp == nil {
+	if cp := parser.Accept(TokenKindCloseBlock); cp.IsNone() {
 		return parser.NewAstError("expected closing block")
 	}
 
@@ -209,11 +211,11 @@ func (parser *Parser) ParseBlock() *Ast {
 }
 
 /* Parses the target of a set or get expression */
-func (parser *Parser) ParseTarget() *Ast {
-	target := parser.Accept(TokenKindWord, TokenKindSymbol)
+func (parser *Parser) ParseTarget() Ast {
+	target := parser.Accept(TokenKindWord, TokenKindType, TokenKindSymbol)
 	ast := NewAst(AstKindTarget, nil, target)
 
-	if target == nil {
+	if target.IsNone() {
 		paren := parser.ParseParenthesis()
 		if paren == nil {
 			return parser.NewAstError("expected word, symbol or parenthesis")
@@ -224,13 +226,13 @@ func (parser *Parser) ParseTarget() *Ast {
 	return ast
 }
 
-func (parser *Parser) ParseSet() *Ast {
+func (parser *Parser) ParseSet() Ast {
 	set := parser.Accept(TokenKindSet)
-	if set == nil {
+	if set.IsNone() {
 		return nil
 	}
 
-	ast := NewAst(AstKindGet, nil, set)
+	ast := NewAst(AstKindSet, nil, set)
 	target := parser.ParseTarget()
 	ast.AppendChild(target)
 
@@ -242,9 +244,9 @@ func (parser *Parser) ParseSet() *Ast {
 	return ast
 }
 
-func (parser *Parser) ParseGet() *Ast {
+func (parser *Parser) ParseGet() Ast {
 	get := parser.Accept(TokenKindGet)
-	if get == nil {
+	if get.IsNone() {
 		return nil
 	}
 	ast := NewAst(AstKindGet, nil, get)
@@ -253,9 +255,9 @@ func (parser *Parser) ParseGet() *Ast {
 	return ast
 }
 
-func (parser *Parser) ParseCommand() *Ast {
-	word := parser.Accept(TokenKindWord)
-	if word == nil {
+func (parser *Parser) ParseCommand() Ast {
+	word := parser.Accept(TokenKindWord, TokenKindType)
+	if word.IsNone() {
 		return nil
 	}
 	arguments := parser.ParseArguments()
@@ -264,56 +266,53 @@ func (parser *Parser) ParseCommand() *Ast {
 	return command
 }
 
-func (parser *Parser) ParseExpression() *Ast {
+func (parser *Parser) ParseExpression() Ast {
 	exp := parser.ParseRequireAny(AstKindExpression, (*Parser).ParseSet,
 		(*Parser).ParseGet, (*Parser).ParseCommand)
 	return exp
 }
 
-func (parser *Parser) ParseEmptyStatement() *Ast {
+func (parser *Parser) ParseEmptyStatement() Ast {
 	eox := parser.Accept(TokenKindEOX)
-	if eox == nil {
+	if eox.IsNone() {
 		return nil
 	}
 	ast := NewAst(AstKindEnd, nil, eox)
 	return ast
 }
 
-func (parser *Parser) ParseStatement() *Ast {
+func (parser *Parser) ParseStatement() Ast {
 	ast := parser.ParseAny(AstKindStatement,
 		(*Parser).ParseBlock,
 		(*Parser).ParseSet,
 		(*Parser).ParseGet,
 		(*Parser).ParseCommand,
 		(*Parser).ParseParenthesis)
-	if eox := parser.Accept(TokenKindEOX); eox == nil {
+	if eox := parser.Accept(TokenKindEOX); eox.IsNone() {
 		return parser.NewAstError("expected end of statement")
 	}
 	return ast
 }
 
-func (parser *Parser) ParseStatements() *Ast {
+func (parser *Parser) ParseStatements() Ast {
 	return parser.ParseMany(AstKindStatements, (*Parser).ParseStatement)
 }
 
-func (parser *Parser) ParseProgram() *Ast {
-	ast := NewAst(AstKindProgram, nil, nil)
-	stats := parser.ParseStatements()
+func (parser *Parser) ParseProgram() Ast {
 	eof := parser.Accept(TokenKindEOF)
 	aeof := NewAst(AstKindEnd, nil, eof)
 	// be lenient with missing EOF for now...
-	ast.AppendChild(stats)
-	ast.AppendChild(aeof)
-	return ast
+	children := append(stats, aeof)
+	return NewAst(AstKindProgram, nil, children, NoToken())
 }
 
-func (parser *Parser) Parse() *Ast {
+func (parser *Parser) Parse() Ast {
 	ast := parser.ParseProgram()
 	return ast
 }
 
 func NewParser(lexer *Lexer) *Parser {
-	parser := &Parser{lexer, nil, LoggerWrapper{nil}}
+	parser := &Parser{lexer, NoToken(), LoggerWrapper{nil}}
 	return parser
 }
 

+ 4 - 7
parser_test.go

@@ -5,7 +5,7 @@ import (
 	"testing"
 )
 
-func HelperFailOnErrors(ast *Ast, expected int, test *testing.T) {
+func HelperFailOnErrors(ast *BasicAst, expected int, test *testing.T) {
 	if ast == nil {
 		test.Errorf("Parse failed, %d parse errors expected", expected)
 	}
@@ -20,18 +20,16 @@ func HelperFailOnErrors(ast *Ast, expected int, test *testing.T) {
 }
 
 func HelperParseAndFailOnErrors(prog string, expected int,
-	parsefunc func(*Parser) *Ast, test *testing.T) {
+	parsefunc func(*Parser) *BasicAst, test *testing.T) {
 	parser := NewParserFromString(prog)
 	/* parser.SetLogger(testLogger{}) */
 	ast := parsefunc(parser)
 	HelperFailOnErrors(ast, expected, test)
 }
 
-/*
 func TestParser(test *testing.T) {
-	com := `puts "hello"
-`
-	// say ( add 5 10 ) .`
+	com := `puts "hello" 
+	say ( add 5 10 ) .`
 	parser := NewParserFromString(com)
 	ast := parser.Parse()
 	ast.Display()
@@ -46,4 +44,3 @@ func TestParser2(test *testing.T) {
 func TestParenthesis(test *testing.T) {
 	HelperParseAndFailOnErrors(`( add 5 10 )`, 0, (*Parser).ParseParenthesis, test)
 }
-*/

+ 12 - 3
token.go

@@ -15,6 +15,7 @@ type Position struct {
 type TokenKind rune
 
 const (
+	TokenKindNone       = TokenKind(0)
 	TokenKindInteger    = TokenKind('i')
 	TokenKindFloat      = TokenKind('f')
 	TokenKindString     = TokenKind('s')
@@ -37,6 +38,7 @@ const (
 
 /* Names of the different token types. */
 var TokenKindNames map[TokenKind]string = map[TokenKind]string{
+	TokenKindNone:       "None",
 	TokenKindInteger:    "Integer",
 	TokenKindFloat:      "Float",
 	TokenKindSymbol:     "Symbol",
@@ -92,9 +94,7 @@ func (token Token) Error() string {
  * that is either an error or EOF. */
 func (token Token) IsLast() bool {
 	switch token.TokenKind {
-	case TokenKindError:
-		return true
-	case TokenKindEOF:
+	case TokenKindError, TokenKindEOF, TokenKindNone:
 		return true
 	default:
 		return false
@@ -105,3 +105,12 @@ func (token Token) IsLast() bool {
 func NewToken(kind TokenKind, val Value, pos Position) Token {
 	return Token{kind, val, pos}
 }
+
+/* Creates a token with type TokenTypeNone */
+func NoToken() Token {
+	return NewToken(TokenKindNone, NilValue, Position{})
+}
+
+func (token Token) IsNone() bool {
+	return token.TokenKind == TokenKindNone
+}

+ 41 - 14
value.go

@@ -5,37 +5,41 @@ import "fmt"
 /* Run time values */
 type Value interface {
 	String() string
+	Type() TypeValue
 }
 
 type IntValue int64
 type FloatValue float64
-
 type StringValue string
-
 type BoolValue bool
-
-const (
-	TrueValue  = BoolValue(true)
-	FalseValue = BoolValue(false)
-)
-
-var NilValue = Value(nil)
-
 type WordValue string
-
 type TypeValue string
-
 type ErrorValue struct {
 	error
 }
-
 type EmptyValue struct {
 }
-
 type ListValue struct {
 	List []Value
 }
 
+const (
+	TrueValue       = BoolValue(true)
+	FalseValue      = BoolValue(false)
+	IntTypeValue    = TypeValue("Int")
+	FloatTypeValue  = TypeValue("Float")
+	StringTypeValue = TypeValue("String")
+	BoolTypeValue   = TypeValue("Bool")
+	WordTypeValue   = TypeValue("Word")
+	ErrorTypeValue  = TypeValue("Error")
+	TypeTypeValue   = TypeValue("Type")
+	EmptyTypeValue  = TypeValue("Empty")
+	ListTypeValue   = TypeValue("List")
+	AnyTypeValue    = TypeValue("Any")
+)
+
+var NilValue = Value(nil)
+
 func (val IntValue) String() string {
 	return fmt.Sprintf("%d", int64(val))
 }
@@ -82,3 +86,26 @@ func (val ListValue) String() string {
 	res += "]"
 	return res
 }
+
+func (v IntValue) Type() TypeValue    { return IntTypeValue }
+func (v FloatValue) Type() TypeValue  { return FloatTypeValue }
+func (v StringValue) Type() TypeValue { return StringTypeValue }
+func (v BoolValue) Type() TypeValue   { return BoolTypeValue }
+func (v WordValue) Type() TypeValue   { return WordTypeValue }
+func (v TypeValue) Type() TypeValue   { return TypeTypeValue }
+func (v ErrorValue) Type() TypeValue  { return ErrorTypeValue }
+func (v EmptyValue) Type() TypeValue  { return EmptyTypeValue }
+func (v ListValue) Type() TypeValue   { return ListTypeValue }
+
+func NewErrorValuef(format string, args ...interface{}) ErrorValue {
+	err := fmt.Errorf(format, args...)
+	return ErrorValue{err}
+}
+
+func NewListValue(elements ...Value) ListValue {
+	return ListValue{elements}
+}
+
+func (list *ListValue) Append(elements ...Value) {
+	list.List = append(list.List, elements...)
+}

+ 307 - 0
vm.go

@@ -0,0 +1,307 @@
+// vm, the virtual low level machine that runs MUESLI.
+package muesli
+
+// import "fmt"
+
+// Handler function
+type Handler func(vm *VM, arguments ...Value) ListValue
+
+func (handler *Handler) Call(vm *VM, arguments ...Value) ListValue {
+	return (*handler)(vm, arguments...)
+}
+
+// A callable Value must implement the Caller interface
+type Caller interface {
+	Call(vm *VM, arguments ...Value) ListValue
+}
+
+// Callable value types
+type CallableValue struct {
+	Name string
+}
+
+func (val CallableValue) String() string {
+	return val.Name
+}
+
+func (val *CallableValue) Call(vm *VM, arguments ...Value) ListValue {
+	panic("Not implemented")
+}
+
+// A struct to store a built in function
+type BuiltinValue struct {
+	CallableValue
+	Handler
+}
+
+func NewCallableValue(name string) CallableValue {
+	return CallableValue{name}
+}
+
+func NewBuiltinValue(name string, handler Handler) BuiltinValue {
+	result := BuiltinValue{}
+	result.Name = name
+	result.Handler = handler
+	return result
+}
+
+func (builtin *BuiltinValue) Call(vm *VM, arguments ...Value) ListValue {
+	return vm.CallBuiltin(builtin.Handler, arguments...)
+}
+
+// A script defined function
+type DefinedValue struct {
+	CallableValue
+	Definition *BasicAst
+}
+
+func NewDefinedValue(name string, definition *BasicAst) DefinedValue {
+	result := DefinedValue{}
+	result.Name = name
+	result.Definition = definition
+	return result
+}
+
+func (defined *DefinedValue) Call(vm *VM, arguments ...Value) ListValue {
+	return vm.CallDefined(defined.Definition, arguments...)
+}
+
+/*
+	Amount of types that will be considered inside a signature.
+	Limited mosty to allow hashability.
+*/
+const TypesInSignature = 8
+
+/* A signature describes the desired types of an overloaded function call. */
+type Signature struct {
+	Types [TypesInSignature]TypeValue
+}
+
+func CalculateSignature(arguments ...Value) Signature {
+	signature := Signature{}
+	for i := 0; i < cap(signature.Types); i++ {
+		if i > len(arguments) {
+			signature.Types[i] = AnyTypeValue
+		} else {
+			signature.Types[i] = arguments[i].Type()
+		}
+	}
+	return signature
+}
+
+func (signature *Signature) IsMatch(arguments ...Value) bool {
+	for i, kind := range signature.Types {
+		if i > len(arguments) || arguments[i] == nil {
+			return false
+		}
+		if kind != arguments[i].Type() && kind != AnyTypeValue {
+			return false
+		}
+	}
+	return true
+}
+
+/* An overload is an overloaded callable value that can be called. */
+type Overload struct {
+	CallableValue
+}
+
+/* A cover is a callable that dispatches to other callables depending on
+the types of the arguments, in particular the first one. The individual
+callable functions are the overloads
+*/
+type CoverValue struct {
+	CallableValue
+	Overloads map[Signature]Overload
+}
+
+func (cover *CoverValue) Call(vm *VM, arguments ...Value) ListValue {
+	signature := CalculateSignature(arguments...)
+	if overload, ok := cover.Overloads[signature]; ok {
+		return overload.Call(vm, arguments...)
+	} else {
+		for signature, overload := range cover.Overloads {
+			if signature.IsMatch(arguments...) {
+				return overload.Call(vm, arguments...)
+			}
+		}
+	}
+	vm.Fail()
+	return NewListValue(NewErrorValuef("Could not match cover %s with arguments.", cover.Name))
+}
+
+const (
+	CoverTypeValue   = TypeValue("Cover")
+	BuiltinTypeValue = TypeValue("Builtin")
+	DefinedTypeValue = TypeValue("Defined")
+)
+
+func (v CoverValue) Type() TypeValue   { return CoverTypeValue }
+func (v BuiltinValue) Type() TypeValue { return BuiltinTypeValue }
+func (v DefinedValue) Type() TypeValue { return DefinedTypeValue }
+
+// Scope of symbols defined in the VM, hierarchical
+type Scope struct {
+	parent   *Scope
+	children []*Scope
+	symbols  map[string]Value
+}
+
+func NewScope(parent *Scope) *Scope {
+	return &Scope{parent, make([]*Scope, 0), make(map[string]Value)}
+}
+
+func (scope *Scope) Parent(level int) *Scope {
+	if level < 1 {
+		return scope
+	}
+	parent := scope.parent
+	for parent != nil && level > 1 {
+		level--
+		parent = parent.parent
+	}
+	return parent
+}
+
+func (scope *Scope) Lookup(name string) Value {
+	value, ok := scope.symbols[name]
+	if ok {
+		return value
+	}
+	if scope.parent != nil {
+		return scope.parent.Lookup(name)
+	}
+	return NilValue
+}
+
+// Frame of execution of a function
+type Frame struct {
+	parent    *Frame
+	arguments ListValue
+	results   ListValue
+	failed    bool
+}
+
+func NewFrame(parent *Frame) *Frame {
+	return &Frame{parent, NewListValue(), NewListValue(), false}
+}
+
+// Virtual machine
+type VM struct {
+	TopScope *Scope // Top level scope
+	TopFrame *Frame // Top level scope
+	*Scope          // Current Scope
+	*Frame          // Current frame
+}
+
+func NewVM() *VM {
+	vm := &VM{NewScope(nil), NewFrame(nil), nil, nil}
+	vm.Scope = vm.TopScope
+	vm.Frame = vm.TopFrame
+	return vm
+}
+
+func (vm *VM) CallDefined(ast *BasicAst, arguments ...Value) ListValue {
+	return NewListValue()
+}
+
+func (vm *VM) CallBuiltin(handler Handler, arguments ...Value) ListValue {
+	return NewListValue()
+}
+
+func (vm *VM) Register(name string, value Value) {
+
+}
+
+func (vm *VM) Fail() {
+	vm.Frame.failed = true
+}
+
+func (vm *VM) RunChildren(ast Ast, args ListValue) ListValue {
+	result := NewListValue()
+	for _, child := range ast.Children() {
+		val := child.Run(vm, args)
+		result.Append(val)
+	}
+	return result
+}
+
+/*
+
+func (vm *VM) RunProgram(ast *BasicAst) ListValue {
+	return vm.RunChildren(ast, (*VM).RunStatements)
+}
+
+func (vm *VM) RunStatements(ast *BasicAst) ListValue {
+	return vm.RunChildren(ast, (*VM).RunStatement)
+}
+
+func (vm *VM) RunStatement(ast *BasicAst) ListValue {
+	return NewListValue()
+}
+
+func (vm *VM) RunSet(ast *BasicAst) ListValue         { return NewListValue() }
+func (vm *VM) RunGet(ast *BasicAst) ListValue         { return NewListValue() }
+func (vm *VM) RunTarget(ast *BasicAst) ListValue      { return NewListValue() }
+func (vm *VM) RunCommand(ast *BasicAst) ListValue     { return NewListValue() }
+func (vm *VM) RunArguments(ast *BasicAst) ListValue   { return NewListValue() }
+func (vm *VM) RunArgument(ast *BasicAst) ListValue    { return NewListValue() }
+func (vm *VM) RunExpression(ast *BasicAst) ListValue  { return NewListValue() }
+func (vm *VM) RunBlock(ast *BasicAst) ListValue       { return NewListValue() }
+func (vm *VM) RunParenthesis(ast *BasicAst) ListValue { return NewListValue() }
+func (vm *VM) RunList(ast *BasicAst) ListValue        { return NewListValue() }
+func (vm *VM) RunCapture(ast *BasicAst) ListValue     { return NewListValue() }
+func (vm *VM) RunWordValue(ast *BasicAst) ListValue   { return NewListValue() }
+func (vm *VM) RunWord(ast *BasicAst) ListValue        { return NewListValue() }
+func (vm *VM) RunType(ast *BasicAst) ListValue        { return NewListValue() }
+func (vm *VM) RunValue(ast *BasicAst) ListValue       { return NewListValue() }
+func (vm *VM) RunEnd(ast *BasicAst) ListValue         { return NewListValue() }
+func (vm *VM) RunError(ast *BasicAst) ListValue       { return NewListValue() }
+
+func (vm *VM) Run(ast *BasicAst) ListValue {
+	switch ast.AstKind {
+	case AstKindProgram:
+		return vm.RunProgram(ast)
+	case AstKindStatements:
+		return vm.RunStatements(ast)
+	case AstKindStatement:
+		return vm.RunStatement(ast)
+	case AstKindSet:
+		return vm.RunSet(ast)
+	case AstKindGet:
+		return vm.RunGet(ast)
+	case AstKindTarget:
+		return vm.RunTarget(ast)
+	case AstKindCommand:
+		return vm.RunCommand(ast)
+	case AstKindArguments:
+		return vm.RunArguments(ast)
+	case AstKindArgument:
+		return vm.RunArgument(ast)
+	case AstKindExpression:
+		return vm.RunExpression(ast)
+	case AstKindBlock:
+		return vm.RunBlock(ast)
+	case AstKindParenthesis:
+		return vm.RunParenthesis(ast)
+	case AstKindList:
+		return vm.RunList(ast)
+	case AstKindCapture:
+		return vm.RunCapture(ast)
+	case AstKindWordValue:
+		return vm.RunWordValue(ast)
+	case AstKindWord:
+		return vm.RunWord(ast)
+	case AstKindType:
+		return vm.RunType(ast)
+	case AstKindValue:
+		return vm.RunValue(ast)
+	case AstKindEnd:
+		return vm.RunEnd(ast)
+	case AstKindError:
+		return vm.RunError(ast)
+	default:
+		return ListValue{[]Value{NewErrorValuef("Unknown ast node type: %d", ast.AstKind)}}
+	}
+}
+*/