aboutsummaryrefslogtreecommitdiff
path: root/parse.go
diff options
context:
space:
mode:
Diffstat (limited to 'parse.go')
-rw-r--r--parse.go107
1 files changed, 102 insertions, 5 deletions
diff --git a/parse.go b/parse.go
index 5261dfe..fa01c52 100644
--- a/parse.go
+++ b/parse.go
@@ -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)
}