aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobby <[email protected]>2023-11-02 22:28:15 -0400
committerBobby <[email protected]>2023-11-02 22:28:15 -0400
commit895fd381cc3867bb362f1abf19ffc26c41cbdbe7 (patch)
tree832f369d6558dbb9fd3fbd178955234fe5272053
parent3c98969220c0f3c6372aef3207a98e4cbcc9a135 (diff)
downloadmana-895fd381cc3867bb362f1abf19ffc26c41cbdbe7.tar.xz
mana-895fd381cc3867bb362f1abf19ffc26c41cbdbe7.zip
parser:return
-rw-r--r--ast/ast.go11
-rw-r--r--parser/parser.go20
-rw-r--r--parser/parser_test.go34
3 files changed, 64 insertions, 1 deletions
diff --git a/ast/ast.go b/ast/ast.go
index 7b75d35..d4493f3 100644
--- a/ast/ast.go
+++ b/ast/ast.go
@@ -52,3 +52,14 @@ func (i *Identifier) expressionNode() {}
func (i *Identifier) TokenLiteral() string {
return i.Token.Literal
}
+
+// ReturnStatement represents a return statement.
+type ReturnStatement struct {
+ Token tokens.Token // the token.RETURN token
+ ReturnValue Expression
+}
+
+func (rs *ReturnStatement) statementNode() {}
+func (rs *ReturnStatement) TokenLiteral() string {
+ return rs.Token.Literal
+}
diff --git a/parser/parser.go b/parser/parser.go
index 6e8bba6..bd587de 100644
--- a/parser/parser.go
+++ b/parser/parser.go
@@ -66,6 +66,8 @@ func (p *Parser) parseStatement() ast.Statement {
switch p.curToken.Type {
case tokens.LET:
return p.parseLetStatement()
+ case tokens.RETURN:
+ return p.parseReturnStatement()
default:
return nil
}
@@ -95,6 +97,22 @@ func (p *Parser) parseLetStatement() *ast.LetStatement {
return stmt
}
+// parseReturnStatement parses a return statement.
+func (p *Parser) parseReturnStatement() *ast.ReturnStatement {
+ var stmt *ast.ReturnStatement = &ast.ReturnStatement{Token: p.curToken}
+
+ p.nextToken()
+
+ // TODO: We're skipping the expressions until we
+ // encounter a semicolon.
+
+ for !p.curTokenIs(tokens.SEMICOLON) {
+ p.nextToken()
+ }
+
+ return stmt
+}
+
// curTokenIs returns true if the current token is of the given type.
func (p *Parser) curTokenIs(t tokens.TokenType) bool {
return p.curToken.Type == t
@@ -113,7 +131,7 @@ func (p *Parser) expectPeek(t tokens.TokenType) bool {
return true
} else {
p.peekError(t)
-
+
return false
}
}
diff --git a/parser/parser_test.go b/parser/parser_test.go
index 8f78c8b..0e27b51 100644
--- a/parser/parser_test.go
+++ b/parser/parser_test.go
@@ -89,3 +89,37 @@ func testLetStatement(t *testing.T, s ast.Statement, name string) bool {
return true
}
+
+
+// Return statement tests.
+func TestReturnStatements(t *testing.T) {
+ var input string = `
+ return 5;
+ return 10;
+ return 993322;
+ `
+
+ var l *lexer.Lexer = lexer.New(input)
+ var p *Parser = New(l)
+
+ var program *ast.Program = p.ParseProgram()
+ checkParserErrors(t, p)
+
+ if len(program.Statements) != 3 {
+ t.Fatalf("program.Statements does not contain 3 statements. got=%d", len(program.Statements))
+ }
+
+ for _, stmt := range program.Statements {
+ var returnStmt, ok = stmt.(*ast.ReturnStatement)
+
+ if !ok {
+ t.Errorf("stmt not *ast.ReturnStatement. got=%T", stmt)
+
+ continue
+ }
+
+ if returnStmt.TokenLiteral() != "return" {
+ t.Errorf("returnStmt.TokenLiteral not 'return', got %q", returnStmt.TokenLiteral())
+ }
+ }
+}