Skip to content

Commit

Permalink
Combined comparison operator <=>, closes #71
Browse files Browse the repository at this point in the history
```
1 <=> 0 // 1
0 <=> 0 // 0
-1 <=> 0 // -1
```
  • Loading branch information
odino committed Dec 24, 2018
1 parent 27dfa68 commit ebbf49d
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 25 deletions.
12 changes: 12 additions & 0 deletions evaluator/evaluator.go
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,18 @@ func evalIntegerInfixExpression(
return nativeBoolToBooleanObject(leftVal <= rightVal)
case ">=":
return nativeBoolToBooleanObject(leftVal >= rightVal)
case "<=>":
i := &object.Integer{}

if leftVal == rightVal {
i.Value = 0
} else if leftVal > rightVal {
i.Value = 1
} else {
i.Value = -1
}

return i
case "==":
return nativeBoolToBooleanObject(leftVal == rightVal)
case "!=":
Expand Down
3 changes: 3 additions & 0 deletions evaluator/evaluator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ func TestEvalIntegerExpression(t *testing.T) {
{"10 && 1", 1},
{"0 && 3", 0},
{`"hello" && 10`, 10},
{"0 <=> 1", -1},
{"1 <=> 1", 0},
{"2 <=> 1", 1},
}

for _, tt := range tests {
Expand Down
44 changes: 23 additions & 21 deletions parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,28 @@ const (
)

var precedences = map[token.TokenType]int{
token.AND: AND,
token.OR: AND,
token.EQ: EQUALS,
token.NOT_EQ: EQUALS,
token.TILDE: EQUALS,
token.IN: EQUALS,
token.COMMA: EQUALS,
token.LT: LESSGREATER,
token.LT_EQ: LESSGREATER,
token.GT: LESSGREATER,
token.GT_EQ: LESSGREATER,
token.PLUS: SUM,
token.MINUS: SUM,
token.SLASH: PRODUCT,
token.ASTERISK: PRODUCT,
token.EXPONENT: PRODUCT,
token.RANGE: RANGE,
token.LPAREN: CALL,
token.LBRACKET: INDEX,
token.DOT: DOT,
token.PIPE: DOT,
token.AND: AND,
token.OR: AND,
token.EQ: EQUALS,
token.NOT_EQ: EQUALS,
token.TILDE: EQUALS,
token.IN: EQUALS,
token.COMMA: EQUALS,
token.LT: LESSGREATER,
token.LT_EQ: LESSGREATER,
token.GT: LESSGREATER,
token.GT_EQ: LESSGREATER,
token.COMBINED_COMP: LESSGREATER,
token.PLUS: SUM,
token.MINUS: SUM,
token.SLASH: PRODUCT,
token.ASTERISK: PRODUCT,
token.EXPONENT: PRODUCT,
token.RANGE: RANGE,
token.LPAREN: CALL,
token.LBRACKET: INDEX,
token.DOT: DOT,
token.PIPE: DOT,
}

type (
Expand Down Expand Up @@ -104,6 +105,7 @@ func New(l *lexer.Lexer) *Parser {
p.registerInfix(token.LT_EQ, p.parseInfixExpression)
p.registerInfix(token.GT, p.parseInfixExpression)
p.registerInfix(token.GT_EQ, p.parseInfixExpression)
p.registerInfix(token.COMBINED_COMP, p.parseInfixExpression)
p.registerInfix(token.AND, p.parseInfixExpression)
p.registerInfix(token.OR, p.parseInfixExpression)
p.registerInfix(token.RANGE, p.parseInfixExpression)
Expand Down
1 change: 1 addition & 0 deletions parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ func TestParsingInfixExpressions(t *testing.T) {
{"5 ~ 5;", 5, "~", 5},
{"5 != 5;", 5, "!=", 5},
{"5 ** 5;", 5, "**", 5},
{"5 <=> 5;", 5, "<=>", 5},
{"foobar + barfoo;", "foobar", "+", "barfoo"},
{"foobar - barfoo;", "foobar", "-", "barfoo"},
{"foobar * barfoo;", "foobar", "*", "barfoo"},
Expand Down
9 changes: 5 additions & 4 deletions token/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ const (
AND = "&&"
OR = "OR"

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

EQ = "=="
NOT_EQ = "!="
Expand Down

0 comments on commit ebbf49d

Please sign in to comment.