diff --git a/include/Value/function.hpp b/include/Value/function.hpp index 6fcac8d..48741f3 100644 --- a/include/Value/function.hpp +++ b/include/Value/function.hpp @@ -2,6 +2,7 @@ #include #include +#include #include @@ -21,18 +22,28 @@ namespace Fig std::function &)> builtin; int builtinParamCount = -1; - FunctionStruct(Ast::FunctionParameters _paras, TypeInfo _retType, Ast::BlockStatement _body) : + std::shared_ptr closureContext; + + FunctionStruct(Ast::FunctionParameters _paras, TypeInfo _retType, Ast::BlockStatement _body, ContextPtr _closureContext) : id(nextId()), // εˆ†ι…ε”―δΈ€ ID paras(std::move(_paras)), retType(std::move(_retType)), - body(std::move(_body)) + body(std::move(_body)), + closureContext(std::move(_closureContext)) { } FunctionStruct(std::function &)> fn, int argc); FunctionStruct(const FunctionStruct &other) : - id(other.id), paras(other.paras), retType(other.retType), body(other.body), isBuiltin(other.isBuiltin), builtin(other.builtin), builtinParamCount(other.builtinParamCount) {} + id(other.id), + paras(other.paras), + retType(other.retType), + body(other.body), + isBuiltin(other.isBuiltin), + builtin(other.builtin), + builtinParamCount(other.builtinParamCount), + closureContext(other.closureContext) {} FunctionStruct &operator=(const FunctionStruct &other) = default; FunctionStruct(FunctionStruct &&) noexcept = default; @@ -63,11 +74,11 @@ namespace Fig { data = std::make_unique(x); } - Function(Ast::FunctionParameters paras, TypeInfo ret, Ast::BlockStatement body) : + Function(Ast::FunctionParameters paras, TypeInfo ret, Ast::BlockStatement body, ContextPtr closureContext) : __ValueWrapper(ValueType::Function) { data = std::make_unique( - std::move(paras), std::move(ret), std::move(body)); + std::move(paras), std::move(ret), std::move(body), std::move(closureContext)); } Function(std::function &)> fn, int argc); diff --git a/src/evaluator.cpp b/src/evaluator.cpp index 14db024..8cf2337 100644 --- a/src/evaluator.cpp +++ b/src/evaluator.cpp @@ -132,7 +132,8 @@ namespace Fig evaluatedArgs.argv.push_back(defaultVal); } // create new context for function call - auto newContext = std::make_shared(FString(std::format("", fnName.toBasicString())), currentContext); + auto newContext = std::make_shared(FString(std::format("", fnName.toBasicString())), + fnStruct.closureContext); auto previousContext = currentContext; currentContext = newContext; // define parameters in new context @@ -238,8 +239,8 @@ namespace Fig return Function( fn->paras, ValueType::Any, - body - ); + body, + currentContext); } else { @@ -247,8 +248,8 @@ namespace Fig return Function( fn->paras, ValueType::Any, - body - ); + body, + currentContext); } } case AstType::ListExpr: { @@ -341,7 +342,8 @@ namespace Fig Value(Function( fnDef->paras, TypeInfo(fnDef->retType), - fnDef->body))); + fnDef->body, + currentContext))); return StatementResult::normal(); }; case AstType::StructSt: { diff --git a/test.fig b/test.fig index 3634dfb..95ba00b 100644 --- a/test.fig +++ b/test.fig @@ -1,8 +1,9 @@ -func build_adder(x) -> Function -{ - return func(a) => a + x; +var x = 1; + +func f() { + x = x + 1; } -var add2 = build_adder(2); -var println = __fstdout_println; -println(add2(1)); \ No newline at end of file +f(); +var print = __fstdout_println; +print(x); \ No newline at end of file