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

@@ -1,7 +1,7 @@
#!/bin/bash
kraken="kraken"
bootstrap_commits=(cf46fb13afe66ba475db9725e9269c9c1cd3bbc3 2cd43e5a217318c70097334b3598d2924f64b362 2051f54b559ac5edf67277d4f1134aca2cb9215d ecbbcb4eda56e2467efb0a04e7d668b95856aa4b d126cbf24ba8b26e3814e2260d555ecaee86508c 947384cced5397a517a71963edc8f47e668d734f cfcaff7887a804fe77dadaf2ebb0251d6e8ae8e2 12dfa837e31bf09adb1335219473b9a7e6db9eac)
bootstrap_commits=(cf46fb13afe66ba475db9725e9269c9c1cd3bbc3 2cd43e5a217318c70097334b3598d2924f64b362 2051f54b559ac5edf67277d4f1134aca2cb9215d ecbbcb4eda56e2467efb0a04e7d668b95856aa4b d126cbf24ba8b26e3814e2260d555ecaee86508c 947384cced5397a517a71963edc8f47e668d734f cfcaff7887a804fe77dadaf2ebb0251d6e8ae8e2 12dfa837e31bf09adb1335219473b9a7e6db9eac acb0e48324f353d30d148eb11d1bf2843d83b51a)
# Echo version string to a file included by kraken.krak

View File

@@ -1,16 +1,17 @@
import io:*
import grammer:*
import parser:*
import ast_transformation:*
import string:*
import util:*
import symbol:*
import tree:*
import serialize:*
import c_generator:*
import c_line_control:*
import interpreter:*
import os:*
import ast_transformation:*
import defer_lower:*
import c_line_control:*
import c_generator:*
import compiler_version
@@ -97,6 +98,9 @@ fun main(argc: int, argv: **char):int {
/*var parsers = vector(parse1,parse2,parse3,parse4,parse5,parse6,parse7,parse8)*/
var importer.construct(parsers, ast_pass, vector(string(), base_dir + "/stdlib/")): importer
importer.import(kraken_file_name)
// Passes
printlnerr("Lowering Defer")
defer_lower(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax)
if (interpret_instead) {
printlnerr("Interpreting!")
var interpret.construct(importer.name_ast_map, importer.ast_pass.ast_to_syntax): interpreter

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()
}

View File

@@ -7,10 +7,11 @@ happens every time, even when breaking or continueing
5
happens every time, even when breaking or continueing
happens every time, even when breaking or continueing
7
only happens once before breaking 7
happens every time, even when breaking or continueing
happens every time, even when breaking or continueing
happens every time, even when breaking or continueing
block outside for
first
last
deferred

View File

@@ -1,14 +1,21 @@
import io:*
fun main():int {
for (var i = 1; i < 10; i++;) {
{
defer println("happens every time, even when breaking or continueing")
if (i % 2 == 0)
continue
if (i == 9)
break
println(i)
{
defer println("block outside for")
for (var i = 1; i < 10; i++;) {
{
defer println("happens every time, even when breaking or continueing")
if (i % 2 == 0)
continue
if (i == 9)
break
if (i == 7) {
defer println("only happens once before breaking 7")
continue
}
println(i)
}
}
}
{