2016-06-15 01:36:59 -07:00
|
|
|
import symbol:*
|
|
|
|
|
import tree:*
|
2018-05-22 19:43:54 -04:00
|
|
|
import vec:*
|
2016-06-15 01:36:59 -07:00
|
|
|
import map:*
|
|
|
|
|
import util:*
|
2018-05-22 19:43:54 -04:00
|
|
|
import str:*
|
2016-06-15 01:36:59 -07:00
|
|
|
import mem:*
|
|
|
|
|
import io:*
|
|
|
|
|
import ast_nodes:*
|
|
|
|
|
import ast_transformation:*
|
2017-01-22 10:13:06 -05:00
|
|
|
import hash_set:*
|
2016-06-15 01:36:59 -07:00
|
|
|
|
|
|
|
|
import pass_common:*
|
|
|
|
|
|
2018-05-22 19:43:54 -04:00
|
|
|
fun defer_lower(name_ast_map: *map<str, pair<*tree<symbol>,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree<symbol>>) {
|
2017-01-22 10:13:06 -05:00
|
|
|
var visited = hash_set<*ast_node>()
|
2018-05-22 19:43:54 -04:00
|
|
|
name_ast_map->for_each(fun(name: str, syntax_ast_pair: pair<*tree<symbol>,*ast_node>) {
|
2017-01-21 22:01:47 -05:00
|
|
|
var defer_triple_stack = stack<stack<stack<*ast_node>>>()
|
2016-06-15 01:36:59 -07:00
|
|
|
var loop_stack = stack(-1)
|
|
|
|
|
var helper_before = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {
|
|
|
|
|
match(*node) {
|
|
|
|
|
ast_node::defer_statement(backing) {
|
2016-07-03 22:50:42 -07:00
|
|
|
if (is_code_block(parent_chain->top())) {
|
|
|
|
|
remove(node, parent_chain)
|
2017-01-21 22:01:47 -05:00
|
|
|
defer_triple_stack.top().top().push(backing.statement)
|
2016-06-15 01:36:59 -07:00
|
|
|
} else {
|
|
|
|
|
replace_with_in(node, backing.statement, parent_chain)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ast_node::code_block(backing) {
|
2017-01-21 22:01:47 -05:00
|
|
|
defer_triple_stack.top().push(stack<*ast_node>())
|
2016-06-15 01:36:59 -07:00
|
|
|
}
|
|
|
|
|
ast_node::for_loop(backing) {
|
2017-01-21 22:01:47 -05:00
|
|
|
loop_stack.push(defer_triple_stack.top().size())
|
2016-06-15 01:36:59 -07:00
|
|
|
}
|
|
|
|
|
ast_node::while_loop(backing) {
|
2017-01-21 22:01:47 -05:00
|
|
|
loop_stack.push(defer_triple_stack.top().size())
|
2016-06-15 01:36:59 -07:00
|
|
|
}
|
2016-06-22 01:41:57 -07:00
|
|
|
ast_node::function(backing) {
|
2017-01-21 22:01:47 -05:00
|
|
|
defer_triple_stack.push(stack<stack<*ast_node>>())
|
2016-06-22 01:41:57 -07:00
|
|
|
}
|
2016-06-15 01:36:59 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
var helper_after = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {
|
|
|
|
|
match(*node) {
|
|
|
|
|
ast_node::branching_statement(backing) {
|
2018-05-22 20:14:15 -04:00
|
|
|
var block = _code_block()
|
2017-11-03 00:39:58 -04:00
|
|
|
add_to_scope("~enclosing_scope", parent_chain->item_from_top_satisfying(fun(i: *ast_node): bool return is_code_block(i) || is_function(i);), block)
|
2016-06-15 01:36:59 -07:00
|
|
|
replace_with_in(node, block, parent_chain)
|
2017-01-21 22:01:47 -05:00
|
|
|
for (var i = 0; i < defer_triple_stack.top().size() - loop_stack.top(); i++;)
|
|
|
|
|
block->code_block.children.add_all(defer_triple_stack.top().from_top(i).reverse_vector())
|
2016-07-03 22:50:42 -07:00
|
|
|
block->code_block.children.add(node)
|
2016-06-15 01:36:59 -07:00
|
|
|
}
|
2016-06-22 01:41:57 -07:00
|
|
|
ast_node::return_statement(backing) {
|
2017-11-03 00:39:58 -04:00
|
|
|
var block = parent_chain->top()
|
|
|
|
|
if (!is_code_block(block))
|
|
|
|
|
error("defer doesn't have block - it should from obj lower")
|
|
|
|
|
for (var i = 0; i < defer_triple_stack.top().size(); i++;) {
|
|
|
|
|
defer_triple_stack.top().from_top(i).reverse_vector().for_each(fun(c: *ast_node) {
|
|
|
|
|
add_before_in(c, node, block)
|
|
|
|
|
})
|
2016-06-22 01:41:57 -07:00
|
|
|
}
|
|
|
|
|
}
|
2016-06-15 01:36:59 -07:00
|
|
|
ast_node::code_block(backing) {
|
2017-01-21 22:01:47 -05:00
|
|
|
node->code_block.children.add_all(defer_triple_stack.top().pop().reverse_vector())
|
2016-06-15 01:36:59 -07:00
|
|
|
}
|
|
|
|
|
ast_node::for_loop(backing) {
|
|
|
|
|
loop_stack.pop()
|
|
|
|
|
}
|
|
|
|
|
ast_node::while_loop(backing) {
|
|
|
|
|
loop_stack.pop()
|
|
|
|
|
}
|
2017-01-21 22:01:47 -05:00
|
|
|
ast_node::function(backing) {
|
|
|
|
|
defer_triple_stack.pop()
|
|
|
|
|
}
|
2016-06-15 01:36:59 -07:00
|
|
|
}
|
|
|
|
|
}
|
2017-01-20 01:11:06 -05:00
|
|
|
run_on_tree(helper_before, helper_after, syntax_ast_pair.second, &visited)
|
2016-06-15 01:36:59 -07:00
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|