From 06df819e7260f6e9a61d44648be9324c9f6dd6b6 Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Sat, 29 Dec 2018 20:58:34 -0500 Subject: [PATCH] Port (though ineffecently) defer_lower! --- k.krak | 79 ++++++++++++++++++++++++++++++++++++++++++++++-- stdlib/tree.krak | 9 ++++++ 2 files changed, 85 insertions(+), 3 deletions(-) diff --git a/k.krak b/k.krak index ac3132b..bc6bea3 100644 --- a/k.krak +++ b/k.krak @@ -6,6 +6,7 @@ import str:* import serialize:* import os:* import set:* +import stack:* import vec:* import vec_literals:* import poset:* @@ -356,7 +357,6 @@ fun main(argc: int, argv: **char): int { } else { t = get_type(bound_to) } - /*var t = get_type(get_ast_binding(a))*/ binding_types[a] = t return t } else { @@ -992,6 +992,79 @@ fun main(argc: int, argv: **char): int { resolve(item) } + passes[str("defer_lower")] = fun(item: *tree) { + if !pass_poset.done(make_pair(item, str("depend_and_template_resolve"))) { + pass_poset.add_open_dep(make_pair(item, str("defer_lower")), make_pair(item, str("depend_and_template_resolve"))) + return + } + var defer_triple_stack = stack>>>() + var loop_stack = stack(-1) + var traverse_for_defer: fun(*tree): void = fun(t: *tree) { + match (t->data) { + ast::_defer() { + if (is_block(t->parent)) { + t->parent->remove_child(t) + defer_triple_stack.top().top().push(t->children[0]) + } else { + t->parent->replace_child(t, t->children[0]) + } + traverse_for_defer(t->children[0]) + return; + } + ast::_function(name_type_ext) { + defer_triple_stack.push(stack>>()) + t->children.clone().for_each(traverse_for_defer) + defer_triple_stack.pop() + return; + } + ast::_block() { + defer_triple_stack.top().push(stack<*tree>()) + t->children.clone().for_each(traverse_for_defer) + t->children.add_all(defer_triple_stack.top().pop().reverse_vector()) + return; + } + ast::_for() { + loop_stack.push(defer_triple_stack.top().size()) + t->children.clone().for_each(traverse_for_defer) + loop_stack.pop() + return; + } + ast::_while() { + loop_stack.push(defer_triple_stack.top().size()) + t->children.clone().for_each(traverse_for_defer) + loop_stack.pop() + return; + } + ast::_return() { + t->children.clone().for_each(traverse_for_defer) + var our_idx = t->parent->children.find(t) + for (var i = 0; i < defer_triple_stack.top().size(); i++;) { + defer_triple_stack.top().from_top(i).reverse_vector().for_each(fun(c: *tree) { + t->parent->children.add(our_idx, c) + }) + } + return; + } + ast::_break() { + var block = _block() + t->parent->replace_child(t, block) + for (var i = 0; i < defer_triple_stack.top().size() - loop_stack.top(); i++;) + block->add_children(defer_triple_stack.top().from_top(i).reverse_vector()) + block->add_child(t) + return; + } + ast::_continue() { + return; + } + } + t->children.clone().for_each(traverse_for_defer) + } + traverse_for_defer(item) + + println("post defer_lower") + print_tree(item, 1) + } + // emit C var C_str = str() var C_type_forward_declaration_str = str() @@ -1000,8 +1073,8 @@ fun main(argc: int, argv: **char): int { var C_declaration_str = str() passes[str("emit_C")] = fun(item: *tree) { - if !pass_poset.done(make_pair(item, str("depend_and_template_resolve"))) { - pass_poset.add_open_dep(make_pair(item, str("emit_C")), make_pair(item, str("depend_and_template_resolve"))) + if !pass_poset.done(make_pair(item, str("defer_lower"))) { + pass_poset.add_open_dep(make_pair(item, str("emit_C")), make_pair(item, str("defer_lower"))) return } println("Emitting C for:") diff --git a/stdlib/tree.krak b/stdlib/tree.krak index 724bdaa..76af518 100644 --- a/stdlib/tree.krak +++ b/stdlib/tree.krak @@ -43,6 +43,12 @@ obj tree (Object) { children.add(c) c->parent = this } + fun add_children(c: vec::vec<*tree>) { + for (var i = 0; i < c.size; i++;) { + children.add(c[i]) + c[i]->parent = this + } + } fun set_child(i: int, c: *tree) { children[i] = c c->parent = this @@ -51,6 +57,9 @@ obj tree (Object) { children[children.find(old_c)] = new_c new_c->parent = this } + fun remove_child(old_c: *tree) { + children.remove(children.find(old_c)) + } fun clone(): *tree { return mem::new>()->construct(data, children.map(fun(c: *tree): *tree return c->clone();)) }