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; } ~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:

View File

@ -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;
} }
} }

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);