reassign values
This commit is contained in:
@@ -45,6 +45,26 @@ func Eval(node ast.Node, env *object.Environment) object.Object {
|
||||
}
|
||||
return &object.ReturnValue{Value: val}
|
||||
|
||||
case *ast.AssignmentStatement:
|
||||
ident := evalIdentifier(node.Name, env)
|
||||
if isError(ident) {
|
||||
return ident
|
||||
}
|
||||
|
||||
val := Eval(node.Value, env)
|
||||
if isError(val) {
|
||||
return val
|
||||
}
|
||||
|
||||
obj, ok := ident.(object.Mutable)
|
||||
if !ok {
|
||||
return newError("cannot assign to %s", ident.Type())
|
||||
}
|
||||
|
||||
obj.Set(val)
|
||||
|
||||
return val
|
||||
|
||||
case *ast.LetStatement:
|
||||
val := Eval(node.Value, env)
|
||||
if isError(val) {
|
||||
|
||||
@@ -238,6 +238,26 @@ func TestErrorHandling(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAssignmentStatements(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
expected int64
|
||||
}{
|
||||
{"let a = 0; a = 5;", 5},
|
||||
{"let a = 0; a = 5; a;", 5},
|
||||
{"let a = 0; a = 5 * 5;", 25},
|
||||
{"let a = 0; a = 5 * 5; a;", 25},
|
||||
{"let a = 0; a = 5; let b = 0; b = a;", 5},
|
||||
{"let a = 0; a = 5; let b = 0; b = a; b;", 5},
|
||||
{"let a = 0; a = 5; let b = 0; b = a; let c = 0; c = a + b + 5;", 15},
|
||||
{"let a = 0; a = 5; let b = 0; b = a; let c = 0; c = a + b + 5; c;", 15},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
testIntegerObject(t, testEval(tt.input), tt.expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLetStatements(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
@@ -560,10 +580,8 @@ func TestWhileExpressions(t *testing.T) {
|
||||
{"while (false) { }", nil},
|
||||
{"let n = 0; while (n < 10) { let n = n + 1 }; n", 10},
|
||||
{"let n = 10; while (n > 0) { let n = n - 1 }; n", 0},
|
||||
// FIXME: let is an expression statement and bind new values
|
||||
// there is currently no assignment expressions :/
|
||||
{"let n = 0; while (n < 10) { let n = n + 1 }", nil},
|
||||
{"let n = 10; while (n > 0) { let n = n - 1 }", nil},
|
||||
{"let n = 0; while (n < 10) { n = n + 1 }", 10},
|
||||
{"let n = 10; while (n > 0) { n = n - 1 }", 0},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
||||
Reference in New Issue
Block a user