diff options
Diffstat (limited to 'parse.go')
-rw-r--r-- | parse.go | 107 |
1 files changed, 102 insertions, 5 deletions
@@ -236,7 +236,6 @@ func parseBlock(toks *tokens) (*blockExpr, error) { return nil, err } if stmt == nil { - expectStmt = true break } @@ -255,18 +254,38 @@ func parseBlock(toks *tokens) (*blockExpr, error) { } func parseStatement(toks *tokens) (statementExpr, error) { + stmt, err := parseStatementContents(toks) + if err != nil { + return nil, err + } + if stmt == nil { + return nil, nil + } + + if err := toks.mustMatch(semicolon); err != nil { + return nil, err + } + + return stmt, nil +} + +func parseStatementContents(toks *tokens) (statementExpr, error) { stmt, err := parseReturnStmt(toks) if err != nil { return nil, err } if stmt != nil { - if err := toks.mustMatch(semicolon); err != nil { - return nil, err - } - return stmt, nil } + decl, err := parseDeclaration(toks) + if err != nil { + return nil, err + } + if decl != nil { + return decl, nil + } + return nil, nil } @@ -288,6 +307,84 @@ func parseReturnStmt(toks *tokens) (*returnStmt, error) { return &returnStmt{value: expr, ln: toks.current().line}, nil } +func parseDeclaration(toks *tokens) (declStmt, error) { + constant, err := parseConstStmt(toks) + if err != nil { + return nil, err + } + if constant != nil { + return constant, nil + } + + mutable, err := parseMutStmt(toks) + if err != nil { + return nil, err + } + if mutable != nil { + return mutable, nil + } + + return nil, nil +} + +func parseConstStmt(toks *tokens) (*constStmt, error) { + ok, err := toks.match(constKeyword) + if err != nil { + return nil, err + } + if !ok { + toks.unreadToken() + return nil, nil + } + + line := toks.current().line + + nameTok, ok := toks.consumeToken() + if !ok { + return nil, unexpectedEOF + } + + if err := toks.mustMatch(equals); err != nil { + return nil, err + } + + expr, err := parseExpression(toks) + if err != nil { + return nil, err + } + + return &constStmt{name: nameTok.value, initial: expr, ln: line}, nil +} + +func parseMutStmt(toks *tokens) (*mutStmt, error) { + ok, err := toks.match(mut) + if err != nil { + return nil, err + } + if !ok { + toks.unreadToken() + return nil, nil + } + + line := toks.current().line + + nameTok, ok := toks.consumeToken() + if !ok { + return nil, unexpectedEOF + } + + if err := toks.mustMatch(equals); err != nil { + return nil, err + } + + expr, err := parseExpression(toks) + if err != nil { + return nil, err + } + + return &mutStmt{name: nameTok.value, initial: expr, ln: line}, nil +} + func parseExpression(toks *tokens) (exprExpr, error) { return parseEquality(toks) } |