diff --git a/lib/keisan/context.rb b/lib/keisan/context.rb index cf0151b..dac9828 100644 --- a/lib/keisan/context.rb +++ b/lib/keisan/context.rb @@ -73,7 +73,7 @@ def variable_is_modifiable?(name) def register_variable!(name, value, local: false) if !@variable_registry.shadowed.member?(name) && (transient? || !local && @parent&.variable_is_modifiable?(name)) - @parent.register_variable!(name, value) + @parent.register_variable!(name, value, local: local) else @variable_registry.register!(name, value) end @@ -93,7 +93,7 @@ def function_is_modifiable?(name) def register_function!(name, function, local: false) if transient? || !local && @parent&.function_is_modifiable?(name) - @parent.register_function!(name, function) + @parent.register_function!(name, function, local: local) else @function_registry.register!(name.to_s, function) end diff --git a/spec/keisan/let_spec.rb b/spec/keisan/let_spec.rb index 1c54f1b..21ced66 100644 --- a/spec/keisan/let_spec.rb +++ b/spec/keisan/let_spec.rb @@ -13,6 +13,8 @@ expect(calculator.evaluate("{let x = 11; x*2}")).to eq 22 expect(calculator.evaluate("x")).to eq 7 + expect(calculator.evaluate("{x = 15; x}")).to eq 15 + expect(calculator.evaluate("x")).to eq 15 end it "raises error for single argument when not assignment" do @@ -29,4 +31,27 @@ expect(calculator.evaluate("x").value).to eq 3 expect(calculator.evaluate("y").value).to eq 6 end + + it "will create local definitions in children contexts" do + calculator2 = Keisan::Calculator.new(context: calculator.context.spawn_child) + + calculator.evaluate("x = 10") + calculator.evaluate("f(x) = x**2") + + calculator2.evaluate("x = 20") + calculator2.evaluate("f(x) = x**3") + + expect(calculator.evaluate("x")).to eq 20 + expect(calculator.evaluate("f(2)")).to eq 8 + expect(calculator2.evaluate("x")).to eq 20 + expect(calculator2.evaluate("f(2)")).to eq 8 + + calculator2.evaluate("let x = 30") + calculator2.evaluate("let f(x) = x**4") + + expect(calculator.evaluate("x")).to eq 20 + expect(calculator.evaluate("f(2)")).to eq 8 + expect(calculator2.evaluate("x")).to eq 30 + expect(calculator2.evaluate("f(2)")).to eq 16 + end end