From 30376cde6f2e79ad15f85884600561d9c25f7e1d Mon Sep 17 00:00:00 2001 From: Arc676/Alessandro Vinciguerra Date: Fri, 22 Jun 2018 13:41:40 +0800 Subject: [PATCH] Fixed function scope destruction Copy argument tokens to avoid destroying originals Only destroy arguments after evaluating builtins Arguments will be destroyed in child scope with user-defined functions Copy parameter strings Scope destruction ignores function wrappers which are destroyed with AST root --- src/evaluation.c | 19 ++++++++++--------- src/scope.c | 4 +++- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/evaluation.c b/src/evaluation.c index e564465..5394d5f 100644 --- a/src/evaluation.c +++ b/src/evaluation.c @@ -289,13 +289,20 @@ Token* eval(Token* exp, Scope* scope) { // evaluate function arguments before passing to function for (int i = 0; i < argc; i++) { - args[i] = eval(givenArgs[i], scope); + args[i] = copyToken(eval(givenArgs[i], scope)); } for (int i = 0; i < BUILTIN_COUNT; i++) { if (!strcmp(fID, builtinFunctions[i])) { returnValue = builtins[i](argc, args); hasEvaluated = 1; + + // tear down copy of arguments + for (int i = 0; i < argc; i++) { + if (!isLiteralToken(args[i])) { + destroyToken(args[i]); + } + } } } @@ -320,23 +327,17 @@ Token* eval(Token* exp, Scope* scope) { // assign given arguments to parameter names, shadowing // any variables in parent scopes with the same name for (int i = 0; i < argc; i++) { - defineVariable(fScope, params[i], args[i]); + defineVariable(fScope, copyString(params[i]), args[i]); } Token* fBody = ht_find_token(func->tokenData, FUNCTION_BODY); returnValue = eval(fBody, fScope); - // tear down child scope + // tear down child scope and arguments contained within it destroyScope(fScope); hasEvaluated = 1; } } - // tear down copy of arguments - for (int i = 0; i < argc; i++) { - if (!isLiteralToken(args[i])) { - destroyToken(args[i]); - } - } free(args); if (!hasEvaluated) { diff --git a/src/scope.c b/src/scope.c index 6b95fd9..8c76907 100644 --- a/src/scope.c +++ b/src/scope.c @@ -36,7 +36,9 @@ void destroyScope(Scope* scope) { char* identifier = scope->storedIdentifiers[i]; if (identifier) { Token* token = ht_find(scope->variables, identifier); - destroyToken(token); + if (token->type != FUNC_WRAPPER) { + destroyToken(token); + } free(identifier); } }