浏览代码

prefix expression object evaluator

simon 3 年之前
父节点
当前提交
c08784cd0c
共有 2 个文件被更改,包括 54 次插入0 次删除
  1. 33 0
      evaluator/evaluator.go
  2. 21 0
      evaluator/evaluator_test.go

+ 33 - 0
evaluator/evaluator.go

@@ -25,6 +25,9 @@ func Eval(node ast.Node) object.Object {
 		return &object.Integer{Value: node.Value}
 	case *ast.Boolean:
 		return nativeBooleanObject(node.Value)
+	case *ast.PrefixExpression:
+		right := Eval(node.Right)
+		return evalPrefixExpression(node.Operator, right)
 	}
 
 	return nil
@@ -46,3 +49,33 @@ func nativeBooleanObject(input bool) *object.Boolean {
 		return FALSE
 	}
 }
+
+func evalPrefixExpression(operator string, right object.Object) object.Object {
+	switch operator {
+	case "!":
+		return evalBangOperatorExpression(right)
+	case "-":
+		return evalMinusPreOperatorExpression(right)
+	default:
+		return NULL
+	}
+}
+
+func evalMinusPreOperatorExpression(right object.Object) object.Object {
+	if right.Type() != object.IntegerObj {
+		return NULL
+	}
+	value := right.(*object.Integer).Value
+	return &object.Integer{Value: -value}
+}
+
+func evalBangOperatorExpression(right object.Object) object.Object {
+	switch right {
+	case TRUE:
+		return FALSE
+	case FALSE:
+		return TRUE
+	default:
+		return FALSE
+	}
+}

+ 21 - 0
evaluator/evaluator_test.go

@@ -14,6 +14,8 @@ func TestEvalIntegerExpression(t *testing.T) {
 	}{
 		{"5", 5},
 		{"10", 10},
+		{"-5", -5},
+		{"-10", -10},
 	}
 
 	for _, tt := range tests {
@@ -37,6 +39,25 @@ 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 testIntegerObject(t *testing.T, obj object.Object, expected int64) bool {
 	result, ok := obj.(*object.Integer)
 	if !ok {