reassign values
Some checks failed
Build / build (push) Failing after 1m46s
Test / build (push) Has been cancelled

This commit is contained in:
Chuck Smith
2024-03-15 15:24:48 -04:00
parent c818591f79
commit 2988719c9c
13 changed files with 327 additions and 17 deletions

View File

@@ -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) {

View File

@@ -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 {