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:
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
kraken="kraken"
|
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
|
# Echo version string to a file included by kraken.krak
|
||||||
|
|||||||
10
kraken.krak
10
kraken.krak
@@ -1,16 +1,17 @@
|
|||||||
import io:*
|
import io:*
|
||||||
import grammer:*
|
import grammer:*
|
||||||
import parser:*
|
import parser:*
|
||||||
import ast_transformation:*
|
|
||||||
import string:*
|
import string:*
|
||||||
import util:*
|
import util:*
|
||||||
import symbol:*
|
import symbol:*
|
||||||
import tree:*
|
import tree:*
|
||||||
import serialize:*
|
import serialize:*
|
||||||
import c_generator:*
|
|
||||||
import c_line_control:*
|
|
||||||
import interpreter:*
|
import interpreter:*
|
||||||
import os:*
|
import os:*
|
||||||
|
import ast_transformation:*
|
||||||
|
import defer_lower:*
|
||||||
|
import c_line_control:*
|
||||||
|
import c_generator:*
|
||||||
import compiler_version
|
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 parsers = vector(parse1,parse2,parse3,parse4,parse5,parse6,parse7,parse8)*/
|
||||||
var importer.construct(parsers, ast_pass, vector(string(), base_dir + "/stdlib/")): importer
|
var importer.construct(parsers, ast_pass, vector(string(), base_dir + "/stdlib/")): importer
|
||||||
importer.import(kraken_file_name)
|
importer.import(kraken_file_name)
|
||||||
|
// Passes
|
||||||
|
printlnerr("Lowering Defer")
|
||||||
|
defer_lower(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax)
|
||||||
if (interpret_instead) {
|
if (interpret_instead) {
|
||||||
printlnerr("Interpreting!")
|
printlnerr("Interpreting!")
|
||||||
var interpret.construct(importer.name_ast_map, importer.ast_pass.ast_to_syntax): interpreter
|
var interpret.construct(importer.name_ast_map, importer.ast_pass.ast_to_syntax): interpreter
|
||||||
|
|||||||
@@ -688,6 +688,7 @@ obj c_generator (Object) {
|
|||||||
return to_ret
|
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 {
|
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)
|
defer_stack->top().second.push(node->defer_statement.statement)
|
||||||
return code_triple("/*defer wanna know what*/")
|
return code_triple("/*defer wanna know what*/")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,66 +9,30 @@ import io:*
|
|||||||
import ast_nodes:*
|
import ast_nodes:*
|
||||||
import ast_transformation:*
|
import ast_transformation:*
|
||||||
|
|
||||||
|
import pass_common:*
|
||||||
|
|
||||||
fun get_line(node: *tree<symbol>, name: string): *ast_node {
|
fun get_line(node: *tree<symbol>, name: string): *ast_node {
|
||||||
var to_ret = ast_simple_passthrough_ptr()
|
var to_ret = ast_simple_passthrough_ptr()
|
||||||
to_ret->simple_passthrough.passthrough_str = string("\n#line ") + get_first_terminal(node)->data.position + " \"" + name + "\"\n"
|
to_ret->simple_passthrough.passthrough_str = string("\n#line ") + get_first_terminal(node)->data.position + " \"" + name + "\"\n"
|
||||||
return to_ret
|
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>>) {
|
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
|
var first = true
|
||||||
name_ast_map->for_each(fun(name: string, syntax_ast_pair: pair<*tree<symbol>,*ast_node>) {
|
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) {
|
var helper_after = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {}
|
||||||
if (!node) return
|
var helper = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {
|
||||||
match(*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) {
|
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))*/
|
/*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)
|
if (first)
|
||||||
helper(syntax_ast_pair.second, null<ast_node>())
|
run_on_tree(helper, helper_after, syntax_ast_pair.second)
|
||||||
first = false
|
first = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
94
stdlib/pass_common.krak
Normal file
94
stdlib/pass_common.krak
Normal 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)
|
||||||
|
}
|
||||||
|
|
||||||
@@ -71,4 +71,6 @@ obj stack<T> (Object, Serializable) {
|
|||||||
fun for_each_reverse(func: fun(T):void) {
|
fun for_each_reverse(func: fun(T):void) {
|
||||||
data.for_each_reverse(func)
|
data.for_each_reverse(func)
|
||||||
}
|
}
|
||||||
|
fun reverse_vector(): vector::vector<T>
|
||||||
|
return data.reverse()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,10 +7,11 @@ happens every time, even when breaking or continueing
|
|||||||
5
|
5
|
||||||
happens every time, even when breaking or continueing
|
happens every time, even when breaking or continueing
|
||||||
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
|
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
|
first
|
||||||
last
|
last
|
||||||
deferred
|
deferred
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import io:*
|
import io:*
|
||||||
|
|
||||||
fun main():int {
|
fun main():int {
|
||||||
|
{
|
||||||
|
defer println("block outside for")
|
||||||
for (var i = 1; i < 10; i++;) {
|
for (var i = 1; i < 10; i++;) {
|
||||||
{
|
{
|
||||||
defer println("happens every time, even when breaking or continueing")
|
defer println("happens every time, even when breaking or continueing")
|
||||||
@@ -8,9 +10,14 @@ fun main():int {
|
|||||||
continue
|
continue
|
||||||
if (i == 9)
|
if (i == 9)
|
||||||
break
|
break
|
||||||
|
if (i == 7) {
|
||||||
|
defer println("only happens once before breaking 7")
|
||||||
|
continue
|
||||||
|
}
|
||||||
println(i)
|
println(i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
{
|
{
|
||||||
println("first")
|
println("first")
|
||||||
defer println("deferred")
|
defer println("deferred")
|
||||||
|
|||||||
Reference in New Issue
Block a user