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