Skip to content

Instantly share code, notes, and snippets.

@mrnugget
Created August 18, 2020 05:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrnugget/4ea12bc08345c7f13881e6b600c32a46 to your computer and use it in GitHub Desktop.
Save mrnugget/4ea12bc08345c7f13881e6b600c32a46 to your computer and use it in GitHub Desktop.
Change the Monkey parser to expect expression statements to either end in a semicolon, a closing brace (because of `if (x) { foo }`) or EOF
diff --git a/parser/parser.go b/parser/parser.go
index dbd581d..c7ebdf9 100644
--- a/parser/parser.go
+++ b/parser/parser.go
@@ -114,6 +114,20 @@ func (p *Parser) expectPeek(t token.TokenType) bool {
}
}
+func (p *Parser) expectStatementEnd() bool {
+ switch p.peekToken.Type {
+ case token.SEMICOLON, token.EOF:
+ p.nextToken()
+ return true
+ case token.RBRACE:
+ // do not consume it
+ return true
+ default:
+ p.peekError(token.SEMICOLON)
+ return false
+ }
+}
+
func (p *Parser) Errors() []string {
return p.errors
}
@@ -202,9 +216,7 @@ func (p *Parser) parseExpressionStatement() *ast.ExpressionStatement {
stmt.Expression = p.parseExpression(LOWEST)
- if p.peekTokenIs(token.SEMICOLON) {
- p.nextToken()
- }
+ p.expectStatementEnd()
return stmt
}
diff --git a/parser/parser_test.go b/parser/parser_test.go
index 75f08bf..6865628 100644
--- a/parser/parser_test.go
+++ b/parser/parser_test.go
@@ -656,6 +656,23 @@ func TestCallExpressionParsing(t *testing.T) {
testInfixExpression(t, exp.Arguments[2], 4, "+", 5)
}
+func TestCallExpressionWithoutParens(t *testing.T) {
+ input := `puts "hello"`
+
+ l := lexer.New(input)
+ p := New(l)
+ _ = p.ParseProgram()
+
+ errs := p.Errors()
+ if len(errs) != 1 {
+ t.Errorf("expected parser errors, but got none")
+ }
+
+ if have, want := errs[0], "expected next token to be ;, got STRING instead"; have != want {
+ t.Errorf("wrong error. want=%q, have=%q", want, have)
+ }
+}
+
func TestCallExpressionParameterParsing(t *testing.T) {
tests := []struct {
input string
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment