Add in address_of_ensure_variable_lower.krak that makes sure & can always take a reference, even of a constant, etc, and start the cleanup of c_generator that this allows
This commit is contained in:
51
stdlib/address_of_ensure_variable_lower.krak
Normal file
51
stdlib/address_of_ensure_variable_lower.krak
Normal file
@@ -0,0 +1,51 @@
|
||||
import symbol:*
|
||||
import tree:*
|
||||
import map:*
|
||||
import util:*
|
||||
import string:*
|
||||
import io:*
|
||||
import ast_nodes:*
|
||||
import ast_transformation:*
|
||||
import pass_common:*
|
||||
|
||||
fun address_of_ensure_variable_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree<symbol>>) {
|
||||
var visited = hash_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::function_call(backing) {
|
||||
if (is_function(backing.func) && backing.func->function.name == "&") {
|
||||
var addresse = backing.parameters[0]
|
||||
// Identifier is always fine. The other options are
|
||||
// function call, value, or cast. The only fine one here
|
||||
// is a function call of *
|
||||
if ( (is_function_call(addresse) &&
|
||||
!(is_function(addresse->function_call.func) &&
|
||||
(addresse->function_call.func->function.name == "*" ||
|
||||
addresse->function_call.func->function.name == "." ||
|
||||
addresse->function_call.func->function.name == "->" ||
|
||||
addresse->function_call.func->function.name == "[]"))) ||
|
||||
is_value(addresse) || is_cast(addresse) ) {
|
||||
// so we're a function call that's not * or a cast or value
|
||||
// so make a temp variable for us
|
||||
// Note that we don't have to worry about destruction because
|
||||
// all object stuff has already ran, so this isn't an object
|
||||
|
||||
var enclosing_block_idx = parent_chain->index_from_top_satisfying(is_code_block)
|
||||
var enclosing_block = parent_chain->from_top(enclosing_block_idx)
|
||||
var before_block_parent = parent_chain->from_top(enclosing_block_idx-1)
|
||||
var ident = ast_identifier_ptr("for_address_of_temp",
|
||||
backing.func->function.type->parameter_types[0],
|
||||
enclosing_block)
|
||||
var decl = ast_declaration_statement_ptr(ident, addresse)
|
||||
add_before_in(decl, before_block_parent, enclosing_block)
|
||||
replace_with_in(addresse, ident, node)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
run_on_tree(helper_before, empty_pass_second_half(), syntax_ast_pair.second, &visited)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user