issue #98 add missing end_function() calls

pull/168/head
Dibyendu Majumdar 5 years ago
parent 2f85d6e8bc
commit 83bcfcbed2

@ -0,0 +1,54 @@
function()
return
function()
local
--[symbols]
a --local symbol ?
--[expressions]
1
local
--[symbols]
y --local symbol function
--[expressions]
function()
--upvalues a
return
function()
--upvalues a
return
--[primary start]
a --upvalue ?
--[primary end]
end
end
local
--[symbols]
a --local symbol ?
--[expressions]
5
local
--[symbols]
z --local symbol function
--[expressions]
function()
--upvalues a
return
function()
--upvalues a
return
--[primary start]
a --upvalue ?
--[primary end]
end
end
return
--[primary start]
y --local symbol function
--[primary end]
,
--[primary start]
z --local symbol function
--[primary end]
end
end

@ -1353,8 +1353,10 @@ function()
y --global symbol ?
=
function()
--upvalues a
return
function()
--upvalues a
return
--[primary start]
a --upvalue ?

@ -283,6 +283,7 @@ static struct ast_node *parse_expression(struct parser_state *);
static void parse_statement_list(struct parser_state *, struct ast_node_list **list);
static struct ast_node *parse_statement(struct parser_state *);
static struct ast_node *new_function(struct parser_state *parser);
static struct ast_node *end_function(struct parser_state *parser);
static struct block_scope *new_scope(struct parser_state *parser);
static void end_scope(struct parser_state *parser);
static struct ast_node *new_literal_expression(struct parser_state *parser, ravitype_t type);
@ -506,15 +507,19 @@ static bool add_upvalue_in_function(struct parser_state *parser, struct ast_node
* the symbol is found or we exhaust the search. NULL is returned if search was
* exhausted.
*/
static struct lua_symbol *search_for_variable(struct parser_state *parser, const TString *varname) {
static struct lua_symbol *search_for_variable(struct parser_state *parser, const TString *varname, bool *is_local) {
*is_local = false;
struct block_scope *current_scope = parser->current_scope;
struct ast_node *start_function = parser->current_function;
assert(current_scope && current_scope->function == parser->current_function);
while (current_scope) {
struct ast_node *current_function = current_scope->function;
while (current_scope && current_function == current_scope->function) {
struct lua_symbol *symbol = search_for_variable_in_block(current_scope, varname);
if (symbol)
if (symbol) {
*is_local = (current_function == start_function);
return symbol;
}
current_scope = current_scope->parent;
}
// search upvalues in the function
@ -554,15 +559,24 @@ static void add_upvalue_in_levels_upto(struct parser_state *parser, struct ast_n
}
}
/* Is the current symbol a local function within current function?
*/
static bool is_local_function(struct parser_state *parser, struct lua_symbol *symbol) {
return symbol->symbol_type == SYM_LOCAL && symbol->value_type.type_code == RAVI_TFUNCTION &&
parser->current_function == symbol->var.block->function->function_expr.parent_function;
}
/* Creates a symbol reference to the name; the returned symbol reference
* may be local, upvalue or global.
*/
static struct ast_node *new_symbol_reference(struct parser_state *parser) {
TString *varname = check_name_and_next(parser->ls);
struct lua_symbol *symbol = search_for_variable(parser, varname);
const char *str = getstr(varname);
bool is_local = false;
struct lua_symbol *symbol = search_for_variable(parser, varname, &is_local);
if (symbol) {
// we found a local or upvalue
if (symbol->symbol_type == SYM_LOCAL && symbol->var.block->function != parser->current_function) {
if (!is_local) {
// If the local symbol occurred in a parent function then we
// need to construct an upvalue. Lua requires that the upvalue be
// added to all functions in the tree up to the function where the local
@ -1040,6 +1054,7 @@ static struct ast_node *parse_simple_expression(struct parser_state *parser) {
luaX_next(ls);
struct ast_node *function_ast = new_function(parser);
parse_function_body(parser, function_ast, 0, ls->linenumber);
end_function(parser);
return function_ast;
}
default: {
@ -1442,6 +1457,7 @@ static struct ast_node *parse_local_function_statement(struct parser_state *pars
new_local_symbol(parser, check_name_and_next(ls), RAVI_TFUNCTION, NULL); /* new local variable */
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);
struct ast_node *stmt = dmrC_allocator_allocate(&parser->container->ast_node_allocator, 0);
stmt->type = AST_LOCAL_STMT;
stmt->local_stmt.vars = NULL;
@ -1504,6 +1520,7 @@ static struct ast_node *parse_function_statement(struct parser_state *parser, in
int ismethod = function_stmt->function_stmt.methodname != NULL;
struct ast_node *function_ast = new_function(parser);
parse_function_body(parser, function_ast, ismethod, line);
end_function(parser);
function_stmt->function_stmt.function_expr = function_ast;
return function_stmt;
}
@ -1821,6 +1838,22 @@ static void print_symbol(membuff_t *buf, struct lua_symbol *sym, int level) {
}
}
static void print_symbol_name(membuff_t *buf, struct lua_symbol *sym) {
switch (sym->symbol_type) {
case SYM_LOCAL:
case SYM_GLOBAL: {
printf_buf(buf, "%t", sym->var.var_name);
break;
}
case SYM_UPVALUE: {
printf_buf(buf, "%t", sym->upvalue.var->var.var_name);
break;
}
default:
assert(0);
}
}
static void print_symbol_list(membuff_t *buf, struct lua_symbol_list *list, int level, const char *delimiter) {
struct lua_symbol *node;
bool is_first = true;
@ -1834,6 +1867,19 @@ static void print_symbol_list(membuff_t *buf, struct lua_symbol_list *list, int
END_FOR_EACH_PTR(node);
}
static void print_symbol_names(membuff_t *buf, struct lua_symbol_list *list) {
struct lua_symbol *node;
bool is_first = true;
FOR_EACH_PTR(list, node) {
if (is_first)
is_first = false;
else
printf_buf(buf, ", ");
print_symbol_name(buf, node);
}
END_FOR_EACH_PTR(node);
}
static const char *get_unary_opr_str(UnOpr op) {
switch (op) {
case OPR_NOT:
@ -1921,12 +1967,15 @@ static void print_ast_node(membuff_t *buf, struct ast_node *node, int level) {
printf_buf(buf, "%pfunction(\n", level);
print_symbol_list(buf, node->function_expr.args, level + 1, ",");
printf_buf(buf, "%p)\n", level);
printf_buf(buf, "%pupvalues ", level);
print_symbol_list(buf, node->function_expr.upvalues, level + 1, ",");
}
else {
printf_buf(buf, "%pfunction()\n", level);
}
if (node->function_expr.upvalues) {
printf_buf(buf, "%p%c ", level, "upvalues ");
print_symbol_names(buf, node->function_expr.upvalues);
printf_buf(buf, "\n");
}
print_statement_list(buf, node->function_expr.function_statement_list, level);
printf_buf(buf, "%pend\n", level);
break;

Loading…
Cancel
Save