|
|
|
@ -83,7 +83,7 @@ func (p *Parser) varDeclaration() ast.Stmt {
|
|
|
|
return &ast.VarStmt{Name: name, Initializer: initializer}
|
|
|
|
return &ast.VarStmt{Name: name, Initializer: initializer}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// statement → exprStmt | ifStmt | printStmt | block ;
|
|
|
|
// statement → exprStmt | ifStmt | printStmt | whileStmt | block ;
|
|
|
|
func (p *Parser) statement() ast.Stmt {
|
|
|
|
func (p *Parser) statement() ast.Stmt {
|
|
|
|
if p.match(token.IF) {
|
|
|
|
if p.match(token.IF) {
|
|
|
|
return p.ifStatement()
|
|
|
|
return p.ifStatement()
|
|
|
|
@ -91,6 +91,9 @@ func (p *Parser) statement() ast.Stmt {
|
|
|
|
if p.match(token.PRINT) {
|
|
|
|
if p.match(token.PRINT) {
|
|
|
|
return p.printStatement()
|
|
|
|
return p.printStatement()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if p.match(token.WHILE) {
|
|
|
|
|
|
|
|
return p.whileStatement()
|
|
|
|
|
|
|
|
}
|
|
|
|
if p.match(token.LEFT_BRACE) {
|
|
|
|
if p.match(token.LEFT_BRACE) {
|
|
|
|
return p.blockStatement()
|
|
|
|
return p.blockStatement()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -132,6 +135,25 @@ func (p *Parser) printStatement() ast.Stmt {
|
|
|
|
return &ast.PrintStmt{Expression: expr}
|
|
|
|
return &ast.PrintStmt{Expression: expr}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// whileStmt → "while" "(" expression ")" statement ;
|
|
|
|
|
|
|
|
func (p *Parser) whileStatement() ast.Stmt {
|
|
|
|
|
|
|
|
err := p.consume(token.LEFT_PAREN, "Expect '(' after 'while'.")
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return p.fromErrorExpr(err)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
condition := p.expression()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
err = p.consume(token.RIGHT_PAREN, "Expect ')' after while condition.")
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return p.fromErrorExpr(err)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
body := p.statement()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return &ast.WhileStmt{Condition: condition, Body: body}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// block → "{" declaration* "}" ;
|
|
|
|
// block → "{" declaration* "}" ;
|
|
|
|
func (p *Parser) blockStatement() ast.Stmt {
|
|
|
|
func (p *Parser) blockStatement() ast.Stmt {
|
|
|
|
statements := []ast.Stmt{}
|
|
|
|
statements := []ast.Stmt{}
|
|
|
|
@ -164,9 +186,9 @@ func (p *Parser) expression() ast.Expr {
|
|
|
|
return p.assignment()
|
|
|
|
return p.assignment()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// assignment → IDENTIFIER "=" assignment | equality ;
|
|
|
|
// assignment → IDENTIFIER "=" assignment | logic_or ;
|
|
|
|
func (p *Parser) assignment() ast.Expr {
|
|
|
|
func (p *Parser) assignment() ast.Expr {
|
|
|
|
expr := p.equality()
|
|
|
|
expr := p.or()
|
|
|
|
|
|
|
|
|
|
|
|
if p.match(token.EQUAL) {
|
|
|
|
if p.match(token.EQUAL) {
|
|
|
|
equals := p.previous()
|
|
|
|
equals := p.previous()
|
|
|
|
@ -182,6 +204,32 @@ func (p *Parser) assignment() ast.Expr {
|
|
|
|
return expr
|
|
|
|
return expr
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// logic_or → logic_and ( "or" logic_and )* ;
|
|
|
|
|
|
|
|
func (p *Parser) or() ast.Expr {
|
|
|
|
|
|
|
|
expr := p.and()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for p.match(token.OR) {
|
|
|
|
|
|
|
|
operator := p.previous()
|
|
|
|
|
|
|
|
right := p.and()
|
|
|
|
|
|
|
|
expr = &ast.LogicalExpr{Left: expr, Operator: operator, Right: right}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return expr
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// logic_and → equality ( "and" equality )* ;
|
|
|
|
|
|
|
|
func (p *Parser) and() ast.Expr {
|
|
|
|
|
|
|
|
expr := p.equality()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for p.match(token.AND) {
|
|
|
|
|
|
|
|
operator := p.previous()
|
|
|
|
|
|
|
|
right := p.equality()
|
|
|
|
|
|
|
|
expr = &ast.LogicalExpr{Left: expr, Operator: operator, Right: right}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return expr
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// equality → comparison ( ( "!=" | "==" ) comparison )* ;
|
|
|
|
// equality → comparison ( ( "!=" | "==" ) comparison )* ;
|
|
|
|
func (p *Parser) equality() ast.Expr {
|
|
|
|
func (p *Parser) equality() ast.Expr {
|
|
|
|
expr := p.comparison()
|
|
|
|
expr := p.comparison()
|
|
|
|
|