@@ -16,14 +16,15 @@ import (
1616var moduleCache = map [string ]* object.Module {}
1717
1818type Evaluator struct {
19- loopDepth int
19+ loopDepth int
20+ Resolutions map [ast.Node ]int
2021}
2122
2223func (e * Evaluator ) Eval (node ast.Node , env * object.Environment ) object.Object {
2324 switch node := node .(type ) {
2425 //statement
2526 case * ast.Program :
26- return e .evalProgram (node , * env )
27+ return e .evalProgram (node , env )
2728 case * ast.ExpressionStatement :
2829 return e .Eval (node .Expression , env )
2930 case * ast.ReturnStatement :
@@ -138,11 +139,11 @@ func (e *Evaluator) Eval(node ast.Node, env *object.Environment) object.Object {
138139 }
139140 return evalInfixExpression (node , left , right )
140141 case * ast.BlockStatement :
141- return e .evalBlockStatements (node , * env )
142+ return e .evalBlockStatements (node , env )
142143 case * ast.IfExpression :
143- return e .evalIfExpression (node , * env )
144+ return e .evalIfExpression (node , env )
144145 case * ast.Identifier :
145- return evalIdentifier (node , env )
146+ return e . evalIdentifier (node , env )
146147 case * ast.FunctionLiteral :
147148 params := node .Parameters
148149 body := node .Body
@@ -259,7 +260,7 @@ func (e *Evaluator) evalAssignment(node *ast.InfixExpression, env *object.Enviro
259260 if node .Operator == "=" {
260261 finalVal = val
261262 } else {
262- currentVal := evalIdentifier (left , env )
263+ currentVal := e . evalIdentifier (left , env )
263264 if isError (currentVal ) {
264265 return currentVal
265266 }
@@ -270,8 +271,11 @@ func (e *Evaluator) evalAssignment(node *ast.InfixExpression, env *object.Enviro
270271 return finalVal
271272 }
272273
273- if isConst , ok := env .Consts [left .Value ]; ok && isConst {
274- return object .NewError (node .Line (), node .Column (), "cannot reassign to const: %s" , left .Value )
274+ if dist , ok := e .Resolutions [left ]; ok {
275+ if ! env .UpdateAt (dist , left .Value , finalVal ) {
276+ return object .NewError (node .Line (), node .Column (), "cannot reassign to const: %s" , left .Value )
277+ }
278+ return finalVal
275279 }
276280
277281 _ , updated := env .Update (left .Value , finalVal )
@@ -626,17 +630,23 @@ func (e *Evaluator) evalExpression(exps []ast.Expression, env *object.Environmen
626630 return result
627631}
628632
629- func evalIdentifier (node * ast.Identifier , env * object.Environment ) object.Object {
633+ func (e * Evaluator ) evalIdentifier (node * ast.Identifier , env * object.Environment ) object.Object {
634+ if dist , ok := e .Resolutions [node ]; ok {
635+ if val , ok := env .GetAt (dist , node .Value ); ok {
636+ return val
637+ }
638+ }
639+
630640 if val , ok := env .Get (node .Value ); ok {
631641 return val
632642 }
633643 return object .NewError (node .Line (), node .Column (), "identifier not found: %s" , node .Value )
634644}
635645
636- func (e * Evaluator ) evalProgram (program * ast.Program , env object.Environment ) object.Object {
646+ func (e * Evaluator ) evalProgram (program * ast.Program , env * object.Environment ) object.Object {
637647 var result object.Object
638648 for _ , statement := range program .Statements {
639- result = e .Eval (statement , & env )
649+ result = e .Eval (statement , env )
640650
641651 switch result := result .(type ) {
642652 case * object.ReturnValue :
@@ -649,15 +659,16 @@ func (e *Evaluator) evalProgram(program *ast.Program, env object.Environment) ob
649659 return result
650660}
651661
652- func (e * Evaluator ) evalBlockStatements (block * ast.BlockStatement , env object.Environment ) object.Object {
662+ func (e * Evaluator ) evalBlockStatements (block * ast.BlockStatement , env * object.Environment ) object.Object {
653663 var result object.Object
664+ blockEnv := object .NewEnclosedEnvironment (env )
654665
655666 for _ , statement := range block .Statements {
656- result = e .Eval (statement , & env )
667+ result = e .Eval (statement , blockEnv )
657668
658669 if result != nil {
659670 rt := result .Type ()
660- if rt == object .RETURN_VALUE_OBJ || rt == object .ERROR_OBJ {
671+ if rt == object .RETURN_VALUE_OBJ || rt == object .ERROR_OBJ || rt == object . BREAK_OBJ || rt == object . CONTINUE_OBJ {
661672 return result
662673 }
663674 }
@@ -666,29 +677,29 @@ func (e *Evaluator) evalBlockStatements(block *ast.BlockStatement, env object.En
666677 return result
667678}
668679
669- func (e * Evaluator ) evalIfExpression (node * ast.IfExpression , env object.Environment ) object.Object {
670- condition := e .Eval (node .Condition , & env )
680+ func (e * Evaluator ) evalIfExpression (node * ast.IfExpression , env * object.Environment ) object.Object {
681+ condition := e .Eval (node .Condition , env )
671682
672683 if isError (condition ) {
673684 return condition
674685 }
675686
676687 if isTruthy (condition ) {
677- return e .Eval (node .Consequence , & env )
688+ return e .Eval (node .Consequence , env )
678689 }
679690
680691 for _ , v := range node .IfElse {
681- condition := e .Eval (v .Condition , & env )
692+ condition := e .Eval (v .Condition , env )
682693 if isError (condition ) {
683694 return condition
684695 }
685696 if isTruthy (condition ) {
686- return e .Eval (v .Consequence , & env )
697+ return e .Eval (v .Consequence , env )
687698 }
688699 }
689700
690701 if node .Alternative != nil {
691- return e .Eval (node .Alternative , & env )
702+ return e .Eval (node .Alternative , env )
692703 }
693704
694705 return object .NULL
0 commit comments