Skip to content

Commit

Permalink
implement LT_EQ and GT_EQ (#48)
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkusFreitag authored Jan 16, 2022
1 parent 91199d8 commit b655395
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 5 deletions.
9 changes: 8 additions & 1 deletion evaluator/evaluator_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package evaluator

import (
"testing"

"github.com/flipez/rocket-lang/lexer"
"github.com/flipez/rocket-lang/object"
"github.com/flipez/rocket-lang/parser"
"github.com/flipez/rocket-lang/utilities"
"testing"
)

func TestEvalIntegerExpression(t *testing.T) {
Expand Down Expand Up @@ -47,6 +48,12 @@ func TestEvalBooleanExpression(t *testing.T) {
{"1 > 2", false},
{"1 < 1", false},
{"1 > 1", false},
{"1 <= 2", true},
{"2 <= 2", true},
{"3 <= 2", false},
{"2 >= 1", true},
{"2 >= 2", true},
{"2 >= 3", false},
{"1 == 1", true},
{"1 != 1", false},
{"1 == 2", false},
Expand Down
8 changes: 8 additions & 0 deletions evaluator/infix.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,12 @@ func evalIntegerInfix(operator string, left, right object.Object) object.Object
return &object.Integer{Value: leftVal / rightVal}
case "<":
return nativeBoolToBooleanObject(leftVal < rightVal)
case "<=":
return nativeBoolToBooleanObject(leftVal <= rightVal)
case ">":
return nativeBoolToBooleanObject(leftVal > rightVal)
case ">=":
return nativeBoolToBooleanObject(leftVal >= rightVal)
default:
return newError("unknown operator: %s %s %s", left.Type(), operator, right.Type())
}
Expand All @@ -47,8 +51,12 @@ func evalFloatInfix(operator string, left, right object.Object) object.Object {
return &object.Float{Value: leftVal / rightVal}
case "<":
return nativeBoolToBooleanObject(leftVal < rightVal)
case "<=":
return nativeBoolToBooleanObject(leftVal <= rightVal)
case ">":
return nativeBoolToBooleanObject(leftVal > rightVal)
case ">=":
return nativeBoolToBooleanObject(leftVal >= rightVal)
default:
return newError("unknown operator: %s %s %s", left.Type(), operator, right.Type())
}
Expand Down
16 changes: 14 additions & 2 deletions lexer/lexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,21 @@ func (l *Lexer) NextToken() token.Token {
case '*':
tok = token.NewToken(token.ASTERISK, l.ch)
case '<':
tok = token.NewToken(token.LT, l.ch)
if l.peekChar() == '=' {
ch := l.ch
l.readChar()
tok = token.NewToken(token.LT_EQ, string(ch)+string(l.ch))
} else {
tok = token.NewToken(token.LT, l.ch)
}
case '>':
tok = token.NewToken(token.GT, l.ch)
if l.peekChar() == '=' {
ch := l.ch
l.readChar()
tok = token.NewToken(token.GT_EQ, string(ch)+string(l.ch))
} else {
tok = token.NewToken(token.GT, l.ch)
}
case ';':
tok = token.NewToken(token.SEMICOLON, l.ch)
case ',':
Expand Down
8 changes: 8 additions & 0 deletions lexer/lexer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ func TestNextToken(t *testing.T) {
"foo bar"
[1, 2];
{"foo": "bar"}
5 <= 10 >= 5;
`

tests := []struct {
Expand Down Expand Up @@ -118,6 +120,12 @@ func TestNextToken(t *testing.T) {
{token.COLON, ":"},
{token.STRING, "bar"},
{token.RBRACE, "}"},
{token.INT, "5"},
{token.LT_EQ, "<="},
{token.INT, "10"},
{token.GT_EQ, ">="},
{token.INT, "5"},
{token.SEMICOLON, ";"},
{token.EOF, ""},
}

Expand Down
4 changes: 4 additions & 0 deletions parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ var precedences = map[token.TokenType]int{
token.EQ: EQUALS,
token.NOT_EQ: EQUALS,
token.LT: LESSGREATER,
token.LT_EQ: LESSGREATER,
token.GT: LESSGREATER,
token.GT_EQ: LESSGREATER,
token.PLUS: SUM,
token.MINUS: SUM,
token.SLASH: PRODUCT,
Expand Down Expand Up @@ -89,7 +91,9 @@ func New(l *lexer.Lexer, imports map[string]struct{}) *Parser {
p.registerInfix(token.NOT_EQ, p.parseInfix)
p.registerInfix(token.PERIOD, p.parseMethodCall)
p.registerInfix(token.LT, p.parseInfix)
p.registerInfix(token.LT_EQ, p.parseInfix)
p.registerInfix(token.GT, p.parseInfix)
p.registerInfix(token.GT_EQ, p.parseInfix)
p.registerInfix(token.LPAREN, p.parseCall)
p.registerInfix(token.LBRACKET, p.parseIndex)

Expand Down
2 changes: 2 additions & 0 deletions parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,8 @@ func TestParsingInfixExpressions(t *testing.T) {
{"5 / 5;", 5, "/", 5},
{"5 > 5;", 5, ">", 5},
{"5 < 5;", 5, "<", 5},
{"5 >= 5;", 5, ">=", 5},
{"5 <= 5;", 5, "<=", 5},
{"5 == 5;", 5, "==", 5},
{"5 != 5;", 5, "!=", 5},
{"true == true", true, "==", true},
Expand Down
6 changes: 4 additions & 2 deletions token/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ const (
ASTERISK = "*"
SLASH = "/"

LT = "<"
GT = ">"
LT = "<"
LT_EQ = "<="
GT = ">"
GT_EQ = ">="

COMMA = ","
SEMICOLON = ";"
Expand Down

1 comment on commit b655395

@vercel
Copy link

@vercel vercel bot commented on b655395 Jan 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.