From 0d4da92f1e19d786d8ac9a1ff10270d2eca46765 Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Sat, 21 Jan 2012 12:31:56 +1000 Subject: More stuff for parsing blocks and their statement lists. --- LuaSL/src/LuaSL_LSL_tree.h | 4 +++- LuaSL/src/LuaSL_compile.c | 49 +++++++++++++++++++++++++++++++++++++++++- LuaSL/src/LuaSL_lemon_yaccer.y | 7 +++--- 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/LuaSL/src/LuaSL_LSL_tree.h b/LuaSL/src/LuaSL_LSL_tree.h index c22ceae..41435ff 100644 --- a/LuaSL/src/LuaSL_LSL_tree.h +++ b/LuaSL/src/LuaSL_LSL_tree.h @@ -191,6 +191,7 @@ struct _LSL_Identifier // For variables and function parameters. struct _LSL_Statement { + Eina_Clist statement; LSL_Leaf *expressions; // For things like a for statement, might hold three expressions. LSL_Type type; // Expression type. }; @@ -198,7 +199,7 @@ struct _LSL_Statement struct _LSL_Block { LSL_Block *outerBlock; -// Eina_Hash *statements; // Probably should be some sort of eina list. + Eina_Clist statements; Eina_Hash *variables; // Those variables in this scope. LSL_Function *function; // A pointer to the function if this block is a function. }; @@ -334,6 +335,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(LuaSL_compiler *compiler, LSL_Leaf *list, LSL_Leaf *comma, LSL_Leaf *newParam); +LSL_Leaf *collectStatements(LuaSL_compiler *compiler, LSL_Leaf *list, LSL_Leaf *newStatement); 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 29c45f3..b1efddd 100644 --- a/LuaSL/src/LuaSL_compile.c +++ b/LuaSL/src/LuaSL_compile.c @@ -7,6 +7,7 @@ static LSL_Leaf *evaluateNoToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *ri static LSL_Leaf *evaluateOperationToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right); static LSL_Leaf *eveluateParenthesisToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right); static LSL_Leaf *evaluateStatementToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right); +static void outputBlockToken(FILE *file, outputMode mode, LSL_Leaf *content); static void outputFloatToken(FILE *file, outputMode mode, LSL_Leaf *content); static void outputFunctionToken(FILE *file, outputMode mode, LSL_Leaf *content); static void outputIntegerToken(FILE *file, outputMode mode, LSL_Leaf *content); @@ -129,7 +130,7 @@ LSL_Token LSL_Tokens[] = {LSL_STATEMENT, ST_NONE, ";", LSL_NOIGNORE, outputStatementToken, evaluateStatementToken}, {LSL_BLOCK_CLOSE, ST_NONE, "}", LSL_NONE, NULL, NULL}, - {LSL_BLOCK_OPEN, ST_NONE, "{", LSL_NONE, NULL, NULL}, + {LSL_BLOCK_OPEN, ST_NONE, "{", LSL_NONE, outputBlockToken, NULL}, {LSL_PARAMETER, ST_NONE, "parameter", LSL_NONE, outputIdentifierToken, NULL}, {LSL_PARAMETER_LIST, ST_NONE, "plist", LSL_NONE, outputParameterListToken, NULL}, {LSL_FUNCTION, ST_NONE, "function", LSL_NONE, outputFunctionToken, NULL}, @@ -547,6 +548,7 @@ LSL_Leaf *addStatement(LSL_Leaf *lval, LSL_Type type, LSL_Leaf *expr) { stat->type = type; stat->expressions = expr; + eina_clist_element_init(&(stat->statement)); if (lval) lval->value.statementValue = stat; } @@ -554,6 +556,31 @@ LSL_Leaf *addStatement(LSL_Leaf *lval, LSL_Type type, LSL_Leaf *expr) return lval; } +LSL_Leaf *collectStatements(LuaSL_compiler *compiler, LSL_Leaf *list, LSL_Leaf *statement) +{ + if (NULL == list) + { + list = newLeaf(LSL_BLOCK_OPEN, NULL, NULL); + if (list) + { + list->value.blockValue = compiler->currentBlock; // Maybe NULL. + } + } + + if (list) + { + if (statement) + { + if (list->value.blockValue) + { + eina_clist_add_tail(&(list->value.blockValue->statements), &(statement->value.statementValue->statement)); + } + } + } + + return list; +} + LSL_Leaf *addTypecast(LSL_Leaf *lval, LSL_Leaf *type, LSL_Leaf *rval, LSL_Leaf *expr) { addParenthesis(lval, expr, LSL_TYPECAST_OPEN, rval); @@ -604,6 +631,7 @@ void beginBlock(LuaSL_compiler *compiler, LSL_Leaf *block) if (blok) { + eina_clist_init(&(blok->statements)); blok->variables = eina_hash_stringshared_new(burnLeaf); block->value.blockValue = blok; blok->outerBlock = compiler->currentBlock; @@ -933,6 +961,25 @@ static void outputLeaf(FILE *file, outputMode mode, LSL_Leaf *leaf) } } +static void outputBlockToken(FILE *file, outputMode mode, LSL_Leaf *content) +{ + if (content) + { + fprintf(file, "\n{\n"); + if (content->value.blockValue) + { + LSL_Statement *statement = NULL; + + EINA_CLIST_FOR_EACH_ENTRY(statement, &(content->value.blockValue->statements), LSL_Statement, statement) + { + outputLeaf(file, mode, statement->expressions); + fprintf(file, ";\n"); + } + } + fprintf(file, "}\n"); + } +} + static void outputFloatToken(FILE *file, outputMode mode, LSL_Leaf *content) { if (content) diff --git a/LuaSL/src/LuaSL_lemon_yaccer.y b/LuaSL/src/LuaSL_lemon_yaccer.y index 54af56d..881bdaf 100644 --- a/LuaSL/src/LuaSL_lemon_yaccer.y +++ b/LuaSL/src/LuaSL_lemon_yaccer.y @@ -54,13 +54,14 @@ function(A) ::= type(B) LSL_IDENTIFIER(C) LSL_PARENTHESIS_OPEN(D) parameterList( block(A) ::= funcBlock(B). { A = B; } block(A) ::= statement(B). { A = B; } -funcBlock ::= LSL_BLOCK_OPEN statementList LSL_BLOCK_CLOSE. +funcBlock(A) ::= LSL_BLOCK_OPEN statementList(B) LSL_BLOCK_CLOSE. { A = B; } // Various forms of statement. %nonassoc LSL_STATEMENT. -statementList ::= statementList statement. -statementList ::= . +statementList(A) ::= statementList(B) statement(C). { A = collectStatements(compiler, B, C); } +//statementList(A) ::= statement(C). { A = collectStatements(compiler, NULL, C); } +statementList(A) ::= . { A = collectStatements(compiler, NULL, NULL); } %nonassoc LSL_DO LSL_FOR LSL_ELSE_IF LSL_IF LSL_JUMP LSL_RETURN LSL_STATE_CHANGE LSL_WHILE. %nonassoc LSL_ELSE. -- cgit v1.1