Merge branch 'ref_lower'
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -26,3 +26,4 @@ kraken_deprecated
|
|||||||
bootstrap_kalypso
|
bootstrap_kalypso
|
||||||
kraken_bootstrap
|
kraken_bootstrap
|
||||||
compiler_version.krak
|
compiler_version.krak
|
||||||
|
untracked_misc
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import ast_transformation:*
|
|||||||
import adt_lower:*
|
import adt_lower:*
|
||||||
import obj_lower:*
|
import obj_lower:*
|
||||||
import defer_lower:*
|
import defer_lower:*
|
||||||
|
import ref_lower:*
|
||||||
import ctce_lower:*
|
import ctce_lower:*
|
||||||
import c_line_control:*
|
import c_line_control:*
|
||||||
import node_counter:*
|
import node_counter:*
|
||||||
@@ -148,6 +149,10 @@ fun main(argc: int, argv: **char):int {
|
|||||||
defer_lower(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax)
|
defer_lower(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax)
|
||||||
/*printlnerr("Counting Nodes")*/
|
/*printlnerr("Counting Nodes")*/
|
||||||
/*node_counter(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax)*/
|
/*node_counter(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax)*/
|
||||||
|
printlnerr("Lowering Ref")
|
||||||
|
ref_lower(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax)
|
||||||
|
/*printlnerr("Counting Nodes")*/
|
||||||
|
/*node_counter(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax)*/
|
||||||
// Lowers #ctce and the current #ctce_pass
|
// Lowers #ctce and the current #ctce_pass
|
||||||
printlnerr("Lowering CTCE")
|
printlnerr("Lowering CTCE")
|
||||||
ctce_lower(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax)
|
ctce_lower(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax)
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import pass_common:*
|
|||||||
|
|
||||||
fun adt_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree<symbol>>) {
|
fun adt_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree<symbol>>) {
|
||||||
var type_def_option_map = map<*ast_node, vector<*ast_node>>()
|
var type_def_option_map = map<*ast_node, vector<*ast_node>>()
|
||||||
|
var visited1 = set<*ast_node>()
|
||||||
|
var visited2 = set<*ast_node>()
|
||||||
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_before = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {
|
var helper_before = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {
|
||||||
match(*node) {
|
match(*node) {
|
||||||
@@ -129,7 +131,7 @@ fun adt_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
run_on_tree(helper_before, empty_pass_second_half, syntax_ast_pair.second)
|
run_on_tree(helper_before, empty_pass_second_half, syntax_ast_pair.second, &visited1)
|
||||||
})
|
})
|
||||||
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 second_helper = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {
|
var second_helper = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {
|
||||||
@@ -182,7 +184,7 @@ fun adt_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
run_on_tree(second_helper, empty_pass_second_half, syntax_ast_pair.second)
|
run_on_tree(second_helper, empty_pass_second_half, syntax_ast_pair.second, &visited2)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -991,6 +991,7 @@ obj ast_transformation (Object) {
|
|||||||
}
|
}
|
||||||
parameters = vector(first_param, second_param)
|
parameters = vector(first_param, second_param)
|
||||||
}
|
}
|
||||||
|
parameters.for_each(fun(param: *ast_node) if (!is_legal_parameter_node_type(param)) error(node, "illegal node type used as parameter (perhaps name resolves to type or translation unit?)");)
|
||||||
var parameter_types = parameters.map(fun(param: *ast_node): *type return get_ast_type(param);)
|
var parameter_types = parameters.map(fun(param: *ast_node): *type return get_ast_type(param);)
|
||||||
// check for operator overloading
|
// check for operator overloading
|
||||||
var possible_overload_call = find_and_make_any_operator_overload_call(func_name, parameters, scope, template_replacements)
|
var possible_overload_call = find_and_make_any_operator_overload_call(func_name, parameters, scope, template_replacements)
|
||||||
|
|||||||
@@ -436,6 +436,7 @@ obj c_generator (Object) {
|
|||||||
if (enclosing_func && enclosing_func->function.closed_variables.contains(node))
|
if (enclosing_func && enclosing_func->function.closed_variables.contains(node))
|
||||||
return code_triple(pre + string("(*(closure_data->") + get_name(node) + "))" + post)
|
return code_triple(pre + string("(*(closure_data->") + get_name(node) + "))" + post)
|
||||||
else if (get_ast_type(node)->is_ref) {
|
else if (get_ast_type(node)->is_ref) {
|
||||||
|
error("still existin ref in identifier")
|
||||||
pre += "(*"
|
pre += "(*"
|
||||||
post += ")"
|
post += ")"
|
||||||
}
|
}
|
||||||
@@ -454,7 +455,8 @@ obj c_generator (Object) {
|
|||||||
to_ret += "return"
|
to_ret += "return"
|
||||||
var refamp = string()
|
var refamp = string()
|
||||||
if (function_return_type->is_ref)
|
if (function_return_type->is_ref)
|
||||||
refamp = "&"
|
error("still exsisting ref in return")
|
||||||
|
/*refamp = "&"*/
|
||||||
if (return_value)
|
if (return_value)
|
||||||
to_ret += code_triple(" ") + refamp + generate(return_value, enclosing_object, enclosing_func, false)
|
to_ret += code_triple(" ") + refamp + generate(return_value, enclosing_object, enclosing_func, false)
|
||||||
return to_ret
|
return to_ret
|
||||||
@@ -611,8 +613,12 @@ obj c_generator (Object) {
|
|||||||
if (call_string != "")
|
if (call_string != "")
|
||||||
call_string += ", "
|
call_string += ", "
|
||||||
|
|
||||||
if (in_function_param_type->is_ref)
|
if (in_function_param_type->is_ref) {
|
||||||
call_string += "&"
|
/*for (var n = node->function_call.func; n; get_from_scope(n, "~enclosing_scope"))) {*/
|
||||||
|
/*}*/
|
||||||
|
error(string("problem :") + (node->function_call.func) cast int + " " + get_fully_scoped_name(node->function_call.func) + ": still ref in function calling, func_type: " + func_type->to_string())
|
||||||
|
}
|
||||||
|
/*call_string += "&"*/
|
||||||
|
|
||||||
var param_type = get_ast_type(param)
|
var param_type = get_ast_type(param)
|
||||||
call_string += generate(param, enclosing_object, enclosing_func, in_function_param_type->is_ref)
|
call_string += generate(param, enclosing_object, enclosing_func, in_function_param_type->is_ref)
|
||||||
@@ -630,6 +636,7 @@ obj c_generator (Object) {
|
|||||||
var ref_pre = string()
|
var ref_pre = string()
|
||||||
var ref_post = string()
|
var ref_post = string()
|
||||||
if (func_return_type->is_ref) {
|
if (func_return_type->is_ref) {
|
||||||
|
error("still ref in function calling")
|
||||||
ref_pre += "(*"
|
ref_pre += "(*"
|
||||||
ref_post += ")"
|
ref_post += ")"
|
||||||
}
|
}
|
||||||
@@ -722,7 +729,7 @@ obj c_generator (Object) {
|
|||||||
}
|
}
|
||||||
fun type_decoration(type: *type): string {
|
fun type_decoration(type: *type): string {
|
||||||
var indirection = string()
|
var indirection = string()
|
||||||
if (type->is_ref) indirection += "ref_"
|
if (type->is_ref) error("still ref in type decoration") //indirection += "ref_"
|
||||||
for (var i = 0; i < type->indirection; i++;) indirection += "p"
|
for (var i = 0; i < type->indirection; i++;) indirection += "p"
|
||||||
if (type->indirection) indirection += "_"
|
if (type->indirection) indirection += "_"
|
||||||
match (type->base) {
|
match (type->base) {
|
||||||
@@ -752,7 +759,7 @@ obj c_generator (Object) {
|
|||||||
}
|
}
|
||||||
fun type_to_c(type: *type): string {
|
fun type_to_c(type: *type): string {
|
||||||
var indirection = string()
|
var indirection = string()
|
||||||
if (type->is_ref) indirection += "/*ref*/ *"
|
if (type->is_ref) error("still ref in type_to_c") //indirection += "/*ref*/ *"
|
||||||
for (var i = 0; i < type->indirection; i++;) indirection += "*"
|
for (var i = 0; i < type->indirection; i++;) indirection += "*"
|
||||||
match (type->base) {
|
match (type->base) {
|
||||||
base_type::none() return string("none") + indirection
|
base_type::none() return string("none") + indirection
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import interpreter:*
|
|||||||
import pass_common:*
|
import pass_common:*
|
||||||
|
|
||||||
fun ctce_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree<symbol>>) {
|
fun ctce_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree<symbol>>) {
|
||||||
|
var visited = set<*ast_node>()
|
||||||
var globals = setup_globals(*name_ast_map)
|
var globals = setup_globals(*name_ast_map)
|
||||||
var ctce_passes = vector<*ast_node>()
|
var ctce_passes = vector<*ast_node>()
|
||||||
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>) {
|
||||||
@@ -29,7 +30,7 @@ fun ctce_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
run_on_tree(helper_before, empty_pass_second_half, syntax_ast_pair.second)
|
run_on_tree(helper_before, empty_pass_second_half, syntax_ast_pair.second, &visited)
|
||||||
})
|
})
|
||||||
ctce_passes.for_each(fun(func: *ast_node) {
|
ctce_passes.for_each(fun(func: *ast_node) {
|
||||||
// don't want to pick up the ast_node::value
|
// don't want to pick up the ast_node::value
|
||||||
|
|||||||
@@ -12,31 +12,33 @@ import ast_transformation:*
|
|||||||
import pass_common:*
|
import pass_common:*
|
||||||
|
|
||||||
fun defer_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree<symbol>>) {
|
fun defer_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree<symbol>>) {
|
||||||
var enclosing_function = null<ast_node>()
|
var enclosing_function_stack = stack<*ast_node>()
|
||||||
|
var visited = set<*ast_node>()
|
||||||
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 defer_double_stack = stack<stack<*ast_node>>()
|
var defer_triple_stack = stack<stack<stack<*ast_node>>>()
|
||||||
var loop_stack = stack(-1)
|
var loop_stack = stack(-1)
|
||||||
var helper_before = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {
|
var helper_before = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {
|
||||||
match(*node) {
|
match(*node) {
|
||||||
ast_node::defer_statement(backing) {
|
ast_node::defer_statement(backing) {
|
||||||
if (is_code_block(parent_chain->top())) {
|
if (is_code_block(parent_chain->top())) {
|
||||||
remove(node, parent_chain)
|
remove(node, parent_chain)
|
||||||
defer_double_stack.top().push(backing.statement)
|
defer_triple_stack.top().top().push(backing.statement)
|
||||||
} else {
|
} else {
|
||||||
replace_with_in(node, backing.statement, parent_chain)
|
replace_with_in(node, backing.statement, parent_chain)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast_node::code_block(backing) {
|
ast_node::code_block(backing) {
|
||||||
defer_double_stack.push(stack<*ast_node>())
|
defer_triple_stack.top().push(stack<*ast_node>())
|
||||||
}
|
}
|
||||||
ast_node::for_loop(backing) {
|
ast_node::for_loop(backing) {
|
||||||
loop_stack.push(defer_double_stack.size())
|
loop_stack.push(defer_triple_stack.top().size())
|
||||||
}
|
}
|
||||||
ast_node::while_loop(backing) {
|
ast_node::while_loop(backing) {
|
||||||
loop_stack.push(defer_double_stack.size())
|
loop_stack.push(defer_triple_stack.top().size())
|
||||||
}
|
}
|
||||||
ast_node::function(backing) {
|
ast_node::function(backing) {
|
||||||
enclosing_function = node
|
enclosing_function_stack.push(node)
|
||||||
|
defer_triple_stack.push(stack<stack<*ast_node>>())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -45,8 +47,8 @@ fun defer_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_t
|
|||||||
ast_node::branching_statement(backing) {
|
ast_node::branching_statement(backing) {
|
||||||
var block = ast_code_block_ptr()
|
var block = ast_code_block_ptr()
|
||||||
replace_with_in(node, block, parent_chain)
|
replace_with_in(node, block, parent_chain)
|
||||||
for (var i = 0; i < defer_double_stack.size() - loop_stack.top(); i++;)
|
for (var i = 0; i < defer_triple_stack.top().size() - loop_stack.top(); i++;)
|
||||||
block->code_block.children.add_all(defer_double_stack.from_top(i).reverse_vector())
|
block->code_block.children.add_all(defer_triple_stack.top().from_top(i).reverse_vector())
|
||||||
block->code_block.children.add(node)
|
block->code_block.children.add(node)
|
||||||
}
|
}
|
||||||
ast_node::return_statement(backing) {
|
ast_node::return_statement(backing) {
|
||||||
@@ -54,22 +56,22 @@ fun defer_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_t
|
|||||||
replace_with_in(node, block, parent_chain)
|
replace_with_in(node, block, parent_chain)
|
||||||
var return_value = node->return_statement.return_value
|
var return_value = node->return_statement.return_value
|
||||||
if (return_value) {
|
if (return_value) {
|
||||||
if (get_ast_type(enclosing_function)->return_type->is_ref)
|
if (get_ast_type(enclosing_function_stack.top())->return_type->is_ref)
|
||||||
return_value = make_operator_call("&", vector(return_value))
|
return_value = make_operator_call("&", vector(return_value))
|
||||||
var temp_return = ast_identifier_ptr("temp_boom_return", get_ast_type(return_value)->clone_without_ref(), block)
|
var temp_return = ast_identifier_ptr("temp_boom_return", get_ast_type(return_value)->clone_without_ref(), block)
|
||||||
block->code_block.children.add(ast_declaration_statement_ptr(temp_return, null<ast_node>(), false))
|
block->code_block.children.add(ast_declaration_statement_ptr(temp_return, null<ast_node>(), false))
|
||||||
block->code_block.children.add(assign_or_copy_construct_statement(temp_return, return_value))
|
block->code_block.children.add(assign_or_copy_construct_statement(temp_return, return_value))
|
||||||
// dereference so that the real ref can take it back
|
// dereference so that the real ref can take it back
|
||||||
if (get_ast_type(enclosing_function)->return_type->is_ref)
|
if (get_ast_type(enclosing_function_stack.top())->return_type->is_ref)
|
||||||
temp_return = make_operator_call("*", vector(temp_return))
|
temp_return = make_operator_call("*", vector(temp_return))
|
||||||
node->return_statement.return_value = temp_return
|
node->return_statement.return_value = temp_return
|
||||||
}
|
}
|
||||||
for (var i = 0; i < defer_double_stack.size(); i++;)
|
for (var i = 0; i < defer_triple_stack.top().size(); i++;)
|
||||||
block->code_block.children.add_all(defer_double_stack.from_top(i).reverse_vector())
|
block->code_block.children.add_all(defer_triple_stack.top().from_top(i).reverse_vector())
|
||||||
block->code_block.children.add(node)
|
block->code_block.children.add(node)
|
||||||
}
|
}
|
||||||
ast_node::code_block(backing) {
|
ast_node::code_block(backing) {
|
||||||
node->code_block.children.add_all(defer_double_stack.pop().reverse_vector())
|
node->code_block.children.add_all(defer_triple_stack.top().pop().reverse_vector())
|
||||||
}
|
}
|
||||||
ast_node::for_loop(backing) {
|
ast_node::for_loop(backing) {
|
||||||
loop_stack.pop()
|
loop_stack.pop()
|
||||||
@@ -77,9 +79,13 @@ fun defer_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_t
|
|||||||
ast_node::while_loop(backing) {
|
ast_node::while_loop(backing) {
|
||||||
loop_stack.pop()
|
loop_stack.pop()
|
||||||
}
|
}
|
||||||
|
ast_node::function(backing) {
|
||||||
|
defer_triple_stack.pop()
|
||||||
|
enclosing_function_stack.pop()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
run_on_tree(helper_before, helper_after, syntax_ast_pair.second)
|
run_on_tree(helper_before, helper_after, syntax_ast_pair.second, &visited)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
113
stdlib/hash_set.krak
Normal file
113
stdlib/hash_set.krak
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
import hash_map
|
||||||
|
import vector
|
||||||
|
import io
|
||||||
|
import serialize
|
||||||
|
|
||||||
|
fun hash_set<T>(): hash_set<T> {
|
||||||
|
var toRet.construct() : hash_set<T>
|
||||||
|
return toRet
|
||||||
|
}
|
||||||
|
|
||||||
|
fun hash_set<T>(item: T): hash_set<T> {
|
||||||
|
var toRet.construct() : hash_set<T>
|
||||||
|
toRet.add(item)
|
||||||
|
return toRet
|
||||||
|
}
|
||||||
|
|
||||||
|
fun from_vector<T>(items: vector::vector<T>): hash_set<T> {
|
||||||
|
var toRet.construct() : hash_set<T>
|
||||||
|
items.for_each( fun(item: T) toRet.add(item); )
|
||||||
|
return toRet
|
||||||
|
}
|
||||||
|
|
||||||
|
obj hash_set<T> (Object, Serializable) {
|
||||||
|
var data: hash_map::hash_map<T>
|
||||||
|
fun construct(): *hash_set<T> {
|
||||||
|
data.construct()
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
/*fun construct(ammt: int): *hash_set<T> {*/
|
||||||
|
/*data.construct(ammt)*/
|
||||||
|
/*return this*/
|
||||||
|
/*}*/
|
||||||
|
fun copy_construct(old: *hash_set<T>) {
|
||||||
|
data.copy_construct(&old->data)
|
||||||
|
}
|
||||||
|
fun operator=(rhs: ref hash_set<T>) {
|
||||||
|
data = rhs.data
|
||||||
|
}
|
||||||
|
fun serialize(): vector::vector<char> {
|
||||||
|
return serialize::serialize(data)
|
||||||
|
}
|
||||||
|
fun unserialize(it: ref vector::vector<char>, pos: int): int {
|
||||||
|
return data.unserialize(it, pos)
|
||||||
|
}
|
||||||
|
fun operator==(rhs: ref hash_set<T>): bool {
|
||||||
|
if (size() != rhs.size())
|
||||||
|
return false
|
||||||
|
return !data.any_true( fun(item: T): bool return !rhs.contains(item); )
|
||||||
|
}
|
||||||
|
fun operator!=(rhs: ref hash_set<T>): bool {
|
||||||
|
return ! (*this == rhs)
|
||||||
|
}
|
||||||
|
fun destruct() {
|
||||||
|
data.destruct()
|
||||||
|
}
|
||||||
|
fun size():int {
|
||||||
|
return data.size
|
||||||
|
}
|
||||||
|
fun contains(items: ref hash_set<T>): bool {
|
||||||
|
return items.size() == 0 || !items.any_true( fun(item: T): bool return !contains(item); )
|
||||||
|
}
|
||||||
|
fun contains(item: ref T): bool {
|
||||||
|
return data.contains_key(item)
|
||||||
|
}
|
||||||
|
fun operator+=(item: ref T) {
|
||||||
|
add(item)
|
||||||
|
}
|
||||||
|
fun operator+=(items: ref hash_set<T>) {
|
||||||
|
add(items)
|
||||||
|
}
|
||||||
|
fun operator+(items: ref hash_set<T>): hash_set<T> {
|
||||||
|
var to_ret.copy_construct(this): hash_set<T>
|
||||||
|
to_ret.add(items)
|
||||||
|
return to_ret
|
||||||
|
}
|
||||||
|
fun add(item: ref T) {
|
||||||
|
if (!contains(item))
|
||||||
|
data.set(item,true)
|
||||||
|
}
|
||||||
|
fun add_all(items: ref hash_set<T>) {
|
||||||
|
add(items)
|
||||||
|
}
|
||||||
|
fun add(items: ref hash_set<T>) {
|
||||||
|
items.for_each( fun(item: ref T) add(item); )
|
||||||
|
}
|
||||||
|
fun remove(item: ref T) {
|
||||||
|
data.remove(item)
|
||||||
|
}
|
||||||
|
fun for_each(func: fun(ref T):void) {
|
||||||
|
data.for_each(func)
|
||||||
|
}
|
||||||
|
fun for_each(func: fun(T):void) {
|
||||||
|
data.for_each(func)
|
||||||
|
}
|
||||||
|
fun any_true(func: fun(T):bool):bool {
|
||||||
|
return data.any_true(func)
|
||||||
|
}
|
||||||
|
fun reduce<U>(func: fun(T,U): U, initial: U): U {
|
||||||
|
return data.reduce(func, initial)
|
||||||
|
}
|
||||||
|
fun flatten_map<U>(func: fun(T):hash_set<U>):hash_set<U> {
|
||||||
|
var newSet.construct(size()): hash_set<U>
|
||||||
|
for (var i = 0; i < size(); i++;)
|
||||||
|
func(data[i]).for_each(fun(item: ref U) newSet.add(item);)
|
||||||
|
return newSet
|
||||||
|
}
|
||||||
|
fun filter(func: fun(T):bool):hash_set<T> {
|
||||||
|
var newSet.construct(): hash_set<T>
|
||||||
|
newSet.data = data.filter(func)
|
||||||
|
return newSet
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1015,7 +1015,7 @@ fun interpret_identifier(ident: *ast_node, var_stack: *stack<map<*ast_node, valu
|
|||||||
// check for global
|
// check for global
|
||||||
if (globals->contains_key(ident))
|
if (globals->contains_key(ident))
|
||||||
return make_pair((*globals)[ident], control_flow::nor())
|
return make_pair((*globals)[ident], control_flow::nor())
|
||||||
println("couldn't find it in interpret identifier, scope:")
|
println("couldn't find " + get_ast_name(ident) + " in interpret identifier, scope:")
|
||||||
for (var i = 0; i < var_stack->size(); i++;) {
|
for (var i = 0; i < var_stack->size(); i++;) {
|
||||||
println(string("level: ") + i)
|
println(string("level: ") + i)
|
||||||
var_stack->from_top(i).for_each(fun(key: *ast_node, v: value) print(get_ast_name(key) + " ");)
|
var_stack->from_top(i).for_each(fun(key: *ast_node, v: value) print(get_ast_name(key) + " ");)
|
||||||
@@ -1025,7 +1025,7 @@ fun interpret_identifier(ident: *ast_node, var_stack: *stack<map<*ast_node, valu
|
|||||||
println("object scope:")
|
println("object scope:")
|
||||||
var object_def = enclosing_object.object_like.second->type_def
|
var object_def = enclosing_object.object_like.second->type_def
|
||||||
for (var i = 0; i < object_def->type_def.variables.size; i++;) {
|
for (var i = 0; i < object_def->type_def.variables.size; i++;) {
|
||||||
print(get_ast_name(object_def->type_def.variables[i]) + " ")
|
print(get_ast_name(object_def->type_def.variables[i]->declaration_statement.identifier) + " ")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
print("no object scope: ")
|
print("no object scope: ")
|
||||||
|
|||||||
@@ -22,11 +22,12 @@ fun node_counter_test(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>,
|
|||||||
}
|
}
|
||||||
fun node_counter_helper(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree<symbol>>): int {
|
fun node_counter_helper(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree<symbol>>): int {
|
||||||
var counter = 0
|
var counter = 0
|
||||||
|
var visited = set<*ast_node>()
|
||||||
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(node: *ast_node, parent_chain: *stack<*ast_node>) {
|
var helper = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {
|
||||||
counter++
|
counter++
|
||||||
}
|
}
|
||||||
run_on_tree(helper, empty_pass_second_half, syntax_ast_pair.second)
|
run_on_tree(helper, empty_pass_second_half, syntax_ast_pair.second, &visited)
|
||||||
})
|
})
|
||||||
return counter
|
return counter
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ import pass_common:*
|
|||||||
// temporaries.
|
// temporaries.
|
||||||
// 3 this is also when we add in defer destructs for function parameters (inside the function) and declaration statements
|
// 3 this is also when we add in defer destructs for function parameters (inside the function) and declaration statements
|
||||||
fun obj_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree<symbol>>) {
|
fun obj_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree<symbol>>) {
|
||||||
|
var visited1 = set<*ast_node>()
|
||||||
|
var visited2 = set<*ast_node>()
|
||||||
|
var visited3 = set<*ast_node>()
|
||||||
|
var functions_visited_for_construct_in_destruct_out = set<*ast_node>()
|
||||||
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>) {
|
||||||
// Pass 1
|
// Pass 1
|
||||||
var ensure_block_and_munge = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {
|
var ensure_block_and_munge = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {
|
||||||
@@ -67,9 +71,9 @@ fun obj_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
run_on_tree(ensure_block_and_munge, empty_pass_second_half, syntax_ast_pair.second)
|
run_on_tree(ensure_block_and_munge, empty_pass_second_half, syntax_ast_pair.second, &visited1)
|
||||||
// Pass 2
|
// Pass 2
|
||||||
var short_circut_op: fun(*ast_node,*stack<*ast_node>): bool = fun(node: *ast_node, parent_chain: *stack<*ast_node>): bool {
|
var short_circut_op: fun(*ast_node,*stack<*ast_node>,*set<*ast_node>): bool = fun(node: *ast_node, parent_chain: *stack<*ast_node>, visited: *set<*ast_node>): bool {
|
||||||
match(*node) {
|
match(*node) {
|
||||||
ast_node::function_call(backing) {
|
ast_node::function_call(backing) {
|
||||||
var func_name = string()
|
var func_name = string()
|
||||||
@@ -98,15 +102,18 @@ fun obj_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_
|
|||||||
add_before_in(short_circuit_if, parent_chain->from_top(enclosing_block_idx-1), parent_chain->from_top(enclosing_block_idx))
|
add_before_in(short_circuit_if, parent_chain->from_top(enclosing_block_idx-1), parent_chain->from_top(enclosing_block_idx))
|
||||||
replace_with_in(node, short_circuit_result, parent_chain)
|
replace_with_in(node, short_circuit_result, parent_chain)
|
||||||
var shorter_tree = stack_from_vector( parent_chain->data.slice(0, parent_chain->size()-enclosing_block_idx))
|
var shorter_tree = stack_from_vector( parent_chain->data.slice(0, parent_chain->size()-enclosing_block_idx))
|
||||||
run_on_tree_helper(short_circut_op, empty_pass_second_half, short_circuit_declaration, &shorter_tree, false)
|
/*visited->add(short_circuit_result)*/
|
||||||
run_on_tree_helper(short_circut_op, empty_pass_second_half, short_circuit_if, &shorter_tree, false)
|
/*visited->add(short_circuit_declaration)*/
|
||||||
|
/*visited->add(short_circuit_if)*/
|
||||||
|
run_on_tree_helper(short_circut_op, empty_pass_second_half, short_circuit_declaration, &shorter_tree, visited)
|
||||||
|
run_on_tree_helper(short_circut_op, empty_pass_second_half, short_circuit_if, &shorter_tree, visited)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
run_on_tree(short_circut_op, empty_pass_second_half, syntax_ast_pair.second)
|
run_on_tree(short_circut_op, empty_pass_second_half, syntax_ast_pair.second, &visited2)
|
||||||
// Pass 3
|
// Pass 3
|
||||||
var construct_in_destruct_out = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {
|
var construct_in_destruct_out = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {
|
||||||
match(*node) {
|
match(*node) {
|
||||||
@@ -160,6 +167,12 @@ fun obj_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast_node::function(backing) {
|
ast_node::function(backing) {
|
||||||
|
// Because of how iteration is done now, we might touch functions multiple times (binding-like iteration in a DFS)
|
||||||
|
// To deal with this, we keep a visited set.
|
||||||
|
if (functions_visited_for_construct_in_destruct_out.contains(node))
|
||||||
|
return;
|
||||||
|
functions_visited_for_construct_in_destruct_out.add(node)
|
||||||
|
|
||||||
var order = 0;
|
var order = 0;
|
||||||
backing.parameters.for_each(fun(param: *ast_node) {
|
backing.parameters.for_each(fun(param: *ast_node) {
|
||||||
var param_type = get_ast_type(param)
|
var param_type = get_ast_type(param)
|
||||||
@@ -186,7 +199,6 @@ fun obj_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_
|
|||||||
backing.expression = null<ast_node>()
|
backing.expression = null<ast_node>()
|
||||||
}
|
}
|
||||||
if (has_method(ident_type->type_def, "destruct", vector<*type>())) {
|
if (has_method(ident_type->type_def, "destruct", vector<*type>())) {
|
||||||
// have to go up one because our parent is a statement
|
|
||||||
add_after_in(ast_defer_statement_ptr(make_method_call(backing.identifier, "destruct", vector<*ast_node>())),
|
add_after_in(ast_defer_statement_ptr(make_method_call(backing.identifier, "destruct", vector<*ast_node>())),
|
||||||
node, parent_chain->top())
|
node, parent_chain->top())
|
||||||
}
|
}
|
||||||
@@ -194,7 +206,7 @@ fun obj_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
run_on_tree(empty_pass_first_half, construct_in_destruct_out, syntax_ast_pair.second)
|
run_on_tree(empty_pass_first_half, construct_in_destruct_out, syntax_ast_pair.second, &visited3)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -148,8 +148,11 @@ fun has_method(object: *ast_node, name: string, parameter_types: vector<*type>):
|
|||||||
}
|
}
|
||||||
fun get_from_scope(node: *ast_node, member: *char): *ast_node
|
fun get_from_scope(node: *ast_node, member: *char): *ast_node
|
||||||
return get_from_scope(node, string(member))
|
return get_from_scope(node, string(member))
|
||||||
fun get_from_scope(node: *ast_node, member: string): *ast_node
|
fun get_from_scope(node: *ast_node, member: string): *ast_node {
|
||||||
return get_ast_scope(node)->get(member).first()
|
/*if (get_ast_scope(node)->contains(member))*/
|
||||||
|
return get_ast_scope(node)->get(member).first()
|
||||||
|
/*return null<ast_node>()*/
|
||||||
|
}
|
||||||
fun make_method_call(object_ident: *ast_node, name: *char, parameters: vector<*ast_node>): *ast_node return make_method_call(object_ident, string(name), parameters);
|
fun make_method_call(object_ident: *ast_node, name: *char, parameters: vector<*ast_node>): *ast_node return make_method_call(object_ident, string(name), parameters);
|
||||||
fun make_method_call(object_ident: *ast_node, name: string, parameters: vector<*ast_node>): *ast_node {
|
fun make_method_call(object_ident: *ast_node, name: string, parameters: vector<*ast_node>): *ast_node {
|
||||||
// note that this type_def is the adt_def if this is an adt type
|
// note that this type_def is the adt_def if this is an adt type
|
||||||
@@ -281,6 +284,7 @@ fun replace_with_in(orig: *ast_node, new: *ast_node, in: *stack<*ast_node>)
|
|||||||
fun replace_with_in(orig: *ast_node, new: *ast_node, in: *ast_node) {
|
fun replace_with_in(orig: *ast_node, new: *ast_node, in: *ast_node) {
|
||||||
match (*in) {
|
match (*in) {
|
||||||
ast_node::return_statement(backing) { backing.return_value = new; return; }
|
ast_node::return_statement(backing) { backing.return_value = new; return; }
|
||||||
|
ast_node::cast(backing) { if (backing.value == orig) { backing.value = new; return; } }
|
||||||
ast_node::assignment_statement(backing) {
|
ast_node::assignment_statement(backing) {
|
||||||
if (backing.to == orig) {
|
if (backing.to == orig) {
|
||||||
backing.to = new
|
backing.to = new
|
||||||
@@ -400,43 +404,47 @@ fun add_after_in(to_add: *ast_node, before: *ast_node, in: *ast_node) {
|
|||||||
error(string("cannot add_after_in to ") + get_ast_name(in))
|
error(string("cannot add_after_in to ") + get_ast_name(in))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun empty_pass_first_half(node: *ast_node, parent_chain: *stack<*ast_node>): bool { return true; }
|
fun empty_pass_first_half(node: *ast_node, parent_chain: *stack<*ast_node>, visited: *set<*ast_node>): bool { return true; }
|
||||||
fun empty_pass_second_half(node: *ast_node, parent_chain: *stack<*ast_node>) {}
|
fun empty_pass_second_half(node: *ast_node, parent_chain: *stack<*ast_node>) {}
|
||||||
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)
|
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, visited: *set<*ast_node>)
|
||||||
run_on_tree(fun(n: *ast_node, s: *stack<*ast_node>): bool {func_before(n, s);return true;}, func_after, tree)
|
run_on_tree(fun(n: *ast_node, s: *stack<*ast_node>, v: *set<*ast_node>): bool {func_before(n, s);return true;}, func_after, tree, visited)
|
||||||
|
|
||||||
fun run_on_tree(func_before: fun(*ast_node,*stack<*ast_node>):bool, func_after: fun(*ast_node,*stack<*ast_node>):void, tree: *ast_node) {
|
fun run_on_tree(func_before: fun(*ast_node,*stack<*ast_node>,*set<*ast_node>):bool, func_after: fun(*ast_node,*stack<*ast_node>):void, tree: *ast_node, visited: *set<*ast_node>) {
|
||||||
var parent_stack = stack<*ast_node>()
|
var parent_stack = stack<*ast_node>()
|
||||||
run_on_tree_helper(func_before, func_after, tree, &parent_stack, false)
|
run_on_tree_helper(func_before, func_after, tree, &parent_stack, visited)
|
||||||
}
|
}
|
||||||
fun run_on_tree_helper(func_before: fun(*ast_node,*stack<*ast_node>):bool, func_after: fun(*ast_node,*stack<*ast_node>):void, node: *ast_node, parent_chain: *stack<*ast_node>, do_func: bool) {
|
fun run_on_tree_helper(func_before: fun(*ast_node,*stack<*ast_node>,*set<*ast_node>):bool,
|
||||||
if (!node || (!do_func && is_function(node))) return
|
func_after: fun(*ast_node,*stack<*ast_node>):void,
|
||||||
var do_children = func_before(node, parent_chain)
|
node: *ast_node, parent_chain: *stack<*ast_node>, visited: *set<*ast_node>) {
|
||||||
|
// So some nodes should be done regardless of weather or not we've visited them - these are the places where a more reasonable AST might use bindings, i.e. variables and functions.
|
||||||
|
if (!node || (!is_function(node) && !is_identifier(node) && visited->contains(node))) return;
|
||||||
|
visited->add(node)
|
||||||
|
var do_children = func_before(node, parent_chain, visited)
|
||||||
parent_chain->push(node)
|
parent_chain->push(node)
|
||||||
if (do_children) {
|
if (do_children) {
|
||||||
match(*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, true);)
|
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, visited);)
|
||||||
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, true);)
|
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, visited);)
|
||||||
ast_node::adt_def(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain, true);)
|
ast_node::adt_def(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain, visited);)
|
||||||
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, false);)
|
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, visited);)
|
||||||
ast_node::template(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain, true);)
|
ast_node::template(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain, visited);)
|
||||||
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, false);)
|
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, visited);)
|
||||||
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, false);)
|
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, visited);)
|
||||||
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, false);)
|
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, visited);)
|
||||||
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, false);)
|
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, visited);)
|
||||||
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, false);)
|
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, visited);)
|
||||||
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, false);)
|
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, visited);)
|
||||||
ast_node::return_statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain, false);)
|
ast_node::return_statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain, visited);)
|
||||||
ast_node::defer_statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain, false);)
|
ast_node::defer_statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain, visited);)
|
||||||
ast_node::assignment_statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain, false);)
|
ast_node::assignment_statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain, visited);)
|
||||||
ast_node::declaration_statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain, false);)
|
ast_node::declaration_statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain, visited);)
|
||||||
ast_node::if_comp(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain, true);)
|
ast_node::if_comp(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain, visited);)
|
||||||
ast_node::function_call(backing) {
|
ast_node::function_call(backing) {
|
||||||
if (!is_function(backing.func))
|
/*if (!is_function(backing.func))*/
|
||||||
run_on_tree_helper(func_before, func_after, backing.func, parent_chain, false)
|
run_on_tree_helper(func_before, func_after, backing.func, parent_chain, visited)
|
||||||
node->function_call.parameters.for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain, false);)
|
node->function_call.parameters.for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain, visited);)
|
||||||
}
|
}
|
||||||
ast_node::cast(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain, false);)
|
ast_node::cast(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain, visited);)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// function may have messed with the parent chain
|
// function may have messed with the parent chain
|
||||||
@@ -445,3 +453,43 @@ fun run_on_tree_helper(func_before: fun(*ast_node,*stack<*ast_node>):bool, func_
|
|||||||
func_after(node, parent_chain)
|
func_after(node, parent_chain)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun is_legal_parameter_node_type(n: *ast_node): bool {
|
||||||
|
match(*n) {
|
||||||
|
ast_node::translation_unit() return false;
|
||||||
|
ast_node::import() return false;
|
||||||
|
ast_node::identifier() return true;
|
||||||
|
ast_node::type_def() return false;
|
||||||
|
ast_node::adt_def() return false;
|
||||||
|
ast_node::function() return true;
|
||||||
|
ast_node::template() return false;
|
||||||
|
ast_node::code_block() return false;
|
||||||
|
ast_node::if_statement() return false;
|
||||||
|
ast_node::match_statement() return false;
|
||||||
|
ast_node::case_statement() return false;
|
||||||
|
ast_node::while_loop() return false;
|
||||||
|
ast_node::for_loop() return false;
|
||||||
|
ast_node::return_statement() return false;
|
||||||
|
ast_node::branching_statement() return false;
|
||||||
|
ast_node::defer_statement() return false;
|
||||||
|
ast_node::assignment_statement() return false;
|
||||||
|
ast_node::declaration_statement() return false;
|
||||||
|
ast_node::if_comp() return false;
|
||||||
|
ast_node::simple_passthrough() return false;
|
||||||
|
ast_node::function_call() return true;
|
||||||
|
ast_node::compiler_intrinsic() return true;
|
||||||
|
ast_node::cast() return true;
|
||||||
|
ast_node::value() return true;
|
||||||
|
}
|
||||||
|
error("is_legal_parameter_node_type with no type")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun get_fully_scoped_name(n: *ast_node): string {
|
||||||
|
if (!n)
|
||||||
|
return string("NULL")
|
||||||
|
var above = string()
|
||||||
|
var scope_map = get_ast_scope(n);
|
||||||
|
if (scope_map && scope_map->contains_key(string("~enclosing_scope")))
|
||||||
|
above = get_fully_scoped_name(scope_map->get(string("~enclosing_scope"))[0])
|
||||||
|
return above + "::" + get_ast_name(n)
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
99
stdlib/ref_lower.krak
Normal file
99
stdlib/ref_lower.krak
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
import symbol:*
|
||||||
|
import tree:*
|
||||||
|
import map:*
|
||||||
|
import vector:*
|
||||||
|
import set:*
|
||||||
|
import util:*
|
||||||
|
import string:*
|
||||||
|
import mem:*
|
||||||
|
import io:*
|
||||||
|
import ast_nodes:*
|
||||||
|
import ast_transformation:*
|
||||||
|
|
||||||
|
import pass_common:*
|
||||||
|
|
||||||
|
fun has_ref_inside(t: *type): bool {
|
||||||
|
if (t->is_ref)
|
||||||
|
return true
|
||||||
|
if (t->is_function()) {
|
||||||
|
for (var i = 0; i < t->parameter_types.size; i++;)
|
||||||
|
if (has_ref_inside(t->parameter_types[i]))
|
||||||
|
return true
|
||||||
|
if (has_ref_inside(t->return_type))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
fun remove_ref(t: *type) {
|
||||||
|
if (t->is_ref) {
|
||||||
|
t->is_ref = false
|
||||||
|
t->indirection++
|
||||||
|
}
|
||||||
|
if (t->is_function()) {
|
||||||
|
for (var i = 0; i < t->parameter_types.size; i++;)
|
||||||
|
remove_ref(t->parameter_types[i])
|
||||||
|
remove_ref(t->return_type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ref_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree<symbol>>) {
|
||||||
|
var remove_ref_type_set = set<pair<string,*type>>()
|
||||||
|
var modify_reference_use_set = set<pair<*ast_node, *ast_node>>()
|
||||||
|
var modify_return_set = set<*ast_node>()
|
||||||
|
var visited = set<*ast_node>()
|
||||||
|
name_ast_map->for_each(fun(name: string, syntax_ast_pair: pair<*tree<symbol>,*ast_node>) {
|
||||||
|
var helper_before = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {
|
||||||
|
match(*node) {
|
||||||
|
ast_node::identifier(backing) {
|
||||||
|
if (backing.type->is_ref)
|
||||||
|
modify_reference_use_set.add(make_pair(node, parent_chain->top()))
|
||||||
|
if (has_ref_inside(backing.type)) {
|
||||||
|
remove_ref_type_set.add(make_pair("identifier: " + backing.name, backing.type))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ast_node::function(backing) {
|
||||||
|
var full_name = get_fully_scoped_name(node) + " - (" + backing.name + ")"
|
||||||
|
if (has_ref_inside(backing.type))
|
||||||
|
remove_ref_type_set.add(make_pair(full_name, backing.type))
|
||||||
|
}
|
||||||
|
ast_node::function_call(backing) {
|
||||||
|
// check to see if it's taking a ref, if so add in the &
|
||||||
|
var func_type_params = get_ast_type(backing.func)->parameter_types
|
||||||
|
for (var i = 0; i < func_type_params.size; i++;)
|
||||||
|
if (func_type_params[i]->is_ref)
|
||||||
|
backing.parameters[i] = make_operator_call("&", vector(backing.parameters[i]))
|
||||||
|
// add the function call to the modify_reference_use set if the function returns a ref
|
||||||
|
if (get_ast_type(backing.func)->return_type->is_ref)
|
||||||
|
modify_reference_use_set.add(make_pair(node, parent_chain->top()))
|
||||||
|
}
|
||||||
|
ast_node::return_statement(backing) {
|
||||||
|
// check to see if it's returning a ref, if so add in the &
|
||||||
|
if (parent_chain->item_from_top_satisfying(is_function)->function.type->return_type->is_ref)
|
||||||
|
modify_return_set.add(node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
run_on_tree(helper_before, empty_pass_second_half, syntax_ast_pair.second, &visited)
|
||||||
|
})
|
||||||
|
remove_ref_type_set.for_each(fun(p: pair<string, *type>) {
|
||||||
|
var t = p.second
|
||||||
|
/*println("before" + p.first + ": " + t->to_string())*/
|
||||||
|
remove_ref(t)
|
||||||
|
/*println("after" + p.first + ": " + t->to_string())*/
|
||||||
|
})
|
||||||
|
modify_reference_use_set.for_each(fun(p: pair<*ast_node, *ast_node>) {
|
||||||
|
// if we haven't modified it's indirection yet
|
||||||
|
if (is_identifier(p.first) && p.first->identifier.type->is_ref) {
|
||||||
|
// remove ref, add 1 to indirection
|
||||||
|
p.first->identifier.type = p.first->identifier.type->clone_with_increased_indirection(1, false);
|
||||||
|
}
|
||||||
|
// note that we definitly want to replace the type for unused parameters, but we don't want to add the * for paramters
|
||||||
|
// in function declarations or the new identifier in declaration statements (but we do for expressions in declaration statements)
|
||||||
|
if (!is_identifier(p.first) || (!is_function(p.second) && (!is_declaration_statement(p.second) || p.second->declaration_statement.identifier != p.first)))
|
||||||
|
replace_with_in(p.first, make_operator_call("*", vector(p.first)), p.second);
|
||||||
|
})
|
||||||
|
modify_return_set.for_each(fun(r: *ast_node) {
|
||||||
|
r->return_statement.return_value = make_operator_call("&", vector(r->return_statement.return_value));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
@@ -82,4 +82,7 @@ obj stack<T> (Object, Serializable) {
|
|||||||
return i
|
return i
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
fun item_from_top_satisfying(func: fun(T):bool): T {
|
||||||
|
return from_top(index_from_top_satisfying(func))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
runner_path="./tester"
|
runner_path="./tester"
|
||||||
#testDir=${1:-"../tests"}
|
#testDir=${1:-"../tests"}
|
||||||
|
|||||||
Reference in New Issue
Block a user