Defer is now lowered in its own pass as a first step towards refactoring other things into their own passes as well
This commit is contained in:
64
stdlib/defer_lower.krak
Normal file
64
stdlib/defer_lower.krak
Normal file
@@ -0,0 +1,64 @@
|
||||
import symbol:*
|
||||
import tree:*
|
||||
import vector:*
|
||||
import map:*
|
||||
import util:*
|
||||
import string:*
|
||||
import mem:*
|
||||
import io:*
|
||||
import ast_nodes:*
|
||||
import ast_transformation:*
|
||||
|
||||
import pass_common:*
|
||||
|
||||
fun defer_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree<symbol>>) {
|
||||
name_ast_map->for_each(fun(name: string, syntax_ast_pair: pair<*tree<symbol>,*ast_node>) {
|
||||
var defer_double_stack = stack<stack<*ast_node>>()
|
||||
var loop_stack = stack(-1)
|
||||
var helper_before = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {
|
||||
match(*node) {
|
||||
ast_node::defer_statement(backing) {
|
||||
if (is_code_block(parent_chain->top()) || (is_statement(parent_chain->top()) && is_code_block(parent_chain->from_top(1)))) {
|
||||
/*println("defer in codeblock, gonna add at the end")*/
|
||||
remove_full_statement(node, parent_chain)
|
||||
defer_double_stack.top().push(backing.statement)
|
||||
} else {
|
||||
/*println("defer not in codeblock, so just removing defer part")*/
|
||||
replace_with_in(node, backing.statement, parent_chain)
|
||||
}
|
||||
}
|
||||
ast_node::code_block(backing) {
|
||||
defer_double_stack.push(stack<*ast_node>())
|
||||
}
|
||||
ast_node::for_loop(backing) {
|
||||
loop_stack.push(defer_double_stack.size())
|
||||
}
|
||||
ast_node::while_loop(backing) {
|
||||
loop_stack.push(defer_double_stack.size())
|
||||
}
|
||||
}
|
||||
}
|
||||
var helper_after = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {
|
||||
match(*node) {
|
||||
ast_node::branching_statement(backing) {
|
||||
var block = ast_code_block_ptr()
|
||||
replace_with_in(node, block, parent_chain)
|
||||
for (var i = 0; i < defer_double_stack.size() - loop_stack.top(); i++;)
|
||||
block->code_block.children.add_all(defer_double_stack.from_top(i).reverse_vector())
|
||||
block->code_block.children.add(ast_statement_ptr(node))
|
||||
}
|
||||
ast_node::code_block(backing) {
|
||||
node->code_block.children.add_all(defer_double_stack.pop().reverse_vector())
|
||||
}
|
||||
ast_node::for_loop(backing) {
|
||||
loop_stack.pop()
|
||||
}
|
||||
ast_node::while_loop(backing) {
|
||||
loop_stack.pop()
|
||||
}
|
||||
}
|
||||
}
|
||||
run_on_tree(helper_before, helper_after, syntax_ast_pair.second)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user