bitwise operators and boolean operators
This commit is contained in:
@@ -256,15 +256,22 @@ func nativeBoolToBooleanObject(input bool) object.Object {
|
||||
func evalPrefixExpression(operator string, right object.Object) object.Object {
|
||||
switch operator {
|
||||
case "!":
|
||||
return evalBangOperatorExpression(right)
|
||||
case "-":
|
||||
return evalMinusPrefixOperatorExpression(right)
|
||||
if right.Type() == object.BOOLEAN_OBJ {
|
||||
return evalBooleanPrefixOperatorExpression(operator, right)
|
||||
}
|
||||
return evalIntegerPrefixOperatorExpression(operator, right)
|
||||
case "~", "-":
|
||||
return evalIntegerPrefixOperatorExpression(operator, right)
|
||||
default:
|
||||
return newError("unknown operator: %s%s", operator, right.Type())
|
||||
}
|
||||
}
|
||||
|
||||
func evalBangOperatorExpression(right object.Object) object.Object {
|
||||
func evalBooleanPrefixOperatorExpression(operator string, right object.Object) object.Object {
|
||||
if right.Type() != object.BOOLEAN_OBJ {
|
||||
return newError("unknown operator: %s%s", operator, right.Type())
|
||||
}
|
||||
|
||||
switch right {
|
||||
case TRUE:
|
||||
return FALSE
|
||||
@@ -277,17 +284,28 @@ func evalBangOperatorExpression(right object.Object) object.Object {
|
||||
}
|
||||
}
|
||||
|
||||
func evalMinusPrefixOperatorExpression(right object.Object) object.Object {
|
||||
func evalIntegerPrefixOperatorExpression(operator string, right object.Object) object.Object {
|
||||
if right.Type() != object.INTEGER_OBJ {
|
||||
return newError("unknown operator: -%s", right.Type())
|
||||
}
|
||||
|
||||
value := right.(*object.Integer).Value
|
||||
return &object.Integer{Value: -value}
|
||||
switch operator {
|
||||
case "!":
|
||||
return FALSE
|
||||
case "~":
|
||||
return &object.Integer{Value: ^value}
|
||||
case "-":
|
||||
return &object.Integer{Value: -value}
|
||||
default:
|
||||
return newError("unknown operator: %s", operator)
|
||||
}
|
||||
}
|
||||
|
||||
func evalInfixExpression(operator string, left, right object.Object) object.Object {
|
||||
switch {
|
||||
case left.Type() == object.BOOLEAN_OBJ && right.Type() == object.BOOLEAN_OBJ:
|
||||
return evalBooleanInfixExpression(operator, left, right)
|
||||
case left.Type() == object.INTEGER_OBJ && right.Type() == object.INTEGER_OBJ:
|
||||
return evalIntegerInfixExpression(operator, left, right)
|
||||
case left.Type() == object.STRING_OBJ && right.Type() == object.STRING_OBJ:
|
||||
@@ -303,6 +321,24 @@ func evalInfixExpression(operator string, left, right object.Object) object.Obje
|
||||
}
|
||||
}
|
||||
|
||||
func evalBooleanInfixExpression(operator string, left, right object.Object) object.Object {
|
||||
leftVal := left.(*object.Boolean).Value
|
||||
rightVal := right.(*object.Boolean).Value
|
||||
|
||||
switch operator {
|
||||
case "==":
|
||||
return nativeBoolToBooleanObject(left == right)
|
||||
case "!=":
|
||||
return nativeBoolToBooleanObject(leftVal != rightVal)
|
||||
case "&&":
|
||||
return &object.Boolean{Value: leftVal && rightVal}
|
||||
case "||":
|
||||
return &object.Boolean{Value: leftVal || rightVal}
|
||||
default:
|
||||
return newError("unknown operator: %s %s %s", left.Type(), operator, right.Type())
|
||||
}
|
||||
}
|
||||
|
||||
func evalStringInfixExpression(operator string, left object.Object, right object.Object) object.Object {
|
||||
leftVal := left.(*object.String).Value
|
||||
rightVal := right.(*object.String).Value
|
||||
@@ -338,6 +374,12 @@ func evalIntegerInfixExpression(operator string, left, right object.Object) obje
|
||||
return &object.Integer{Value: leftVal / rightVal}
|
||||
case "%":
|
||||
return &object.Integer{Value: leftVal % rightVal}
|
||||
case "|":
|
||||
return &object.Integer{Value: leftVal | rightVal}
|
||||
case "^":
|
||||
return &object.Integer{Value: leftVal ^ rightVal}
|
||||
case "&":
|
||||
return &object.Integer{Value: leftVal & rightVal}
|
||||
case "<":
|
||||
return nativeBoolToBooleanObject(leftVal < rightVal)
|
||||
case "<=":
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
func TestEvalIntegerExpression(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
expected int64
|
||||
expected interface{}
|
||||
}{
|
||||
{"5", 5},
|
||||
{"10", 10},
|
||||
@@ -30,12 +30,21 @@ func TestEvalIntegerExpression(t *testing.T) {
|
||||
{"3 * 3 * 3 + 10", 37},
|
||||
{"3 * (3 * 3) + 10", 37},
|
||||
{"(5 + 10 * 2 + 15 / 3) * 2 + -10", 50},
|
||||
{"!1", false},
|
||||
{"~1", -2},
|
||||
{"5 % 2", 1},
|
||||
{"1 | 2", 3},
|
||||
{"2 ^ 4", 6},
|
||||
{"3 & 6", 2},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
evaluated := testEval(tt.input)
|
||||
testIntegerObject(t, evaluated, tt.expected)
|
||||
if expected, ok := tt.expected.(int64); ok {
|
||||
testIntegerObject(t, evaluated, expected)
|
||||
} else if expected, ok := tt.expected.(bool); ok {
|
||||
testBooleanObject(t, evaluated, expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +55,16 @@ func TestEvalBooleanExpression(t *testing.T) {
|
||||
}{
|
||||
{"true", true},
|
||||
{"false", false},
|
||||
{"!true", false},
|
||||
{"!false", true},
|
||||
{"true && true", true},
|
||||
{"false && true", false},
|
||||
{"true && false", false},
|
||||
{"false && false", false},
|
||||
{"true || true", true},
|
||||
{"false || true", true},
|
||||
{"true || false", true},
|
||||
{"false || false", false},
|
||||
{"1 < 2", true},
|
||||
{"1 > 2", false},
|
||||
{"1 < 1", false},
|
||||
@@ -78,25 +97,6 @@ func TestEvalBooleanExpression(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestBangOperator(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
expected bool
|
||||
}{
|
||||
{"!true", false},
|
||||
{"!false", true},
|
||||
{"!5", false},
|
||||
{"!!true", true},
|
||||
{"!!false", false},
|
||||
{"!!5", true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
evaluated := testEval(tt.input)
|
||||
testBooleanObject(t, evaluated, tt.expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIfElseExpression(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
|
||||
Reference in New Issue
Block a user