From ab9fb1f8fb1a9cb5ad8d68ab690ea139b6779246 Mon Sep 17 00:00:00 2001 From: Dibyendu Majumdar Date: Sun, 8 Mar 2020 16:14:23 +0000 Subject: [PATCH] issue #98 fix scoping of local vars --- src/ravi_ast_parse.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/src/ravi_ast_parse.c b/src/ravi_ast_parse.c index 2e3661a..bdd6c4f 100644 --- a/src/ravi_ast_parse.c +++ b/src/ravi_ast_parse.c @@ -24,6 +24,7 @@ static void end_scope(struct parser_state *parser); static struct ast_node *new_literal_expression(struct parser_state *parser, ravitype_t type); static struct ast_node *generate_label(struct parser_state *parser, TString *label); static struct ast_container *new_ast_container(lua_State *L); +static void add_local_symbol_to_current_scope(struct parser_state *parser, struct lua_symbol *sym); static void add_symbol(struct ast_container *container, struct lua_symbol_list **list, struct lua_symbol *sym) { ptrlist_add((struct ptr_list **)list, sym, &container->ptrlist_allocator); @@ -118,10 +119,6 @@ static struct lua_symbol *new_local_symbol(struct parser_state *parser, TString symbol->symbol_type = SYM_LOCAL; symbol->var.block = scope; symbol->var.var_name = name; - add_symbol(parser->container, &scope->symbol_list, symbol); // Add to the end of the symbol list - add_symbol(parser->container, &scope->function->function_expr.locals, symbol); - // Note that Lua allows multiple local declarations of the same name - // so a new instance just gets added to the end return symbol; } @@ -540,6 +537,7 @@ static bool parse_parameter_list(struct parser_state *parser, struct lua_symbol_ /* RAVI change - add type */ struct lua_symbol *symbol = declare_local_variable(parser); add_symbol(parser->container, list, symbol); + add_local_symbol_to_current_scope(parser, symbol); nparams++; break; } @@ -933,6 +931,13 @@ static struct ast_node *parse_expression(struct parser_state *parser) { ** ======================================================================= */ +static void add_local_symbol_to_current_scope(struct parser_state *parser, struct lua_symbol *sym) { + // Note that Lua allows multiple local declarations of the same name + // so a new instance just gets added to the end + add_symbol(parser->container, &parser->current_scope->symbol_list, sym); + add_symbol(parser->container, &parser->current_scope->function->function_expr.locals, sym); +} + static struct block_scope *parse_block(struct parser_state *parser, struct ast_node_list **statement_list) { /* block -> statlist */ struct block_scope *scope = new_scope(parser); @@ -1038,7 +1043,9 @@ static void parse_forbody(struct parser_state *parser, struct ast_node *stmt, in static void parse_fornum_statement(struct parser_state *parser, struct ast_node *stmt, TString *varname, int line) { LexState *ls = parser->ls; /* fornum -> NAME = exp1,exp1[,exp1] forbody */ - add_symbol(parser->container, &stmt->for_stmt.symbols, new_local_symbol(parser, varname, RAVI_TANY, NULL)); + struct lua_symbol *local = new_local_symbol(parser, varname, RAVI_TANY, NULL); + add_symbol(parser->container, &stmt->for_stmt.symbols, local); + add_local_symbol_to_current_scope(parser, local); checknext(ls, '='); /* get the type of each expression */ add_ast_node(parser->container, &stmt->for_stmt.expr_list, parse_expression(parser)); /* initial value */ @@ -1056,10 +1063,13 @@ static void parse_for_list(struct parser_state *parser, struct ast_node *stmt, T /* forlist -> NAME {,NAME} IN explist forbody */ int nvars = 4; /* gen, state, control, plus at least one declared var */ /* create declared variables */ - add_symbol(parser->container, &stmt->for_stmt.symbols, new_local_symbol(parser, indexname, RAVI_TANY, NULL)); + struct lua_symbol *local = new_local_symbol(parser, indexname, RAVI_TANY, NULL); + add_symbol(parser->container, &stmt->for_stmt.symbols, local); + add_local_symbol_to_current_scope(parser, local); while (testnext(ls, ',')) { - add_symbol(parser->container, &stmt->for_stmt.symbols, - new_local_symbol(parser, check_name_and_next(ls), RAVI_TANY, NULL)); + local = new_local_symbol(parser, check_name_and_next(ls), RAVI_TANY, NULL); + add_symbol(parser->container, &stmt->for_stmt.symbols, local); + add_local_symbol_to_current_scope(parser, local); nvars++; } checknext(ls, TK_IN); @@ -1156,6 +1166,8 @@ static struct ast_node *parse_local_function_statement(struct parser_state *pars LexState *ls = parser->ls; struct lua_symbol *symbol = new_local_symbol(parser, check_name_and_next(ls), RAVI_TFUNCTION, NULL); /* new local variable */ + /* local function f ... is parsed as local f; f = function ... */ + add_local_symbol_to_current_scope(parser, symbol); struct ast_node *function_ast = new_function(parser); parse_function_body(parser, function_ast, 0, ls->linenumber); /* function created in next register */ end_function(parser); @@ -1190,6 +1202,10 @@ static struct ast_node *parse_local_statement(struct parser_state *parser) { /* nexps = 0; */ ; } + /* local symbols are only added to scope at the end of the local statement */ + struct lua_symbol *sym = NULL; + FOR_EACH_PTR(node->local_stmt.var_list, sym) { add_local_symbol_to_current_scope(parser, sym); } + END_FOR_EACH_PTR(sym); return node; }