RAII env
This commit is contained in:
parent
b87b342dff
commit
671f8a6350
@ -26,6 +26,14 @@ struct ScopedThunkFlag {
|
|||||||
~ScopedThunkFlag() { flag = prev; }
|
~ScopedThunkFlag() { flag = prev; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// RAII helper for environment management
|
||||||
|
struct ScopedEnv {
|
||||||
|
std::shared_ptr<Environment>& target;
|
||||||
|
std::shared_ptr<Environment> prev;
|
||||||
|
ScopedEnv(std::shared_ptr<Environment>& e) : target(e), prev(e) {}
|
||||||
|
~ScopedEnv() { target = prev; }
|
||||||
|
};
|
||||||
|
|
||||||
// Thunk class for trampoline-based tail call optimization
|
// Thunk class for trampoline-based tail call optimization
|
||||||
class Thunk {
|
class Thunk {
|
||||||
public:
|
public:
|
||||||
|
|||||||
@ -604,8 +604,8 @@ Value Interpreter::visitCallExpr(const std::shared_ptr<CallExpr>& expression) {
|
|||||||
if (expression->isTailCall) {
|
if (expression->isTailCall) {
|
||||||
// Create a thunk for tail call optimization
|
// Create a thunk for tail call optimization
|
||||||
auto thunk = new Thunk([this, function, arguments]() -> Value {
|
auto thunk = new Thunk([this, function, arguments]() -> Value {
|
||||||
// Set up the environment for the tail call
|
// Use RAII to manage environment
|
||||||
auto previousEnv = environment;
|
ScopedEnv _env(environment);
|
||||||
environment = std::make_shared<Environment>(function->closure);
|
environment = std::make_shared<Environment>(function->closure);
|
||||||
environment->setErrorReporter(errorReporter);
|
environment->setErrorReporter(errorReporter);
|
||||||
|
|
||||||
@ -623,12 +623,10 @@ Value Interpreter::visitCallExpr(const std::shared_ptr<CallExpr>& expression) {
|
|||||||
for (const auto& stmt : function->body) {
|
for (const auto& stmt : function->body) {
|
||||||
execute(stmt, &context);
|
execute(stmt, &context);
|
||||||
if (context.hasReturn) {
|
if (context.hasReturn) {
|
||||||
environment = previousEnv;
|
|
||||||
return context.returnValue;
|
return context.returnValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
environment = previousEnv;
|
|
||||||
return context.returnValue;
|
return context.returnValue;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -636,7 +634,7 @@ Value Interpreter::visitCallExpr(const std::shared_ptr<CallExpr>& expression) {
|
|||||||
return Value(thunk);
|
return Value(thunk);
|
||||||
} else {
|
} else {
|
||||||
// Normal function call - create new environment
|
// Normal function call - create new environment
|
||||||
auto previousEnv = environment;
|
ScopedEnv _env(environment);
|
||||||
environment = std::make_shared<Environment>(function->closure);
|
environment = std::make_shared<Environment>(function->closure);
|
||||||
environment->setErrorReporter(errorReporter);
|
environment->setErrorReporter(errorReporter);
|
||||||
|
|
||||||
@ -651,12 +649,10 @@ Value Interpreter::visitCallExpr(const std::shared_ptr<CallExpr>& expression) {
|
|||||||
for (const auto& stmt : function->body) {
|
for (const auto& stmt : function->body) {
|
||||||
execute(stmt, &context);
|
execute(stmt, &context);
|
||||||
if (context.hasReturn) {
|
if (context.hasReturn) {
|
||||||
environment = previousEnv;
|
|
||||||
return context.returnValue;
|
return context.returnValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
environment = previousEnv;
|
|
||||||
return context.returnValue;
|
return context.returnValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user