diff --git a/src/memory.cpp b/src/memory.cpp index 9b37351..1f3f620 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -79,6 +79,14 @@ void Memory::update(string identifier, EvalResult value) { scope.vars[identifier].initialized = true; return; } + if (scope.type == ScopeType::Function) { + Closure closure = std::get<1>(std::get(scope.fn->value)); + if (closure.contains(identifier)) { + MemoryVar& var = closure.at(identifier); + var.value = value; + var.initialized = true; + } + } } throw exception(); diff --git a/test/functions.cpp b/test/functions.cpp index 567af3f..4c99acd 100644 --- a/test/functions.cpp +++ b/test/functions.cpp @@ -110,5 +110,47 @@ int main() { true ); + _TEST_ASSERT( + _TEST_NO_EXCEPTION(get(execute(R"( + int x = 1; + int a() { + return x; + } + int b() { + int x = 2; + return a(); + } + b(); + )")) == 1), + "Closure capture", + true + ); + + _TEST_ASSERT( + _TEST_NO_EXCEPTION(get(execute(R"( + int x = 1; + int a() { + return x; + } + x = 2; + a(); + )")) == 2), + "Closure mutation externe", + true + ); + + _TEST_ASSERT( + _TEST_NO_EXCEPTION(get(execute(R"( + int x = 1; + void a() { + x = 2; + } + a(); + x; + )")) == 2), + "Closure mutation interne", + true + ); + return 0; } \ No newline at end of file