This commit is contained in:
Bobby Lucero 2025-08-05 20:40:40 -04:00
parent b87b342dff
commit 671f8a6350
3 changed files with 24 additions and 7 deletions

View File

@ -26,6 +26,14 @@ struct ScopedThunkFlag {
~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
class Thunk {
public:

View File

@ -604,8 +604,8 @@ Value Interpreter::visitCallExpr(const std::shared_ptr<CallExpr>& expression) {
if (expression->isTailCall) {
// Create a thunk for tail call optimization
auto thunk = new Thunk([this, function, arguments]() -> Value {
// Set up the environment for the tail call
auto previousEnv = environment;
// Use RAII to manage environment
ScopedEnv _env(environment);
environment = std::make_shared<Environment>(function->closure);
environment->setErrorReporter(errorReporter);
@ -623,12 +623,10 @@ Value Interpreter::visitCallExpr(const std::shared_ptr<CallExpr>& expression) {
for (const auto& stmt : function->body) {
execute(stmt, &context);
if (context.hasReturn) {
environment = previousEnv;
return context.returnValue;
}
}
environment = previousEnv;
return context.returnValue;
});
@ -636,7 +634,7 @@ Value Interpreter::visitCallExpr(const std::shared_ptr<CallExpr>& expression) {
return Value(thunk);
} else {
// Normal function call - create new environment
auto previousEnv = environment;
ScopedEnv _env(environment);
environment = std::make_shared<Environment>(function->closure);
environment->setErrorReporter(errorReporter);
@ -651,12 +649,10 @@ Value Interpreter::visitCallExpr(const std::shared_ptr<CallExpr>& expression) {
for (const auto& stmt : function->body) {
execute(stmt, &context);
if (context.hasReturn) {
environment = previousEnv;
return context.returnValue;
}
}
environment = previousEnv;
return context.returnValue;
}
}

13
tco.bob Normal file
View File

@ -0,0 +1,13 @@
func countdown(n)
{
if(n == 0)
return 0;
print(n);
return countdown(n - 1);
}
countdown(1000000);