From be8b61cf6770ac252f5295e029042ad2bc33f509 Mon Sep 17 00:00:00 2001 From: Jonak-Adipta-Kalita Date: Sat, 8 Apr 2023 15:15:46 +0530 Subject: [PATCH] evaluating if statements!! --- evaluator/evaluator.go | 32 ++++++++++++++++++++++++++++++-- object/object.go | 14 +++++++++++--- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/evaluator/evaluator.go b/evaluator/evaluator.go index 1ddc13c..30d9981 100644 --- a/evaluator/evaluator.go +++ b/evaluator/evaluator.go @@ -14,7 +14,7 @@ var ( func Eval(node ast.Node) object.Object { switch node := node.(type) { case *ast.Program: - return evalStatements(node.Statements) + return evalProgram(node) case *ast.ExpressionStatement: return Eval(node.Expression) case *ast.PrefixExpression: @@ -25,9 +25,12 @@ func Eval(node ast.Node) object.Object { right := Eval(node.Right) return evalInfixExpression(node.Operator, left, right) case *ast.BlockStatement: - return evalStatements(node.Statements) + return evalBlockStatement(node) case *ast.IfExpression: return evalIfExpression(node) + case *ast.ReturnStatement: + val := Eval(node.ReturnValue) + return &object.ReturnValue{Value: val} case *ast.IntegerLiteral: return &object.Integer{Value: node.Value} @@ -37,10 +40,35 @@ func Eval(node ast.Node) object.Object { return nil } +func evalProgram(program *ast.Program) object.Object { + var result object.Object + for _, statement := range program.Statements { + result = Eval(statement) + if returnValue, ok := result.(*object.ReturnValue); ok { + return returnValue.Value + } + } + return result +} + +func evalBlockStatement(block *ast.BlockStatement) object.Object { + var result object.Object + for _, statement := range block.Statements { + result = Eval(statement) + if result != nil && result.Type() == object.RETURN_VALUE_OBJ { + return result + } + } + return result +} + func evalStatements(stmts []ast.Statement) object.Object { var result object.Object for _, statement := range stmts { result = Eval(statement) + if returnValue, ok := result.(*object.ReturnValue); ok { + return returnValue.Value + } } return result } diff --git a/object/object.go b/object/object.go index 3ab9d30..1c96154 100644 --- a/object/object.go +++ b/object/object.go @@ -10,9 +10,10 @@ type Object interface { } const ( - INTEGER_OBJ = "INTEGER" - BOOLEAN_OBJ = "BOOLEAN" - NULL_OBJ = "NULL" + INTEGER_OBJ = "INTEGER" + BOOLEAN_OBJ = "BOOLEAN" + NULL_OBJ = "NULL" + RETURN_VALUE_OBJ = "RETURN_VALUE" ) type Boolean struct { @@ -33,3 +34,10 @@ type Null struct{} func (n *Null) Type() ObjectType { return NULL_OBJ } func (n *Null) Inspect() string { return "null" } + +type ReturnValue struct { + Value Object +} + +func (rv *ReturnValue) Type() ObjectType { return RETURN_VALUE_OBJ } +func (rv *ReturnValue) Inspect() string { return rv.Value.Inspect() }