|
@@ -32,6 +32,11 @@ func Eval(node ast.Node) object.Object {
|
|
|
left := Eval(node.Left)
|
|
left := Eval(node.Left)
|
|
|
right := Eval(node.Right)
|
|
right := Eval(node.Right)
|
|
|
return evalInfixExpression(node.Operator, left, right)
|
|
return evalInfixExpression(node.Operator, left, right)
|
|
|
|
|
+
|
|
|
|
|
+ case *ast.BlockStatement:
|
|
|
|
|
+ return evalStatements(node.Statements)
|
|
|
|
|
+ case *ast.IfExpression:
|
|
|
|
|
+ return evalIfExpression(node)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
return nil
|
|
@@ -76,6 +81,16 @@ func evalInfixExpression(operator string, left object.Object, right object.Objec
|
|
|
return NULL
|
|
return NULL
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+func evalIfExpression(node *ast.IfExpression) object.Object {
|
|
|
|
|
+ condition := Eval(node.Condition)
|
|
|
|
|
+ if isTruthy(condition) {
|
|
|
|
|
+ return Eval(node.Consequence)
|
|
|
|
|
+ } else if node.Alternative != nil {
|
|
|
|
|
+ return Eval(node.Alternative)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return NULL
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
func evalIntegerInfixExpression(operator string,
|
|
func evalIntegerInfixExpression(operator string,
|
|
|
left object.Object, right object.Object) object.Object {
|
|
left object.Object, right object.Object) object.Object {
|
|
@@ -122,3 +137,16 @@ func evalBangOperatorExpression(right object.Object) object.Object {
|
|
|
return FALSE
|
|
return FALSE
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+func isTruthy(obj object.Object) bool {
|
|
|
|
|
+ switch obj {
|
|
|
|
|
+ case NULL:
|
|
|
|
|
+ return false
|
|
|
|
|
+ case TRUE:
|
|
|
|
|
+ return true
|
|
|
|
|
+ case FALSE:
|
|
|
|
|
+ return false
|
|
|
|
|
+ default:
|
|
|
|
|
+ return true
|
|
|
|
|
+ }
|
|
|
|
|
+}
|