Skip to content

Commit

Permalink
feat: adds support for booleans
Browse files Browse the repository at this point in the history
  • Loading branch information
Tezzish committed Sep 25, 2024
1 parent cff190a commit ce73688
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 3 deletions.
9 changes: 9 additions & 0 deletions ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,12 @@ func (rs *ReturnStatement) String() string {
out.WriteString(";")
return out.String()
}

type Boolean struct {
Token token.Token
Value bool
}

func (b *Boolean) expressionNode() {}
func (b *Boolean) TokenLiteral() string { return b.Token.Literal }
func (b *Boolean) String() string { return b.Token.Literal }
12 changes: 10 additions & 2 deletions parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ func New(l *lexer.Lexer) *Parser {
l: l,
errors: []string{},
}
// read two tokens so curToken and peekToken are both set
p.nextToken()
p.nextToken()

Expand All @@ -54,6 +55,8 @@ func New(l *lexer.Lexer) *Parser {
p.registerPrefix(token.INT, p.parseIntegerLiteral)
p.registerPrefix(token.BANG, p.parsePrefixExpression)
p.registerPrefix(token.MINUS, p.parsePrefixExpression)
p.registerPrefix(token.TRUE, p.parseBoolean)
p.registerPrefix(token.FALSE, p.parseBoolean)
p.infixParseFns = make(map[token.TokenType]infixParseFn)
p.registerInfix(token.PLUS, p.parseInfixExpression)
p.registerInfix(token.MINUS, p.parseInfixExpression)
Expand Down Expand Up @@ -172,6 +175,10 @@ func (p *Parser) parseIntegerLiteral() ast.Expression {
return literal
}

func (p *Parser) parseBoolean() ast.Expression {
return &ast.Boolean{Token: p.curToken, Value: p.curTokenIs(token.TRUE)}
}

func (p *Parser) parseLetStatement() *ast.LetStatement {
stmt := &ast.LetStatement{Token: p.curToken}
// if the next token is not an identifier, we return nil
Expand Down Expand Up @@ -221,7 +228,6 @@ func (p *Parser) parseExpression(precedence int) ast.Expression {
// else we move onto the next token
p.nextToken()
// and we call the infix function on the previous prefix
// we will call the parseInfixExpression with the leftExp as our left
leftExp = infix(leftExp)
}
return leftExp
Expand Down Expand Up @@ -261,9 +267,11 @@ func (p *Parser) parseInfixExpression(left ast.Expression) ast.Expression {
Operator: p.curToken.Literal,
Left: left,
}
//
// get the precedence of the current token
precedence := p.curPrecedence()
// move to the next token
p.nextToken()
// parse the expression
expression.Right = p.parseExpression(precedence)

return expression
Expand Down
35 changes: 34 additions & 1 deletion parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ func TestIdentifierExpression(t *testing.T) {
if ident.Value != "foobar" {
t.Errorf("ident.Value not %s. got=%s", "foobar", ident.TokenLiteral())
}

}

func TestIntegerLiteralExpression(t *testing.T) {
Expand Down Expand Up @@ -160,6 +159,40 @@ func TestIntegerLiteralExpression(t *testing.T) {
}
}

func TestBooleanExpression(t *testing.T) {
boolTests := []struct {
input string
value bool
}{
{"true;", true},
{"false;", false},
}
for _, tt := range boolTests {
l := lexer.New(tt.input)
p := New(l)
program := p.ParseProgram()
checkParserErrors(t, p)
if len(program.Statements) != 1 {
t.Fatalf("program has not enough statements. got=%d",
len(program.Statements))
}
stmt, ok := program.Statements[0].(*ast.ExpressionStatement)
if !ok {
t.Fatalf("program.Statements[0] is not ast.ExpressionStatement. got=%T", program.Statements[0])
}

exp, ok := stmt.Expression.(*ast.Boolean)
if !ok {
t.Fatalf("stmt is not ast.Boolean. got=%T", stmt.Expression)
}

if exp.Value != tt.value {
t.Fatalf("exp.Operator is not '%t'. got=%T", tt.value, exp.Value)
}
}

}

func TestParsingPrefixExressions(t *testing.T) {
prefixTests := []struct {
input string
Expand Down

0 comments on commit ce73688

Please sign in to comment.