diff --git a/src/linearizer.c b/src/linearizer.c index 1690402..2a29ae1 100644 --- a/src/linearizer.c +++ b/src/linearizer.c @@ -1593,17 +1593,19 @@ encountered a goto statement but we did not know the block then. static void linearize_label_statement(struct proc *proc, struct ast_node *node) { /* If the current block is empty then we can use it as the label target */ - struct basic_block* block = proc->current_bb; - if (ptrlist_size((const struct ptr_list*)block->insns) > 0) { - /* Create new block as label target */ - block = create_block(proc); + struct basic_block* block; + if (node->label_stmt.symbol->label.pseudo != NULL) { + assert(node->label_stmt.symbol->label.pseudo->block != NULL); + block = node->label_stmt.symbol->label.pseudo->block; start_block(proc, block); } - if (node->label_stmt.symbol->label.pseudo != NULL) { - /* label pseudo was created by a goto statement */ - assert(node->label_stmt.symbol->label.pseudo->block == NULL); - node->label_stmt.symbol->label.pseudo->block = block; - } else { + else { + block = proc->current_bb; + if (ptrlist_size((const struct ptr_list*)block->insns) > 0) { + /* Create new block as label target */ + block = create_block(proc); + start_block(proc, block); + } node->label_stmt.symbol->label.pseudo = allocate_block_pseudo(proc, block); } } @@ -1611,11 +1613,15 @@ static void linearize_label_statement(struct proc *proc, struct ast_node *node) /* TODO move this logic to parser? */ /* Search for a label going up scopes starting from the scope where the goto statement appeared. */ static struct lua_symbol *find_label(struct proc *proc, struct block_scope *block, - const struct string_object *label_name) + const struct string_object *label_name, struct block_scope **min_closing_block) { struct ast_node *function = block->function; /* We need to stay inside the function when lookng for the label */ + *min_closing_block = NULL; while (block != NULL && block->function == function) { struct lua_symbol *symbol; + if (block->need_close) { + *min_closing_block = block; + } FOR_EACH_PTR_REVERSE(block->symbol_list, symbol) { if (symbol->symbol_type == SYM_LABEL && symbol->label.label_name == label_name) { @@ -1628,6 +1634,57 @@ static struct lua_symbol *find_label(struct proc *proc, struct block_scope *bloc return NULL; } +struct block_scope *find_min_closing_block(struct block_scope *block, struct block_scope *target_block) +{ + struct ast_node *function = block->function; /* We need to stay inside the function when lookng for the label */ + struct block_scope *min_closing_block = NULL; + while (block != NULL && block->function == function) { + if (block->need_close) { + min_closing_block = block; + } + if (block == target_block) + break; + block = block->parent; + } + return min_closing_block; +} + +static bool is_already_closed(struct proc *proc, struct basic_block *block) +{ + struct instruction *last_insn = raviX_last_instruction(block); + if (last_insn == NULL) + return false; + if (last_insn->opcode == op_ret) + return true; + if (last_insn->opcode == op_close) { + // hmmm + assert(false); + } + return false; +} + +static void instruct_close(struct proc *proc, struct basic_block *block, struct block_scope *scope) +{ + if (is_already_closed(proc, block)) + return; + /* temporarily make block current */ + struct basic_block *prev_current = proc->current_bb; + proc->current_bb = block; + struct lua_symbol *symbol; + FOR_EACH_PTR(scope->symbol_list, symbol) + { + if (symbol->symbol_type == SYM_LOCAL && symbol->variable.escaped) { + assert(symbol->variable.pseudo); + struct instruction *insn = allocate_instruction(proc, op_close); + add_instruction_operand(proc, insn, symbol->variable.pseudo); + add_instruction(proc, insn); + break; + } + } + END_FOR_EACH_PTR(symbol) + proc->current_bb = prev_current; +} + /* When linearizing the goto statement we create a pseudo for the label if it hasn't been already created. But at this point we may not know the target basic block to goto, which we expect to be filled when the label is @@ -1640,22 +1697,34 @@ static void linearize_goto_statement(struct proc *proc, const struct ast_node *n if (proc->current_break_target == NULL) { handle_error(proc->linearizer->ast_container, "no current break target"); } + struct block_scope *min_closing_block = find_min_closing_block(node->goto_stmt.goto_scope, proc->current_break_scope); instruct_br(proc, allocate_block_pseudo(proc, proc->current_break_target)); start_block(proc, create_block(proc)); + if (min_closing_block) { + instruct_close(proc, proc->current_break_target, min_closing_block); + } return; } /* The AST does not provide link to the label so we have to search for the label in the goto scope and above */ if (node->goto_stmt.goto_scope) { - struct lua_symbol *symbol = find_label(proc, node->goto_stmt.goto_scope, node->goto_stmt.name); + struct block_scope *min_closing_block = NULL; + struct lua_symbol *symbol = find_label(proc, node->goto_stmt.goto_scope, node->goto_stmt.name, &min_closing_block); if (symbol) { /* label found */ if (symbol->label.pseudo == NULL) { - /* No pseudo? create with NULL target block, must be filled by a label statement */ - symbol->label.pseudo = allocate_block_pseudo(proc, NULL); + /* No pseudo? create with target block to be processed later when label is encountered */ + symbol->label.pseudo = allocate_block_pseudo(proc, create_block(proc)); + } + else { + assert(symbol->label.pseudo->block != NULL); } instruct_br(proc, symbol->label.pseudo); start_block(proc, create_block(proc)); + if (min_closing_block) { + /* close intruction needs to go after the label */ + instruct_close(proc, symbol->label.pseudo->block, min_closing_block); + } return; } } @@ -1783,7 +1852,9 @@ static void linearize_for_num_statement(struct proc *proc, struct ast_node *node struct basic_block *Lbody = create_block(proc); struct basic_block *Lend = create_block(proc); struct basic_block *previous_break_target = proc->current_break_target; + struct block_scope *previous_break_scope = proc->current_break_scope; proc->current_break_target = Lend; + proc->current_break_scope = proc->current_scope; start_block(proc, L1); create_binary_instruction(proc, op_addii, index_var_pseudo, step_pseudo, index_var_pseudo); @@ -1804,6 +1875,10 @@ static void linearize_for_num_statement(struct proc *proc, struct ast_node *node linearize_statement_list(proc, node->for_stmt.for_statement_list); end_scope(proc->linearizer, proc); + if (proc->current_break_scope->need_close) { + /* need to put close instruction in current basic block */ + instruct_close(proc, proc->current_bb, proc->current_break_scope); + } instruct_br(proc, allocate_block_pseudo(proc, L1)); end_scope(proc->linearizer, proc); @@ -1817,6 +1892,7 @@ static void linearize_for_num_statement(struct proc *proc, struct ast_node *node start_block(proc, Lend); proc->current_break_target = previous_break_target; + proc->current_break_scope = previous_break_scope; } static void linearize_while_statment(struct proc *proc, struct ast_node *node) @@ -1825,7 +1901,9 @@ static void linearize_while_statment(struct proc *proc, struct ast_node *node) struct basic_block *body_block = create_block(proc); struct basic_block *end_block = create_block(proc); struct basic_block *previous_break_target = proc->current_break_target; + struct block_scope *previous_break_scope = proc->current_break_scope; proc->current_break_target = end_block; + proc->current_break_scope = node->while_or_repeat_stmt.loop_scope; if (node->type == STMT_REPEAT) { instruct_br(proc, allocate_block_pseudo(proc, body_block)); @@ -1840,11 +1918,16 @@ static void linearize_while_statment(struct proc *proc, struct ast_node *node) start_scope(proc->linearizer, proc, node->while_or_repeat_stmt.loop_scope); linearize_statement_list(proc, node->while_or_repeat_stmt.loop_statement_list); end_scope(proc->linearizer, proc); + + if (proc->current_break_scope->need_close) { + instruct_close(proc, proc->current_bb, proc->current_break_scope); + } instruct_br(proc, allocate_block_pseudo(proc, test_block)); start_block(proc, end_block); proc->current_break_target = previous_break_target; + proc->current_break_scope = previous_break_scope; } static void linearize_function_statement(struct proc *proc, struct ast_node *node) @@ -2050,6 +2133,9 @@ static void end_scope(struct linearizer_state *linearizer, struct proc *proc) { struct block_scope *scope = proc->current_scope; struct lua_symbol *sym; + if (scope->need_close) { + instruct_close(proc, proc->current_bb, scope); + } FOR_EACH_PTR_REVERSE(scope->symbol_list, sym) { if (sym->symbol_type == SYM_LOCAL) { @@ -2177,7 +2263,7 @@ static const char *op_codenames[] = { "PUTik", "PUTsk", "TPUT", "TPUTik", "TPUTsk", "IAPUT", "IAPUTiv", "FAPUT", "FAPUTfv", "CBR", "BR", "MOV", "MOVi", "MOVif", "MOVf", "MOVfi", "CALL", "GET", "GETik", "GETsk", "TGET", "TGETik", "TGETsk", "IAGET", "IAGETik", "FAGET", "FAGETik", - "STOREGLOBAL"}; + "STOREGLOBAL", "CLOSE"}; static void output_pseudo_list(struct pseudo_list *list, membuff_t *mb) { diff --git a/src/linearizer.h b/src/linearizer.h index 1f6133b..386e92c 100644 --- a/src/linearizer.h +++ b/src/linearizer.h @@ -117,6 +117,7 @@ enum opcode { op_faget, op_faget_ikey, op_storeglobal, + op_close }; enum pseudo_type { @@ -191,7 +192,9 @@ struct proc { struct ast_node *function_expr; /* function ast that we are compiling */ struct block_scope *current_scope; struct basic_block *current_bb; - struct basic_block *current_break_target; /* track the current break target, previous target must be saved / restored in stack discipline */ + struct basic_block *current_break_target; /* track the current break target, previous target must be saved / + restored in stack discipline */ + struct block_scope *current_break_scope; /* as above track the block scope */ struct pseudo_generator local_pseudos; /* locals */ struct pseudo_generator temp_int_pseudos; /* temporaries known to be integer type */ struct pseudo_generator temp_flt_pseudos; /* temporaries known to be number type */ diff --git a/src/parser.c b/src/parser.c index 85b60e3..b1da03e 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1,5 +1,5 @@ /* -A parser and syntax tree builder for Ravi. +A parser and syntax tree builder for Ravi. Note that the overall structure of the parser is loosely based on the Lua 5.3 parser. The parser retains the syntactic structure - including constant expressions and some redundant @@ -254,7 +254,9 @@ static bool add_upvalue_in_function(struct parser_state *parser, struct ast_node (const struct ptr_list *)function->function_expr.upvalues); /* position of upvalue in function */ copy_type(&upvalue->upvalue.value_type, &sym->variable.value_type); add_symbol(parser->container, &function->function_expr.upvalues, upvalue); - sym->variable.escaped = 1; /* mark original variable as having escaped */ + sym->variable.escaped = 1; /* mark original variable as having escaped */ + sym->variable.block->need_close = 1; /* mark block containing variable as needing close operation */ + sym->variable.block->function->function_expr.need_close = 1; return true; } @@ -1454,6 +1456,7 @@ static struct block_scope *new_scope(struct parser_state *parser) scope->symbol_list = NULL; // scope->do_statement_list = NULL; scope->function = parser->current_function; + scope->need_close = 0; assert(scope->function && scope->function->type == EXPR_FUNCTION); scope->parent = parser->current_scope; parser->current_scope = scope; @@ -1480,6 +1483,7 @@ static struct ast_node *new_function(struct parser_state *parser) set_type(&node->function_expr.type, RAVI_TFUNCTION); node->function_expr.is_method = false; node->function_expr.is_vararg = false; + node->function_expr.need_close = false; node->function_expr.proc_id = 0; node->function_expr.args = NULL; node->function_expr.child_functions = NULL; diff --git a/src/parser.h b/src/parser.h index 0a74a2d..74a4dd3 100644 --- a/src/parser.h +++ b/src/parser.h @@ -152,6 +152,7 @@ struct block_scope { struct ast_node *function; /* function owning this block - of type FUNCTION_EXPR */ struct block_scope *parent; /* parent block, may belong to parent function */ struct lua_symbol_list *symbol_list; /* symbols defined in this block */ + unsigned need_close: 1; /* When we exit scope of this block the upvalues need to be closed */ }; /*STMT_RETURN */ @@ -248,8 +249,9 @@ struct binary_expression { }; struct function_expression { BASE_EXPRESSION_FIELDS; - unsigned int is_vararg : 1; - unsigned int is_method : 1; + unsigned is_vararg : 1; + unsigned is_method : 1; + unsigned need_close : 1; uint32_t proc_id; /* Backend allocated id */ struct ast_node *parent_function; /* parent function or NULL if main chunk */ struct block_scope *main_block; /* the function's main block */ diff --git a/tests/expected/results.expected b/tests/expected/results.expected index df0ef7f..85aad8e 100644 --- a/tests/expected/results.expected +++ b/tests/expected/results.expected @@ -2636,6 +2636,7 @@ L0 (entry) MOV {1 Kint(0)} {local(a, 0)} CLOSURE {Proc%3} {T(1)} STOREGLOBAL {y, T(1)} + CLOSE {local(a, 0)} BR {L1} L1 (exit) define Proc%3 @@ -5888,15 +5889,15 @@ function() end define Proc%1 L0 (entry) - BR {L3} + BR {L2} L1 (exit) L2 - STOREGLOBAL {x, 1 Kint(0)} - BR {L3} -L3 STOREGLOBAL {z, 2 Kint(1)} STOREGLOBAL {y, 1 Kint(0)} BR {L0} +L3 + STOREGLOBAL {x, 1 Kint(0)} + BR {L2} L4 BR {L1} goto l1; do ::l1:: end @@ -6295,34 +6296,40 @@ L4 EQ {local(a, 0), local(d, 3)} {T(2)} CBR {T(2)} {L7, L8} L5 - BR {L9} + BR {L10} L6 - BR {L9} + BR {L12} L7 - BR {L9} + BR {L12} L8 - BR {L13} + BR {L15} L9 - BR {L1} + BR {L10} L10 - BR {L9} + BR {L12} L11 BR {L9} L12 - BR {L9} + BR {L19} L13 - EQ {local(a, 0), local(e, 4)} {T(3)} - CBR {T(3)} {L14, L15} + BR {L9} L14 BR {L9} L15 - BR {L9} + EQ {local(a, 0), local(e, 4)} {T(3)} + CBR {T(3)} {L16, L17} L16 - BR {L9} + BR {L19} L17 - BR {L16} + BR {L19} L18 - BR {L16} + BR {L9} +L19 + BR {L1} +L20 + BR {L18} +L21 + BR {L18} return function (a) while a < 10 do a = a + 1 end end function() return @@ -6540,15 +6547,17 @@ L2 NOT {T(0)} {T(1)} CBR {T(1)} {L3, L4} L3 - BR {L6} + BR {L5} L4 ADD {local(a, 0), 1 Kint(1)} {T(2)} MOV {T(2)} {local(a, 0)} BR {L0} L5 - BR {L4} -L6 BR {L1} +L6 + BR {L4} +L7 + BR {L5} return function () (function () end){f()} end @@ -8493,20 +8502,24 @@ end define Proc%1 L0 (entry) MOV {12 Kint(0)} {local(y, 1)} - BR {L3} + BR {L2} L1 (exit) L2 + MOV {local(y, 1)} {local(x, 0)} + BR {L3} +L3 ADD {local(x, 0), 1 Kint(1)} {T(0)} MOV {T(0)} {local(x, 0)} BR {L4} -L3 - MOV {local(y, 1)} {local(x, 0)} - BR {L2} L4 LOADGLOBAL {assert} {T(0)} EQ {local(x, 0), 13 Kint(2)} {T(1)} CALL {T(0), T(1)} {T(0..)} BR {L1} +L5 + BR {L2} +L6 + BR {L4} for i=1,10 do print(i) end function() --locals i @@ -9195,6 +9208,7 @@ L0 (entry) MOV {T(0)} {local(msgs, 0)} CLOSURE {Proc%2} {T(1)} STOREGLOBAL {Message, T(1)} + CLOSE {local(msgs, 0)} BR {L1} L1 (exit) define Proc%2 diff --git a/tests/expected/t06_close.expected b/tests/expected/t06_close.expected new file mode 100644 index 0000000..75e75ee --- /dev/null +++ b/tests/expected/t06_close.expected @@ -0,0 +1,1443 @@ + +function() +end +function() +end +define Proc%1 +L0 (entry) + BR {L1} +L1 (exit) +digraph Proc1 { +L0 [shape=none, margin=0, label=< + + +
L0
BR {L1}
>]; +L0 -> L1 +} +local z, a do (function() a =1 end)() end + +function() +--locals z, a + local + --[symbols] + z --local symbol any + , + a --local symbol any + do + --[expression statement start] + --[expression list start] + --[suffixed expr start] closure + --[primary start] closure + function() + --upvalues a + --[expression statement start] + --[var list start] + --[suffixed expr start] any + --[primary start] any + a --upvalue any + --[primary end] + --[suffixed expr end] + = --[var list end] + --[expression list start] + 1 + --[expression list end] + --[expression statement end] + end + --[primary end] + --[suffix list start] + --[function call start] any + ( + ) + --[function call end] + --[suffix list end] + --[suffixed expr end] + --[expression list end] + --[expression statement end] + end +end +function() +--locals z, a + local + --[symbols] + z --local symbol any + , + a --local symbol any + do + --[expression statement start] + --[expression list start] + --[suffixed expr start] closure + --[primary start] closure + function() + --upvalues a + --[expression statement start] + --[var list start] + --[suffixed expr start] any + --[primary start] any + a --upvalue any + --[primary end] + --[suffixed expr end] + = --[var list end] + --[expression list start] + 1 + --[expression list end] + --[expression statement end] + end + --[primary end] + --[suffix list start] + --[function call start] any + ( + ) + --[function call end] + --[suffix list end] + --[suffixed expr end] + --[expression list end] + --[expression statement end] + end +end +define Proc%1 +L0 (entry) + CLOSURE {Proc%2} {T(0)} + CALL {T(0)} {T(0..)} + CLOSE {local(a, 1)} + BR {L1} +L1 (exit) +define Proc%2 +L0 (entry) + MOV {1 Kint(0)} {Upval(0, Proc%1, a)} + BR {L1} +L1 (exit) +digraph Proc1 { +L0 [shape=none, margin=0, label=< + + + + + +
L0
CLOSURE {Proc%2} {T(0)}
CALL {T(0)} {T(0..)}
CLOSE {local(a, 1)}
BR {L1}
>]; +L0 -> L1 +digraph Proc2 { +L0 [shape=none, margin=0, label=< + + + +
L0
MOV {1 Kint(0)} {Upval(0, Proc%1, a)}
BR {L1}
>]; +L0 -> L1 +} +digraph Proc2 { +L0 [shape=none, margin=0, label=< + + + +
L0
MOV {1 Kint(0)} {Upval(0, Proc%1, a)}
BR {L1}
>]; +L0 -> L1 +} +} +function add3(x) + return function (y) + return function (z) return x + y + z end + end +end + +function() + add3 --global symbol any + = + function( + x --local symbol any + ) + --locals x + return + function( + y --local symbol any + ) + --locals y + --upvalues x + return + function( + z --local symbol any + ) + --locals z + --upvalues x, y + return + --[binary expr start] any + --[binary expr start] any + --[suffixed expr start] any + --[primary start] any + x --upvalue any + --[primary end] + --[suffixed expr end] + + + --[suffixed expr start] any + --[primary start] any + y --upvalue any + --[primary end] + --[suffixed expr end] + --[binary expr end] + + + --[suffixed expr start] any + --[primary start] any + z --local symbol any + --[primary end] + --[suffixed expr end] + --[binary expr end] + end + end + end +end +function() + add3 --global symbol any + = + function( + x --local symbol any + ) + --locals x + return + function( + y --local symbol any + ) + --locals y + --upvalues x + return + function( + z --local symbol any + ) + --locals z + --upvalues x, y + return + --[binary expr start] any + --[binary expr start] any + --[suffixed expr start] any + --[primary start] any + x --upvalue any + --[primary end] + --[suffixed expr end] + + + --[suffixed expr start] any + --[primary start] any + y --upvalue any + --[primary end] + --[suffixed expr end] + --[binary expr end] + + + --[suffixed expr start] any + --[primary start] any + z --local symbol any + --[primary end] + --[suffixed expr end] + --[binary expr end] + end + end + end +end +define Proc%1 +L0 (entry) + CLOSURE {Proc%2} {T(1)} + STOREGLOBAL {add3, T(1)} + BR {L1} +L1 (exit) +define Proc%2 +L0 (entry) + CLOSURE {Proc%3} {T(0)} + RET {T(0)} {L1} +L1 (exit) +define Proc%3 +L0 (entry) + CLOSURE {Proc%4} {T(0)} + RET {T(0)} {L1} +L1 (exit) +define Proc%4 +L0 (entry) + ADD {Upval(0, Proc%2, x), Upval(1, Proc%3, y)} {T(0)} + ADD {T(0), local(z, 0)} {T(1)} + RET {T(1)} {L1} +L1 (exit) +digraph Proc1 { +L0 [shape=none, margin=0, label=< + + + + +
L0
CLOSURE {Proc%2} {T(1)}
STOREGLOBAL {add3, T(1)}
BR {L1}
>]; +L0 -> L1 +digraph Proc2 { +L0 [shape=none, margin=0, label=< + + + +
L0
CLOSURE {Proc%3} {T(0)}
RET {T(0)} {L1}
>]; +L0 -> L1 +digraph Proc3 { +L0 [shape=none, margin=0, label=< + + + +
L0
CLOSURE {Proc%4} {T(0)}
RET {T(0)} {L1}
>]; +L0 -> L1 +digraph Proc4 { +L0 [shape=none, margin=0, label=< + + + + +
L0
ADD {Upval(0, Proc%2, x), Upval(1, Proc%3, y)} {T(0)}
ADD {T(0), local(z, 0)} {T(1)}
RET {T(1)} {L1}
>]; +L0 -> L1 +} +digraph Proc4 { +L0 [shape=none, margin=0, label=< + + + + +
L0
ADD {Upval(0, Proc%2, x), Upval(1, Proc%3, y)} {T(0)}
ADD {T(0), local(z, 0)} {T(1)}
RET {T(1)} {L1}
>]; +L0 -> L1 +} +} +digraph Proc3 { +L0 [shape=none, margin=0, label=< + + + +
L0
CLOSURE {Proc%4} {T(0)}
RET {T(0)} {L1}
>]; +L0 -> L1 +digraph Proc4 { +L0 [shape=none, margin=0, label=< + + + + +
L0
ADD {Upval(0, Proc%2, x), Upval(1, Proc%3, y)} {T(0)}
ADD {T(0), local(z, 0)} {T(1)}
RET {T(1)} {L1}
>]; +L0 -> L1 +} +digraph Proc4 { +L0 [shape=none, margin=0, label=< + + + + +
L0
ADD {Upval(0, Proc%2, x), Upval(1, Proc%3, y)} {T(0)}
ADD {T(0), local(z, 0)} {T(1)}
RET {T(1)} {L1}
>]; +L0 -> L1 +} +} +} +digraph Proc2 { +L0 [shape=none, margin=0, label=< + + + +
L0
CLOSURE {Proc%3} {T(0)}
RET {T(0)} {L1}
>]; +L0 -> L1 +digraph Proc3 { +L0 [shape=none, margin=0, label=< + + + +
L0
CLOSURE {Proc%4} {T(0)}
RET {T(0)} {L1}
>]; +L0 -> L1 +digraph Proc4 { +L0 [shape=none, margin=0, label=< + + + + +
L0
ADD {Upval(0, Proc%2, x), Upval(1, Proc%3, y)} {T(0)}
ADD {T(0), local(z, 0)} {T(1)}
RET {T(1)} {L1}
>]; +L0 -> L1 +} +digraph Proc4 { +L0 [shape=none, margin=0, label=< + + + + +
L0
ADD {Upval(0, Proc%2, x), Upval(1, Proc%3, y)} {T(0)}
ADD {T(0), local(z, 0)} {T(1)}
RET {T(1)} {L1}
>]; +L0 -> L1 +} +} +digraph Proc3 { +L0 [shape=none, margin=0, label=< + + + +
L0
CLOSURE {Proc%4} {T(0)}
RET {T(0)} {L1}
>]; +L0 -> L1 +digraph Proc4 { +L0 [shape=none, margin=0, label=< + + + + +
L0
ADD {Upval(0, Proc%2, x), Upval(1, Proc%3, y)} {T(0)}
ADD {T(0), local(z, 0)} {T(1)}
RET {T(1)} {L1}
>]; +L0 -> L1 +} +digraph Proc4 { +L0 [shape=none, margin=0, label=< + + + + +
L0
ADD {Upval(0, Proc%2, x), Upval(1, Proc%3, y)} {T(0)}
ADD {T(0), local(z, 0)} {T(1)}
RET {T(1)} {L1}
>]; +L0 -> L1 +} +} +} +} +local a = {} +local x = 10 +for i = 1, 2 do + local j = i + a[i] = function() return x + j end +end +x = 20 + +function() +--locals a, x, i, j + local + --[symbols] + a --local symbol any + --[expressions] + { --[table constructor start] table + } --[table constructor end] + local + --[symbols] + x --local symbol any + --[expressions] + 10 + for + i --local symbol any + = + 1 + , + 2 + do + local + --[symbols] + j --local symbol any + --[expressions] + --[suffixed expr start] any + --[primary start] any + i --local symbol any + --[primary end] + --[suffixed expr end] + --[expression statement start] + --[var list start] + --[suffixed expr start] any + --[primary start] any + a --local symbol any + --[primary end] + --[suffix list start] + --[Y index start] any + [ + --[suffixed expr start] any + --[primary start] any + i --local symbol any + --[primary end] + --[suffixed expr end] + ] + --[Y index end] + --[suffix list end] + --[suffixed expr end] + = --[var list end] + --[expression list start] + function() + --upvalues x, j + return + --[binary expr start] any + --[suffixed expr start] any + --[primary start] any + x --upvalue any + --[primary end] + --[suffixed expr end] + + + --[suffixed expr start] any + --[primary start] any + j --upvalue any + --[primary end] + --[suffixed expr end] + --[binary expr end] + end + --[expression list end] + --[expression statement end] + end + --[expression statement start] + --[var list start] + --[suffixed expr start] any + --[primary start] any + x --local symbol any + --[primary end] + --[suffixed expr end] + = --[var list end] + --[expression list start] + 20 + --[expression list end] + --[expression statement end] +end +function() +--locals a, x, i, j + local + --[symbols] + a --local symbol any + --[expressions] + { --[table constructor start] table + } --[table constructor end] + local + --[symbols] + x --local symbol any + --[expressions] + 10 + for + i --local symbol integer + = + 1 + , + 2 + do + local + --[symbols] + j --local symbol any + --[expressions] + --[suffixed expr start] integer + --[primary start] integer + i --local symbol integer + --[primary end] + --[suffixed expr end] + --[expression statement start] + --[var list start] + --[suffixed expr start] any + --[primary start] any + a --local symbol any + --[primary end] + --[suffix list start] + --[Y index start] any + [ + --[suffixed expr start] integer + --[primary start] integer + i --local symbol integer + --[primary end] + --[suffixed expr end] + ] + --[Y index end] + --[suffix list end] + --[suffixed expr end] + = --[var list end] + --[expression list start] + function() + --upvalues x, j + return + --[binary expr start] any + --[suffixed expr start] any + --[primary start] any + x --upvalue any + --[primary end] + --[suffixed expr end] + + + --[suffixed expr start] any + --[primary start] any + j --upvalue any + --[primary end] + --[suffixed expr end] + --[binary expr end] + end + --[expression list end] + --[expression statement end] + end + --[expression statement start] + --[var list start] + --[suffixed expr start] any + --[primary start] any + x --local symbol any + --[primary end] + --[suffixed expr end] + = --[var list end] + --[expression list start] + 20 + --[expression list end] + --[expression statement end] +end +define Proc%1 +L0 (entry) + NEWTABLE {T(0)} + MOV {T(0)} {local(a, 0)} + MOV {10 Kint(0)} {local(x, 1)} + MOV {1 Kint(1)} {Tint(1)} + MOV {2 Kint(2)} {Tint(2)} + MOV {1 Kint(1)} {Tint(3)} + LIii {0 Kint(3), Tint(3)} {Tint(4)} + SUBii {Tint(1), Tint(3)} {Tint(1)} + BR {L2} +L1 (exit) +L2 + ADDii {Tint(1), Tint(3)} {Tint(1)} + CBR {Tint(4)} {L3, L4} +L3 + LEii {Tint(2), Tint(1)} {Tint(5)} + CBR {Tint(5)} {L6, L5} +L4 + LIii {Tint(1), Tint(2)} {Tint(5)} + CBR {Tint(5)} {L6, L5} +L5 + MOV {Tint(1)} {Tint(0)} + MOV {Tint(0)} {local(j, 2)} + CLOSURE {Proc%2} {T(1)} + PUTik {local(a, 0), Tint(0), T(1)} + CLOSE {local(j, 2)} + BR {L2} +L6 + MOV {20 Kint(4)} {local(x, 1)} + CLOSE {local(x, 1)} + BR {L1} +define Proc%2 +L0 (entry) + ADD {Upval(0, Proc%1, x), Upval(1, Proc%1, j)} {T(0)} + RET {T(0)} {L1} +L1 (exit) +digraph Proc1 { +L0 [shape=none, margin=0, label=< + + + + + + + + + + +
L0
NEWTABLE {T(0)}
MOV {T(0)} {local(a, 0)}
MOV {10 Kint(0)} {local(x, 1)}
MOV {1 Kint(1)} {Tint(1)}
MOV {2 Kint(2)} {Tint(2)}
MOV {1 Kint(1)} {Tint(3)}
LIii {0 Kint(3), Tint(3)} {Tint(4)}
SUBii {Tint(1), Tint(3)} {Tint(1)}
BR {L2}
>]; +L0 -> L2 +digraph Proc2 { +L0 [shape=none, margin=0, label=< + + + +
L0
ADD {Upval(0, Proc%1, x), Upval(1, Proc%1, j)} {T(0)}
RET {T(0)} {L1}
>]; +L0 -> L1 +} +digraph Proc2 { +L0 [shape=none, margin=0, label=< + + + +
L0
ADD {Upval(0, Proc%1, x), Upval(1, Proc%1, j)} {T(0)}
RET {T(0)} {L1}
>]; +L0 -> L1 +} +L2 [shape=none, margin=0, label=< + + + +
L2
ADDii {Tint(1), Tint(3)} {Tint(1)}
CBR {Tint(4)} {L3, L4}
>]; +L2 -> L3 +L2 -> L4 +digraph Proc2 { +L0 [shape=none, margin=0, label=< + + + +
L0
ADD {Upval(0, Proc%1, x), Upval(1, Proc%1, j)} {T(0)}
RET {T(0)} {L1}
>]; +L0 -> L1 +} +L3 [shape=none, margin=0, label=< + + + +
L3
LEii {Tint(2), Tint(1)} {Tint(5)}
CBR {Tint(5)} {L6, L5}
>]; +L3 -> L6 +L3 -> L5 +digraph Proc2 { +L0 [shape=none, margin=0, label=< + + + +
L0
ADD {Upval(0, Proc%1, x), Upval(1, Proc%1, j)} {T(0)}
RET {T(0)} {L1}
>]; +L0 -> L1 +} +L4 [shape=none, margin=0, label=< + + + +
L4
LIii {Tint(1), Tint(2)} {Tint(5)}
CBR {Tint(5)} {L6, L5}
>]; +L4 -> L6 +L4 -> L5 +digraph Proc2 { +L0 [shape=none, margin=0, label=< + + + +
L0
ADD {Upval(0, Proc%1, x), Upval(1, Proc%1, j)} {T(0)}
RET {T(0)} {L1}
>]; +L0 -> L1 +} +L5 [shape=none, margin=0, label=< + + + + + + + +
L5
MOV {Tint(1)} {Tint(0)}
MOV {Tint(0)} {local(j, 2)}
CLOSURE {Proc%2} {T(1)}
PUTik {local(a, 0), Tint(0), T(1)}
CLOSE {local(j, 2)}
BR {L2}
>]; +L5 -> L2 +digraph Proc2 { +L0 [shape=none, margin=0, label=< + + + +
L0
ADD {Upval(0, Proc%1, x), Upval(1, Proc%1, j)} {T(0)}
RET {T(0)} {L1}
>]; +L0 -> L1 +} +L6 [shape=none, margin=0, label=< + + + + +
L6
MOV {20 Kint(4)} {local(x, 1)}
CLOSE {local(x, 1)}
BR {L1}
>]; +L6 -> L1 +digraph Proc2 { +L0 [shape=none, margin=0, label=< + + + +
L0
ADD {Upval(0, Proc%1, x), Upval(1, Proc%1, j)} {T(0)}
RET {T(0)} {L1}
>]; +L0 -> L1 +} +} +local x = 1 +do + for i = 1,10 do + local j = i; + (function () x = x + j end)() + if i == 5 then break end + end +end +print(x) + +function() +--locals x, i, j + local + --[symbols] + x --local symbol any + --[expressions] + 1 + do + for + i --local symbol any + = + 1 + , + 10 + do + local + --[symbols] + j --local symbol any + --[expressions] + --[suffixed expr start] any + --[primary start] any + i --local symbol any + --[primary end] + --[suffixed expr end] + --[expression statement start] + --[expression list start] + --[suffixed expr start] closure + --[primary start] closure + function() + --upvalues x, j + --[expression statement start] + --[var list start] + --[suffixed expr start] any + --[primary start] any + x --upvalue any + --[primary end] + --[suffixed expr end] + = --[var list end] + --[expression list start] + --[binary expr start] any + --[suffixed expr start] any + --[primary start] any + x --upvalue any + --[primary end] + --[suffixed expr end] + + + --[suffixed expr start] any + --[primary start] any + j --upvalue any + --[primary end] + --[suffixed expr end] + --[binary expr end] + --[expression list end] + --[expression statement end] + end + --[primary end] + --[suffix list start] + --[function call start] any + ( + ) + --[function call end] + --[suffix list end] + --[suffixed expr end] + --[expression list end] + --[expression statement end] + if + --[binary expr start] any + --[suffixed expr start] any + --[primary start] any + i --local symbol any + --[primary end] + --[suffixed expr end] + == + 5 + --[binary expr end] + then + goto break + end + end + end + --[expression statement start] + --[expression list start] + --[suffixed expr start] any + --[primary start] any + print --global symbol any + --[primary end] + --[suffix list start] + --[function call start] any + ( + --[suffixed expr start] any + --[primary start] any + x --local symbol any + --[primary end] + --[suffixed expr end] + ) + --[function call end] + --[suffix list end] + --[suffixed expr end] + --[expression list end] + --[expression statement end] +end +function() +--locals x, i, j + local + --[symbols] + x --local symbol any + --[expressions] + 1 + do + for + i --local symbol any + = + 1 + , + 10 + do + local + --[symbols] + j --local symbol any + --[expressions] + --[suffixed expr start] any + --[primary start] any + i --local symbol any + --[primary end] + --[suffixed expr end] + --[expression statement start] + --[expression list start] + --[suffixed expr start] closure + --[primary start] closure + function() + --upvalues x, j + --[expression statement start] + --[var list start] + --[suffixed expr start] any + --[primary start] any + x --upvalue any + --[primary end] + --[suffixed expr end] + = --[var list end] + --[expression list start] + --[binary expr start] any + --[suffixed expr start] any + --[primary start] any + x --upvalue any + --[primary end] + --[suffixed expr end] + + + --[suffixed expr start] any + --[primary start] any + j --upvalue any + --[primary end] + --[suffixed expr end] + --[binary expr end] + --[expression list end] + --[expression statement end] + end + --[primary end] + --[suffix list start] + --[function call start] any + ( + ) + --[function call end] + --[suffix list end] + --[suffixed expr end] + --[expression list end] + --[expression statement end] + if + --[binary expr start] any + --[suffixed expr start] any + --[primary start] any + i --local symbol any + --[primary end] + --[suffixed expr end] + == + 5 + --[binary expr end] + then + goto break + end + end + end + --[expression statement start] + --[expression list start] + --[suffixed expr start] any + --[primary start] any + print --global symbol any + --[primary end] + --[suffix list start] + --[function call start] any + ( + --[suffixed expr start] any + --[primary start] any + x --local symbol any + --[primary end] + --[suffixed expr end] + ) + --[function call end] + --[suffix list end] + --[suffixed expr end] + --[expression list end] + --[expression statement end] +end +define Proc%1 +L0 (entry) + MOV {1 Kint(0)} {local(x, 0)} + MOV {1 Kint(0)} {Tint(0)} + MOV {10 Kint(1)} {Tint(1)} + MOV {1 Kint(0)} {Tint(2)} + LIii {0 Kint(2), Tint(2)} {Tint(3)} + SUBii {Tint(0), Tint(2)} {Tint(0)} + BR {L2} +L1 (exit) +L2 + ADDii {Tint(0), Tint(2)} {Tint(0)} + CBR {Tint(3)} {L3, L4} +L3 + LEii {Tint(1), Tint(0)} {Tint(4)} + CBR {Tint(4)} {L6, L5} +L4 + LIii {Tint(0), Tint(1)} {Tint(4)} + CBR {Tint(4)} {L6, L5} +L5 + MOV {Tint(0)} {local(i, 1)} + MOV {local(i, 1)} {local(j, 2)} + CLOSURE {Proc%2} {T(0)} + CALL {T(0)} {T(0..)} + BR {L7} +L6 + CLOSE {local(j, 2)} + LOADGLOBAL {print} {T(2)} + CALL {T(2), local(x, 0)} {T(2..)} + CLOSE {local(x, 0)} + BR {L1} +L7 + EQ {local(i, 1), 5 Kint(3)} {T(1)} + CBR {T(1)} {L8, L9} +L8 + BR {L6} +L9 + CLOSE {local(j, 2)} + BR {L2} +L10 + BR {L9} +define Proc%2 +L0 (entry) + ADD {Upval(0, Proc%1, x), Upval(1, Proc%1, j)} {T(0)} + MOV {T(0)} {Upval(0, Proc%1, x)} + BR {L1} +L1 (exit) +digraph Proc1 { +L0 [shape=none, margin=0, label=< + + + + + + + + +
L0
MOV {1 Kint(0)} {local(x, 0)}
MOV {1 Kint(0)} {Tint(0)}
MOV {10 Kint(1)} {Tint(1)}
MOV {1 Kint(0)} {Tint(2)}
LIii {0 Kint(2), Tint(2)} {Tint(3)}
SUBii {Tint(0), Tint(2)} {Tint(0)}
BR {L2}
>]; +L0 -> L2 +digraph Proc2 { +L0 [shape=none, margin=0, label=< + + + + +
L0
ADD {Upval(0, Proc%1, x), Upval(1, Proc%1, j)} {T(0)}
MOV {T(0)} {Upval(0, Proc%1, x)}
BR {L1}
>]; +L0 -> L1 +} +digraph Proc2 { +L0 [shape=none, margin=0, label=< + + + + +
L0
ADD {Upval(0, Proc%1, x), Upval(1, Proc%1, j)} {T(0)}
MOV {T(0)} {Upval(0, Proc%1, x)}
BR {L1}
>]; +L0 -> L1 +} +L2 [shape=none, margin=0, label=< + + + +
L2
ADDii {Tint(0), Tint(2)} {Tint(0)}
CBR {Tint(3)} {L3, L4}
>]; +L2 -> L3 +L2 -> L4 +digraph Proc2 { +L0 [shape=none, margin=0, label=< + + + + +
L0
ADD {Upval(0, Proc%1, x), Upval(1, Proc%1, j)} {T(0)}
MOV {T(0)} {Upval(0, Proc%1, x)}
BR {L1}
>]; +L0 -> L1 +} +L3 [shape=none, margin=0, label=< + + + +
L3
LEii {Tint(1), Tint(0)} {Tint(4)}
CBR {Tint(4)} {L6, L5}
>]; +L3 -> L6 +L3 -> L5 +digraph Proc2 { +L0 [shape=none, margin=0, label=< + + + + +
L0
ADD {Upval(0, Proc%1, x), Upval(1, Proc%1, j)} {T(0)}
MOV {T(0)} {Upval(0, Proc%1, x)}
BR {L1}
>]; +L0 -> L1 +} +L4 [shape=none, margin=0, label=< + + + +
L4
LIii {Tint(0), Tint(1)} {Tint(4)}
CBR {Tint(4)} {L6, L5}
>]; +L4 -> L6 +L4 -> L5 +digraph Proc2 { +L0 [shape=none, margin=0, label=< + + + + +
L0
ADD {Upval(0, Proc%1, x), Upval(1, Proc%1, j)} {T(0)}
MOV {T(0)} {Upval(0, Proc%1, x)}
BR {L1}
>]; +L0 -> L1 +} +L5 [shape=none, margin=0, label=< + + + + + + +
L5
MOV {Tint(0)} {local(i, 1)}
MOV {local(i, 1)} {local(j, 2)}
CLOSURE {Proc%2} {T(0)}
CALL {T(0)} {T(0..)}
BR {L7}
>]; +L5 -> L7 +digraph Proc2 { +L0 [shape=none, margin=0, label=< + + + + +
L0
ADD {Upval(0, Proc%1, x), Upval(1, Proc%1, j)} {T(0)}
MOV {T(0)} {Upval(0, Proc%1, x)}
BR {L1}
>]; +L0 -> L1 +} +L6 [shape=none, margin=0, label=< + + + + + + +
L6
CLOSE {local(j, 2)}
LOADGLOBAL {print} {T(2)}
CALL {T(2), local(x, 0)} {T(2..)}
CLOSE {local(x, 0)}
BR {L1}
>]; +L6 -> L1 +digraph Proc2 { +L0 [shape=none, margin=0, label=< + + + + +
L0
ADD {Upval(0, Proc%1, x), Upval(1, Proc%1, j)} {T(0)}
MOV {T(0)} {Upval(0, Proc%1, x)}
BR {L1}
>]; +L0 -> L1 +} +L7 [shape=none, margin=0, label=< + + + +
L7
EQ {local(i, 1), 5 Kint(3)} {T(1)}
CBR {T(1)} {L8, L9}
>]; +L7 -> L8 +L7 -> L9 +digraph Proc2 { +L0 [shape=none, margin=0, label=< + + + + +
L0
ADD {Upval(0, Proc%1, x), Upval(1, Proc%1, j)} {T(0)}
MOV {T(0)} {Upval(0, Proc%1, x)}
BR {L1}
>]; +L0 -> L1 +} +L8 [shape=none, margin=0, label=< + + +
L8
BR {L6}
>]; +L8 -> L6 +digraph Proc2 { +L0 [shape=none, margin=0, label=< + + + + +
L0
ADD {Upval(0, Proc%1, x), Upval(1, Proc%1, j)} {T(0)}
MOV {T(0)} {Upval(0, Proc%1, x)}
BR {L1}
>]; +L0 -> L1 +} +L9 [shape=none, margin=0, label=< + + + +
L9
CLOSE {local(j, 2)}
BR {L2}
>]; +L9 -> L2 +digraph Proc2 { +L0 [shape=none, margin=0, label=< + + + + +
L0
ADD {Upval(0, Proc%1, x), Upval(1, Proc%1, j)} {T(0)}
MOV {T(0)} {Upval(0, Proc%1, x)}
BR {L1}
>]; +L0 -> L1 +} +L10 [shape=none, margin=0, label=< + + +
L10
BR {L9}
>]; +L10 -> L9 +digraph Proc2 { +L0 [shape=none, margin=0, label=< + + + + +
L0
ADD {Upval(0, Proc%1, x), Upval(1, Proc%1, j)} {T(0)}
MOV {T(0)} {Upval(0, Proc%1, x)}
BR {L1}
>]; +L0 -> L1 +} +} +function A(a) + local function B(b) + local function C(c) + return c + g + b + a + end + end +end + +function() + A --global symbol any + = + function( + a --local symbol any + ) + --locals a, B + local + --[symbols] + B --local symbol closure + --[expressions] + function( + b --local symbol any + ) + --locals b, C + --upvalues a + local + --[symbols] + C --local symbol closure + --[expressions] + function( + c --local symbol any + ) + --locals c + --upvalues b, a + return + --[binary expr start] any + --[binary expr start] any + --[binary expr start] any + --[suffixed expr start] any + --[primary start] any + c --local symbol any + --[primary end] + --[suffixed expr end] + + + --[suffixed expr start] any + --[primary start] any + g --global symbol any + --[primary end] + --[suffixed expr end] + --[binary expr end] + + + --[suffixed expr start] any + --[primary start] any + b --upvalue any + --[primary end] + --[suffixed expr end] + --[binary expr end] + + + --[suffixed expr start] any + --[primary start] any + a --upvalue any + --[primary end] + --[suffixed expr end] + --[binary expr end] + end + end + end +end +function() + A --global symbol any + = + function( + a --local symbol any + ) + --locals a, B + local + --[symbols] + B --local symbol closure + --[expressions] + function( + b --local symbol any + ) + --locals b, C + --upvalues a + local + --[symbols] + C --local symbol closure + --[expressions] + function( + c --local symbol any + ) + --locals c + --upvalues b, a + return + --[binary expr start] any + --[binary expr start] any + --[binary expr start] any + --[suffixed expr start] any + --[primary start] any + c --local symbol any + --[primary end] + --[suffixed expr end] + + + --[suffixed expr start] any + --[primary start] any + g --global symbol any + --[primary end] + --[suffixed expr end] + --[binary expr end] + + + --[suffixed expr start] any + --[primary start] any + b --upvalue any + --[primary end] + --[suffixed expr end] + --[binary expr end] + + + --[suffixed expr start] any + --[primary start] any + a --upvalue any + --[primary end] + --[suffixed expr end] + --[binary expr end] + end + end + end +end +define Proc%1 +L0 (entry) + CLOSURE {Proc%2} {T(1)} + STOREGLOBAL {A, T(1)} + BR {L1} +L1 (exit) +define Proc%2 +L0 (entry) + CLOSURE {Proc%3} {T(0)} + MOV {T(0)} {local(B, 1)} + CLOSE {local(a, 0)} + BR {L1} +L1 (exit) +define Proc%3 +L0 (entry) + CLOSURE {Proc%4} {T(0)} + MOV {T(0)} {local(C, 1)} + CLOSE {local(b, 0)} + BR {L1} +L1 (exit) +define Proc%4 +L0 (entry) + LOADGLOBAL {g} {T(0)} + ADD {local(c, 0), T(0)} {T(1)} + ADD {T(1), Upval(0, Proc%3, b)} {T(0)} + ADD {T(0), Upval(1, Proc%2, a)} {T(1)} + RET {T(1)} {L1} +L1 (exit) +digraph Proc1 { +L0 [shape=none, margin=0, label=< + + + + +
L0
CLOSURE {Proc%2} {T(1)}
STOREGLOBAL {A, T(1)}
BR {L1}
>]; +L0 -> L1 +digraph Proc2 { +L0 [shape=none, margin=0, label=< + + + + + +
L0
CLOSURE {Proc%3} {T(0)}
MOV {T(0)} {local(B, 1)}
CLOSE {local(a, 0)}
BR {L1}
>]; +L0 -> L1 +digraph Proc3 { +L0 [shape=none, margin=0, label=< + + + + + +
L0
CLOSURE {Proc%4} {T(0)}
MOV {T(0)} {local(C, 1)}
CLOSE {local(b, 0)}
BR {L1}
>]; +L0 -> L1 +digraph Proc4 { +L0 [shape=none, margin=0, label=< + + + + + + +
L0
LOADGLOBAL {g} {T(0)}
ADD {local(c, 0), T(0)} {T(1)}
ADD {T(1), Upval(0, Proc%3, b)} {T(0)}
ADD {T(0), Upval(1, Proc%2, a)} {T(1)}
RET {T(1)} {L1}
>]; +L0 -> L1 +} +digraph Proc4 { +L0 [shape=none, margin=0, label=< + + + + + + +
L0
LOADGLOBAL {g} {T(0)}
ADD {local(c, 0), T(0)} {T(1)}
ADD {T(1), Upval(0, Proc%3, b)} {T(0)}
ADD {T(0), Upval(1, Proc%2, a)} {T(1)}
RET {T(1)} {L1}
>]; +L0 -> L1 +} +} +digraph Proc3 { +L0 [shape=none, margin=0, label=< + + + + + +
L0
CLOSURE {Proc%4} {T(0)}
MOV {T(0)} {local(C, 1)}
CLOSE {local(b, 0)}
BR {L1}
>]; +L0 -> L1 +digraph Proc4 { +L0 [shape=none, margin=0, label=< + + + + + + +
L0
LOADGLOBAL {g} {T(0)}
ADD {local(c, 0), T(0)} {T(1)}
ADD {T(1), Upval(0, Proc%3, b)} {T(0)}
ADD {T(0), Upval(1, Proc%2, a)} {T(1)}
RET {T(1)} {L1}
>]; +L0 -> L1 +} +digraph Proc4 { +L0 [shape=none, margin=0, label=< + + + + + + +
L0
LOADGLOBAL {g} {T(0)}
ADD {local(c, 0), T(0)} {T(1)}
ADD {T(1), Upval(0, Proc%3, b)} {T(0)}
ADD {T(0), Upval(1, Proc%2, a)} {T(1)}
RET {T(1)} {L1}
>]; +L0 -> L1 +} +} +} +digraph Proc2 { +L0 [shape=none, margin=0, label=< + + + + + +
L0
CLOSURE {Proc%3} {T(0)}
MOV {T(0)} {local(B, 1)}
CLOSE {local(a, 0)}
BR {L1}
>]; +L0 -> L1 +digraph Proc3 { +L0 [shape=none, margin=0, label=< + + + + + +
L0
CLOSURE {Proc%4} {T(0)}
MOV {T(0)} {local(C, 1)}
CLOSE {local(b, 0)}
BR {L1}
>]; +L0 -> L1 +digraph Proc4 { +L0 [shape=none, margin=0, label=< + + + + + + +
L0
LOADGLOBAL {g} {T(0)}
ADD {local(c, 0), T(0)} {T(1)}
ADD {T(1), Upval(0, Proc%3, b)} {T(0)}
ADD {T(0), Upval(1, Proc%2, a)} {T(1)}
RET {T(1)} {L1}
>]; +L0 -> L1 +} +digraph Proc4 { +L0 [shape=none, margin=0, label=< + + + + + + +
L0
LOADGLOBAL {g} {T(0)}
ADD {local(c, 0), T(0)} {T(1)}
ADD {T(1), Upval(0, Proc%3, b)} {T(0)}
ADD {T(0), Upval(1, Proc%2, a)} {T(1)}
RET {T(1)} {L1}
>]; +L0 -> L1 +} +} +digraph Proc3 { +L0 [shape=none, margin=0, label=< + + + + + +
L0
CLOSURE {Proc%4} {T(0)}
MOV {T(0)} {local(C, 1)}
CLOSE {local(b, 0)}
BR {L1}
>]; +L0 -> L1 +digraph Proc4 { +L0 [shape=none, margin=0, label=< + + + + + + +
L0
LOADGLOBAL {g} {T(0)}
ADD {local(c, 0), T(0)} {T(1)}
ADD {T(1), Upval(0, Proc%3, b)} {T(0)}
ADD {T(0), Upval(1, Proc%2, a)} {T(1)}
RET {T(1)} {L1}
>]; +L0 -> L1 +} +digraph Proc4 { +L0 [shape=none, margin=0, label=< + + + + + + +
L0
LOADGLOBAL {g} {T(0)}
ADD {local(c, 0), T(0)} {T(1)}
ADD {T(1), Upval(0, Proc%3, b)} {T(0)}
ADD {T(0), Upval(1, Proc%2, a)} {T(1)}
RET {T(1)} {L1}
>]; +L0 -> L1 +} +} +} +} diff --git a/tests/input/t06_close.in b/tests/input/t06_close.in new file mode 100644 index 0000000..5e60551 --- /dev/null +++ b/tests/input/t06_close.in @@ -0,0 +1,34 @@ +# +local z, a do (function() a =1 end)() end +# +function add3(x) + return function (y) + return function (z) return x + y + z end + end +end +# +local a = {} +local x = 10 +for i = 1, 2 do + local j = i + a[i] = function() return x + j end +end +x = 20 +# +local x = 1 +do + for i = 1,10 do + local j = i; + (function () x = x + j end)() + if i == 5 then break end + end +end +print(x) +# +function A(a) + local function B(b) + local function C(c) + return c + g + b + a + end + end +end