|
|
@@ -15,7 +15,7 @@ func Eval(node ast.Node) object.Object {
|
|
|
switch node := node.(type) {
|
|
|
// Statements
|
|
|
case *ast.Program:
|
|
|
- return evalStatements(node.Statements)
|
|
|
+ return evalProgram(node)
|
|
|
|
|
|
case *ast.ExpressionStatement:
|
|
|
return Eval(node.Expression)
|
|
|
@@ -34,20 +34,29 @@ func Eval(node ast.Node) object.Object {
|
|
|
return evalInfixExpression(node.Operator, left, right)
|
|
|
|
|
|
case *ast.BlockStatement:
|
|
|
- return evalStatements(node.Statements)
|
|
|
+ return evalBlockStatements(node)
|
|
|
case *ast.IfExpression:
|
|
|
return evalIfExpression(node)
|
|
|
+
|
|
|
+ case *ast.ReturnStatement:
|
|
|
+ val := Eval(node.ReturnValue)
|
|
|
+ return &object.ReturnValue{Value: val}
|
|
|
}
|
|
|
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func evalStatements(stmts []ast.Statement) object.Object {
|
|
|
+func evalProgram(node *ast.Program) object.Object {
|
|
|
var result object.Object
|
|
|
|
|
|
- for _, statement := range stmts {
|
|
|
- result = Eval(statement)
|
|
|
+ for _, stmt := range node.Statements {
|
|
|
+ result = Eval(stmt)
|
|
|
+ // skip return 后面的语句
|
|
|
+ if rVal, ok := result.(*object.ReturnValue); ok {
|
|
|
+ return rVal.Value
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
return result
|
|
|
}
|
|
|
|
|
|
@@ -91,7 +100,18 @@ func evalIfExpression(node *ast.IfExpression) object.Object {
|
|
|
return NULL
|
|
|
}
|
|
|
}
|
|
|
+func evalBlockStatements(node *ast.BlockStatement) object.Object {
|
|
|
+ var result object.Object
|
|
|
+
|
|
|
+ for _, stmt := range node.Statements {
|
|
|
+ result = Eval(stmt)
|
|
|
|
|
|
+ if result != nil && result.Type() == object.ReturnValueObj {
|
|
|
+ return result
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result
|
|
|
+}
|
|
|
func evalIntegerInfixExpression(operator string,
|
|
|
left object.Object, right object.Object) object.Object {
|
|
|
leftVal := left.(*object.Integer).Value
|