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:
Nathan Braswell
2016-06-15 01:36:59 -07:00
parent acb0e48324
commit d44293a48b
9 changed files with 193 additions and 56 deletions

View File

@@ -688,6 +688,7 @@ obj c_generator (Object) {
return to_ret
}
fun generate_defer_statement(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node, defer_stack: *stack<pair<bool,stack<*ast_node>>>): code_triple {
error("Unremoved defer!")
defer_stack->top().second.push(node->defer_statement.statement)
return code_triple("/*defer wanna know what*/")
}

View File

@@ -9,66 +9,30 @@ import io:*
import ast_nodes:*
import ast_transformation:*
import pass_common:*
fun get_line(node: *tree<symbol>, name: string): *ast_node {
var to_ret = ast_simple_passthrough_ptr()
to_ret->simple_passthrough.passthrough_str = string("\n#line ") + get_first_terminal(node)->data.position + " \"" + name + "\"\n"
return to_ret
}
fun add_before_in(to_add: *ast_node, before: *ast_node, in: *ast_node) {
var bc = null<vector<*ast_node>>()
match(*in) {
ast_node::translation_unit(backing) bc = &in->translation_unit.children
ast_node::code_block(backing) bc = &in->code_block.children
}
if (bc) {
for (var i = 0; i < bc->size; i++;) {
if ((*bc)[i] == before) {
/*println("\nbefore\n")*/
/*(*bc).for_each(fun(n:*ast_node) println(get_ast_name(n));)*/
/*(*bc).for_each(fun(n:*ast_node) println(n);)*/
(*bc).add(to_add, i)
/*println("\nafter\n")*/
/*(*bc).for_each(fun(n:*ast_node) println(get_ast_name(n));)*/
/*(*bc).for_each(fun(n:*ast_node) println(n);)*/
/*println("\n")*/
return
}
}
}
error(string("cannot add_before_in to ") + get_ast_name(in))
}
fun c_line_control(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree<symbol>>) {
var first = true
name_ast_map->for_each(fun(name: string, syntax_ast_pair: pair<*tree<symbol>,*ast_node>) {
var helper: fun(*ast_node, *ast_node):void = fun(node: *ast_node, parent: *ast_node) {
if (!node) return
var helper_after = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {}
var helper = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {
match(*node) {
ast_node::translation_unit(backing) get_ast_children(node).for_each(fun(n: *ast_node) helper(n, node);)
ast_node::type_def(backing) {
/*println(string("adding ") + get_ast_name(node) + " to " + get_ast_name(parent))*/
/*add_before_in(get_line(), node, parent)*/
/*get_ast_children(node).for_each(fun(n: *ast_node) helper(n, node);)*/
}
ast_node::function(backing) get_ast_children(node).for_each(fun(n: *ast_node) helper(n, node);)
ast_node::code_block(backing) get_ast_children(node).for_each(fun(n: *ast_node) helper(n, node);)
ast_node::statement(backing) {
if (is_code_block(parent) && ast_to_syntax->contains_key(node)) {
if (is_code_block(parent_chain->top()) && ast_to_syntax->contains_key(node)) {
/*println(string("adding ") + get_ast_name(node) + " to " + get_ast_name(parent))*/
add_before_in(get_line(ast_to_syntax->get(node), name), node, parent)
add_before_in(get_line(ast_to_syntax->get(node), name), node, parent_chain->top())
}
get_ast_children(node).for_each(fun(n: *ast_node) helper(n, node);)
}
ast_node::if_statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) helper(n, node);)
ast_node::match_statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) helper(n, node);)
ast_node::case_statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) helper(n, node);)
ast_node::while_loop(backing) get_ast_children(node).for_each(fun(n: *ast_node) helper(n, node);)
ast_node::for_loop(backing) get_ast_children(node).for_each(fun(n: *ast_node) helper(n, node);)
}
}
if (first)
helper(syntax_ast_pair.second, null<ast_node>())
run_on_tree(helper, helper_after, syntax_ast_pair.second)
first = false
})
}

64
stdlib/defer_lower.krak Normal file
View 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)
})
}

94
stdlib/pass_common.krak Normal file
View File

@@ -0,0 +1,94 @@
import ast_nodes:*
import mem:*
import util:*
import vector:*
import stack:*
import string:*
fun get_children_pointer(node: *ast_node): *vector<*ast_node> {
var bc = null<vector<*ast_node>>()
match(*node) {
ast_node::translation_unit(backing) bc = &node->translation_unit.children
ast_node::code_block(backing) bc = &node->code_block.children
}
return bc
}
fun remove_full_statement(node: *ast_node, parent_chain: *stack<*ast_node>): *ast_node {
if (is_statement(node))
return remove(node, parent_chain)
if (is_statement(parent_chain->top()))
return remove(parent_chain->top(), parent_chain->from_top(1))
error(string("cannot remove full statement in ") + get_ast_name(parent_chain->top()))
}
fun remove(orig: *ast_node, in: *stack<*ast_node>): *ast_node
return remove(orig, in->top())
fun remove(orig: *ast_node, in: *ast_node): *ast_node {
var bc = get_children_pointer(in)
if (bc) {
var i = bc->find(orig)
if (i >= 0) {
var temp = bc->at(i)
bc->remove(i)
return temp
}
}
error(string("cannot remove inside ") + get_ast_name(in))
}
fun replace_with_in(orig: *ast_node, new: *ast_node, in: *stack<*ast_node>)
replace_with_in(orig, new, in->top())
fun replace_with_in(orig: *ast_node, new: *ast_node, in: *ast_node) {
if (is_statement(in)) {
in->statement.child = new
} else {
var bc = get_children_pointer(in)
if (bc) {
var i = bc->find(orig)
if (i >= 0) {
bc->set(i, new)
return
}
}
error(string("cannot replace_with_in inside ") + get_ast_name(in))
}
}
fun add_before_in(to_add: *ast_node, before: *ast_node, in: *stack<*ast_node>)
add_before_in(to_add, before, in->top())
fun add_before_in(to_add: *ast_node, before: *ast_node, in: *ast_node) {
var bc = get_children_pointer(in)
if (bc) {
var i = bc->find(before)
if (i >= 0) {
bc->add(to_add, i)
return
}
}
error(string("cannot add_before_in to ") + get_ast_name(in))
}
fun run_on_tree(func_before: fun(*ast_node,*stack<*ast_node>):void, func_after: fun(*ast_node,*stack<*ast_node>):void, tree: *ast_node) {
var parent_stack = stack<*ast_node>()
run_on_tree_helper(func_before, func_after, tree, &parent_stack)
}
fun run_on_tree_helper(func_before: fun(*ast_node,*stack<*ast_node>):void, func_after: fun(*ast_node,*stack<*ast_node>):void, node: *ast_node, parent_chain: *stack<*ast_node>) {
if (!node) return
func_before(node, parent_chain)
parent_chain->push(node)
match(*node) {
ast_node::translation_unit(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);)
ast_node::type_def(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);)
ast_node::function(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);)
ast_node::code_block(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);)
ast_node::statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);)
ast_node::if_statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);)
ast_node::match_statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);)
ast_node::case_statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);)
ast_node::while_loop(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);)
ast_node::for_loop(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain);)
}
parent_chain->pop()
func_after(node, parent_chain)
}

View File

@@ -71,4 +71,6 @@ obj stack<T> (Object, Serializable) {
fun for_each_reverse(func: fun(T):void) {
data.for_each_reverse(func)
}
fun reverse_vector(): vector::vector<T>
return data.reverse()
}