From 36f91bf237a2d48e27171c6661eff9cc255214d0 Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Tue, 17 Jan 2012 19:52:21 +1000 Subject: Add function parameters to the search list. --- LuaSL/src/LuaSL_LSL_tree.h | 33 ++++++++++++++++++--------------- LuaSL/src/LuaSL_compile.c | 40 +++++++++++++++++++++++++++++++--------- LuaSL/src/LuaSL_lemon_yaccer.y | 18 ++++++++++-------- 3 files changed, 59 insertions(+), 32 deletions(-) diff --git a/LuaSL/src/LuaSL_LSL_tree.h b/LuaSL/src/LuaSL_LSL_tree.h index 2c2bfa6..c8d1cc6 100644 --- a/LuaSL/src/LuaSL_LSL_tree.h +++ b/LuaSL/src/LuaSL_LSL_tree.h @@ -225,6 +225,7 @@ struct _LSL_Block LSL_Block *outerBlock; // Eina_Hash *statements; // Probably should be some sort of eina list. Eina_Hash *variables; // Those variables in this scope. + LSL_Function *function; }; struct _LSL_Function @@ -232,6 +233,7 @@ struct _LSL_Function const char *name; LSL_Leaf *type; LSL_Leaf *params; + Eina_Hash *variables; LSL_Leaf *block; }; @@ -255,18 +257,18 @@ struct _LSL_Script typedef struct { - gameGlobals *game; - void *scanner; // This should be of type yyscan_t, which is typedef to void * anyway, but that does not get defined until LuaSL_lexer.h, which depends on this struct being defined first. - int argc; - char **argv; - char fileName[PATH_MAX]; - FILE *file; - LSL_Leaf *ast; - LSL_Script script; - Eina_Strbuf *ignorableText; - LSL_Leaf *lval; - int column, line; - LSL_Block *currentBlock; + gameGlobals *game; + void *scanner; // This should be of type yyscan_t, which is typedef to void * anyway, but that does not get defined until LuaSL_lexer.h, which depends on this struct being defined first. + int argc; + char **argv; + char fileName[PATH_MAX]; + FILE *file; + LSL_Leaf *ast; + LSL_Script script; + Eina_Strbuf *ignorableText; + LSL_Leaf *lval; + int column, line; + LSL_Block *currentBlock; } LuaSL_compiler; @@ -276,9 +278,10 @@ typedef struct void burnLeaf(void *data); -LSL_Leaf *addFunction(LuaSL_compiler *compiler, LSL_Leaf *type, LSL_Leaf *identifier, LSL_Leaf *open, LSL_Leaf *params, LSL_Leaf *close, LSL_Leaf *block); +LSL_Leaf *addFunction(LuaSL_compiler *compiler, LSL_Leaf *type, LSL_Leaf *identifier, LSL_Leaf *open, LSL_Leaf *params, LSL_Leaf *close); +LSL_Leaf *addFunctionBody(LuaSL_compiler *compiler, LSL_Leaf *function, LSL_Leaf *block); LSL_Leaf *addOperation(LuaSL_compiler *compiler, LSL_Leaf *left, LSL_Leaf *lval, LSL_Leaf *right); -LSL_Leaf *addParameter(LSL_Leaf *type, LSL_Leaf *newParam); +LSL_Leaf *addParameter(LuaSL_compiler *compiler, LSL_Leaf *type, LSL_Leaf *newParam); LSL_Leaf *addParenthesis(LSL_Leaf *lval, LSL_Leaf *expr, LSL_Type type, LSL_Leaf *rval); LSL_Leaf *addState(LuaSL_compiler *compiler, LSL_Leaf *identifier, LSL_Leaf *block); LSL_Leaf *addStatement(LSL_Leaf *lval, LSL_Type type, LSL_Leaf *expr); @@ -287,7 +290,7 @@ LSL_Leaf *addVariable(LuaSL_compiler *compiler, LSL_Leaf *type, LSL_Leaf *identi void beginBlock(LuaSL_compiler *compiler, LSL_Leaf *block); LSL_Leaf *checkVariable(LuaSL_compiler *compiler, LSL_Leaf *identifier); -LSL_Leaf *collectParameters(LSL_Leaf *list, LSL_Leaf *comma, LSL_Leaf *newParam); +LSL_Leaf *collectParameters(LuaSL_compiler *compiler, LSL_Leaf *list, LSL_Leaf *comma, LSL_Leaf *newParam); void endBlock(LuaSL_compiler *compiler, LSL_Leaf *block); void *ParseAlloc(void *(*mallocProc)(size_t)); diff --git a/LuaSL/src/LuaSL_compile.c b/LuaSL/src/LuaSL_compile.c index c28a6fc..4e089c7 100644 --- a/LuaSL/src/LuaSL_compile.c +++ b/LuaSL/src/LuaSL_compile.c @@ -219,10 +219,13 @@ static LSL_Leaf *findVariable(LuaSL_compiler *compiler, const char *name) while ((block) && (NULL == var)) { - if (block->variables) + if (block->function) + var = eina_hash_find(block->function->variables, name); + if ((NULL == var) && block->variables) var = eina_hash_find(block->variables, name); block = block->outerBlock; } + if (NULL == var) var = eina_hash_find(compiler->script.variables, name); } @@ -351,7 +354,7 @@ LSL_Leaf *addOperation(LuaSL_compiler *compiler, LSL_Leaf *left, LSL_Leaf *lval, return lval; } -LSL_Leaf *addParameter(LSL_Leaf *type, LSL_Leaf *identifier) +LSL_Leaf *addParameter(LuaSL_compiler *compiler, LSL_Leaf *type, LSL_Leaf *identifier) { LSL_Identifier *result = calloc(1, sizeof(LSL_Identifier)); @@ -370,7 +373,7 @@ LSL_Leaf *addParameter(LSL_Leaf *type, LSL_Leaf *identifier) return identifier; } -LSL_Leaf *collectParameters(LSL_Leaf *list, LSL_Leaf *comma, LSL_Leaf *newParam) +LSL_Leaf *collectParameters(LuaSL_compiler *compiler, LSL_Leaf *list, LSL_Leaf *comma, LSL_Leaf *newParam) { LSL_Leaf *newList = newLeaf(LSL_PARAMETER_LIST, NULL, NULL); @@ -379,15 +382,13 @@ LSL_Leaf *collectParameters(LSL_Leaf *list, LSL_Leaf *comma, LSL_Leaf *newParam) newList->left = list; newList->value.listValue = newParam; if ((list) && (list->value.listValue)) - { list->value.listValue->right = comma; - } } return newList; } -LSL_Leaf *addFunction(LuaSL_compiler *compiler, LSL_Leaf *type, LSL_Leaf *identifier, LSL_Leaf *open, LSL_Leaf *params, LSL_Leaf *close, LSL_Leaf *block) +LSL_Leaf *addFunction(LuaSL_compiler *compiler, LSL_Leaf *type, LSL_Leaf *identifier, LSL_Leaf *open, LSL_Leaf *params, LSL_Leaf *close) { LSL_Function *func = calloc(1, sizeof(LSL_Function)); @@ -398,19 +399,40 @@ LSL_Leaf *addFunction(LuaSL_compiler *compiler, LSL_Leaf *type, LSL_Leaf *identi func->name = identifier->value.stringValue; identifier->token = tokens[LSL_FUNCTION - lowestToken]; identifier->value.functionValue = func; - identifier->value.functionValue->block = block; func->type = type; if (type) identifier->basicType = type->basicType; else identifier->basicType = OT_nothing; - func->params = addParenthesis(open, params, LSL_PARAMETER_LIST, close); eina_hash_add(compiler->script.functions, func->name, identifier); + func->variables = eina_hash_stringshared_new(burnLeaf); + func->params = addParenthesis(open, params, LSL_PARAMETER_LIST, close); + while (params) + { + if (params->value.listValue) + { + LSL_Identifier *identifier = params->value.listValue->value.identifierValue; + + if (identifier) + eina_hash_add(func->variables, identifier->name, identifier); + } + params = params->left; + } + if (compiler->currentBlock) + compiler->currentBlock->function = func; } } return identifier; } +LSL_Leaf *addFunctionBody(LuaSL_compiler *compiler, LSL_Leaf *function, LSL_Leaf *block) +{ + if (function) + function->value.functionValue->block = block; + + return function; +} + LSL_Leaf *addParenthesis(LSL_Leaf *lval, LSL_Leaf *expr, LSL_Type type, LSL_Leaf *rval) { LSL_Parenthesis *parens = malloc(sizeof(LSL_Parenthesis)); @@ -514,7 +536,7 @@ LSL_Leaf *addVariable(LuaSL_compiler *compiler, LSL_Leaf *type, LSL_Leaf *identi void beginBlock(LuaSL_compiler *compiler, LSL_Leaf *block) { - LSL_Block *blok = malloc(sizeof(LSL_Block)); + LSL_Block *blok = calloc(1, sizeof(LSL_Block)); if (blok) { diff --git a/LuaSL/src/LuaSL_lemon_yaccer.y b/LuaSL/src/LuaSL_lemon_yaccer.y index d5a6751..a0defc5 100644 --- a/LuaSL/src/LuaSL_lemon_yaccer.y +++ b/LuaSL/src/LuaSL_lemon_yaccer.y @@ -24,7 +24,7 @@ program ::= script LSL_SCRIPT(A). { if (NULL != A) A->left = compiler->ast; %nonassoc LSL_SCRIPT. script ::= script state(A). { if (NULL != A) A->left = compiler->ast; compiler->ast = A; } -script ::= script function(A). { if (NULL != A) A->left = compiler->ast; compiler->ast = A; } +script ::= script functionBody(A). { if (NULL != A) A->left = compiler->ast; compiler->ast = A; } script ::= script statement(A). { if (NULL != A) A->left = compiler->ast; compiler->ast = A; } script ::= . @@ -37,16 +37,18 @@ state(S) ::= LSL_IDENTIFIER(I) stateBlock(B). { S = addState(compiler, I, B) // Function definitions. %nonassoc LSL_PARAMETER LSL_PARAMETER_LIST LSL_FUNCTION. -functionList ::= functionList function. +functionList ::= functionList functionBody. functionList ::= . -parameterList(A) ::= parameterList(B) LSL_COMMA(C) parameter(D). { A = collectParameters(B, C, D); } -parameterList(A) ::= parameter(D). { A = collectParameters(NULL, NULL, D); } -parameterList(A) ::= . { A = collectParameters(NULL, NULL, NULL); } -parameter(A) ::= type(B) LSL_IDENTIFIER(C). { A = addParameter(B, C); } +functionBody(A) ::= function(B) funcBlock(C). { A = addFunctionBody(compiler, B, C); } + +parameterList(A) ::= parameterList(B) LSL_COMMA(C) parameter(D). { A = collectParameters(compiler, B, C, D); } +parameterList(A) ::= parameter(D). { A = collectParameters(compiler, NULL, NULL, D); } +parameterList(A) ::= . { A = collectParameters(compiler, NULL, NULL, NULL); } +parameter(A) ::= type(B) LSL_IDENTIFIER(C). { A = addParameter(compiler, B, C); } // Causes a conflict when it's an empty parameterList with calling the same type of function. -function(A) ::= LSL_IDENTIFIER(C) LSL_PARENTHESIS_OPEN(D) parameterList(E) LSL_PARENTHESIS_CLOSE(F) funcBlock(G). { A = addFunction(compiler, NULL, C, D, E, F, G); } -function(A) ::= type(B) LSL_IDENTIFIER(C) LSL_PARENTHESIS_OPEN(D) parameterList(E) LSL_PARENTHESIS_CLOSE(F) funcBlock(G). { A = addFunction(compiler, B, C, D, E, F, G); } +function(A) ::= LSL_IDENTIFIER(C) LSL_PARENTHESIS_OPEN(D) parameterList(E) LSL_PARENTHESIS_CLOSE(F). { A = addFunction(compiler, NULL, C, D, E, F); } +function(A) ::= type(B) LSL_IDENTIFIER(C) LSL_PARENTHESIS_OPEN(D) parameterList(E) LSL_PARENTHESIS_CLOSE(F). { A = addFunction(compiler, B, C, D, E, F); } // Blocks. -- cgit v1.1