This commit is contained in:
Nathan Braswell
2017-01-23 01:09:31 -05:00
parent beb50b8e25
commit 3a7f73b711
9 changed files with 88 additions and 64 deletions

View File

@@ -135,7 +135,7 @@ cast_expression = "\(" WS boolean_expression WS "\)" WS "cast" WS type ;
number = integer | floating_literal ;
access_operation = unarad WS "." WS identifier | unarad WS "->" WS identifier | unarad WS "." WS identifier WS template_inst | unarad WS "->" WS identifier WS template_inst ;
assignment_statement = factor WS "=" WS boolean_expression | factor WS "\+=" WS boolean_expression | factor WS "-=" WS boolean_expression | factor WS "\*=" WS boolean_expression | factor WS "/=" WS boolean_expression ;
assignment_statement = factor WS "=" WS boolean_expression | factor WS "\+=" WS boolean_expression | factor WS "-=" WS boolean_expression | factor WS "\*=" WS boolean_expression | factor WS "/=" WS boolean_expression | factor WS "^=" WS boolean_expression ;
# if it's being assigned to, we allow type inferencing
declaration_statement = "var" WS identifier WS "=" WS boolean_expression | "var" WS identifier WS dec_type WS "=" WS boolean_expression | "var" WS identifier WS dec_type | "ext" WS "var" WS identifier WS dec_type | "var" WS identifier WS "." WS identifier WS "\(" WS opt_parameter_list WS "\)" WS dec_type ;
hexadecimal = "0x([0-9]|[a-f])+" ;

View File

@@ -29,16 +29,16 @@ fun adt_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_
var option_union = ast_type_def_ptr(backing.name + "_union", true);
node->adt_def.options.for_each(fun(opt: *ast_node) {
if (!opt->identifier.type->is_empty_adt_option())
option_union->type_def.variables.add(ast_declaration_statement_ptr(opt, null<ast_node>(), false))
option_union->type_def.variables.add(ast_declaration_statement_ptr(opt, null<ast_node>()))
type_def_option_map[node].add(opt)
})
var option_union_type = type_ptr(option_union)
option_union->type_def.self_type = option_union_type
var option_union_ident = ast_identifier_ptr(string("data"), option_union_type, replacement)
replacement->type_def.variables.add(ast_declaration_statement_ptr(option_union_ident, null<ast_node>(), false))
replacement->type_def.variables.add(ast_declaration_statement_ptr(option_union_ident, null<ast_node>()))
add_to_scope("data", option_union_ident, replacement)
var flag = ast_identifier_ptr(string("flag"), type_ptr(base_type::integer()), replacement)
replacement->type_def.variables.add(ast_declaration_statement_ptr(flag, null<ast_node>(), false))
replacement->type_def.variables.add(ast_declaration_statement_ptr(flag, null<ast_node>()))
add_to_scope("flag", flag, replacement)
add_before_in(option_union, node, parent_chain)
var enclosing_scope = node->adt_def.scope[string("~enclosing_scope")][0]
@@ -48,7 +48,7 @@ fun adt_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_
var block = ast_code_block_ptr()
func->function.body_statement = block
var to_ret = ast_identifier_ptr(string("to_ret"), adt_type, block)
block->code_block.children.add(ast_declaration_statement_ptr(to_ret, null<ast_node>(), false))
block->code_block.children.add(ast_declaration_statement_ptr(to_ret, null<ast_node>()))
var value = ast_value_ptr(to_string(idx), type_ptr(base_type::integer()))
block->code_block.children.add(ast_assignment_statement_ptr(make_operator_call(".", vector(to_ret, flag)), value))
@@ -141,7 +141,7 @@ fun adt_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_
var block = ast_code_block_ptr()
var value = backing.value
var holder = ast_identifier_ptr(string("holder"), get_ast_type(value)->clone_with_increased_indirection(), block)
block->code_block.children.add(ast_declaration_statement_ptr(holder, null<ast_node>(), false))
block->code_block.children.add(ast_declaration_statement_ptr(holder, null<ast_node>()))
block->code_block.children.add(ast_assignment_statement_ptr(holder, make_operator_call("&", vector(value))))
backing.cases.for_each(fun(case_stmt: *ast_node) {
var option = case_stmt->case_statement.option
@@ -161,7 +161,7 @@ fun adt_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_
var get_option = make_operator_call(".", vector(make_operator_call("->", vector(holder, data)), option))
get_option = make_operator_call("&", vector(get_option))
unpack_ident->identifier.type = unpack_ident->identifier.type->clone_with_ref()
inner_block->code_block.children.add(ast_declaration_statement_ptr(unpack_ident, get_option, false))
inner_block->code_block.children.add(ast_declaration_statement_ptr(unpack_ident, get_option))
}
inner_block->code_block.children.add(case_stmt->case_statement.statement)
if_stmt->if_statement.then_part = inner_block

View File

@@ -148,7 +148,10 @@ fun ast_identifier_ptr(name: *char, type: *type, enclosing_scope: *ast_node): *a
return ast_identifier_ptr(string(name), type, enclosing_scope)
}
fun ast_identifier_ptr(name: string, type: *type, enclosing_scope: *ast_node): *ast_node {
var to_ret.construct(name, type, enclosing_scope): identifier
return ast_identifier_ptr(name, type, enclosing_scope, false)
}
fun ast_identifier_ptr(name: string, type: *type, enclosing_scope: *ast_node, is_extern: bool): *ast_node {
var to_ret.construct(name, type, enclosing_scope, is_extern): identifier
var ptr = new<ast_node>()
ptr->copy_construct(&ast_node::identifier(to_ret))
return ptr
@@ -164,11 +167,13 @@ obj identifier (Object) {
var scope: map<string, vector<*ast_node>>
var type: *type
var enclosing_scope: *ast_node
fun construct(name_in: string, type_in: *type, enclosing_scope: *ast_node): *identifier {
var is_extern: bool
fun construct(name_in: string, type_in: *type, enclosing_scope: *ast_node, is_extern_in: bool): *identifier {
name.copy_construct(&name_in)
scope.construct()
type = type_in
identifier::enclosing_scope = enclosing_scope
is_extern = is_extern_in
return this
}
fun copy_construct(old: *identifier) {
@@ -176,6 +181,7 @@ obj identifier (Object) {
scope.copy_construct(&old->scope)
type = old->type
enclosing_scope = old->enclosing_scope
is_extern = old->is_extern
}
fun destruct() {
name.destruct()
@@ -186,7 +192,7 @@ obj identifier (Object) {
copy_construct(&other)
}
fun operator==(other: ref identifier): bool {
return name == other.name && type == other.type && enclosing_scope == other.enclosing_scope
return name == other.name && type == other.type && enclosing_scope == other.enclosing_scope && is_extern == other.is_extern
}
}
/*fun ast_type_def_ptr(name: string): *ast_node {*/
@@ -797,8 +803,8 @@ obj assignment_statement (Object) {
return to == other.to && from == other.from
}
}
fun ast_declaration_statement_ptr(ident: *ast_node, expression: *ast_node, is_extern: bool): *ast_node {
var to_ret.construct(ident, expression, is_extern): declaration_statement
fun ast_declaration_statement_ptr(ident: *ast_node, expression: *ast_node): *ast_node {
var to_ret.construct(ident, expression): declaration_statement
var ptr = new<ast_node>()
ptr->copy_construct(&ast_node::declaration_statement(to_ret))
return ptr
@@ -813,19 +819,16 @@ obj declaration_statement (Object) {
var identifier: *ast_node
var expression: *ast_node
var init_method_call: *ast_node
var is_extern: bool
fun construct(identifier_in: *ast_node, expression_in: *ast_node, is_extern_in: bool): *declaration_statement {
fun construct(identifier_in: *ast_node, expression_in: *ast_node): *declaration_statement {
identifier = identifier_in
expression = expression_in
init_method_call = null<ast_node>()
is_extern = is_extern_in
return this
}
fun copy_construct(old: *declaration_statement) {
identifier = old->identifier
expression = old->expression
init_method_call = old->init_method_call
is_extern = old->is_extern
}
fun destruct() {
}
@@ -834,7 +837,7 @@ obj declaration_statement (Object) {
copy_construct(&other)
}
fun operator==(other: ref declaration_statement): bool {
return identifier == other.identifier && expression == other.expression && init_method_call == other.init_method_call && is_extern == other.is_extern
return identifier == other.identifier && expression == other.expression && init_method_call == other.init_method_call
}
}
fun ast_if_comp_ptr(): *ast_node {

View File

@@ -631,7 +631,7 @@ obj ast_transformation (Object) {
var expression_syntax_node = get_node("boolean_expression", node)
var expression = null<ast_node>()
// we do it early so that if there is a type_syntax_node we can add to scope so that the expression can find this for things like rec closures
var identifier = ast_identifier_ptr(name, null<type>(), scope)
var identifier = ast_identifier_ptr(name, null<type>(), scope, get_node("\"ext\"", node) != null<tree<symbol>>())
add_to_scope(name, identifier, scope)
if (type_syntax_node) identifier->identifier.type = transform_type(type_syntax_node, scope, template_replacements)
if (expression_syntax_node) {
@@ -641,7 +641,7 @@ obj ast_transformation (Object) {
}
if (!identifier->identifier.type) error(node, "declaration statement with no type or expression from which to inference type")
if (identifier->identifier.type->is_none() || (identifier->identifier.type->indirection == 0 && identifier->identifier.type->is_void())) error(node, "declaration statement with bad type")
var declaration = ast_declaration_statement_ptr(identifier, expression, get_node("\"ext\"", node) != null<tree<symbol>>())
var declaration = ast_declaration_statement_ptr(identifier, expression)
// ok, deal with the possible init position method call
if (identifiers.size == 2) {
var parameters = get_nodes("parameter", node).map(fun(child: *tree<symbol>): *ast_node return transform(get_node("boolean_expression", child), scope, template_replacements);)
@@ -707,6 +707,13 @@ obj ast_transformation (Object) {
return possible_assign
}
to_assign = make_operator_call("/", vector(assign_to, to_assign))
} else if (get_node("\"^=\"", node)){
var possible_assign = find_and_make_any_operator_overload_call(string("^="), vector(assign_to, to_assign), scope, template_replacements)
if (possible_assign) {
/*print("Computed and returning operator/=")*/
return possible_assign
}
to_assign = make_operator_call("^", vector(assign_to, to_assign))
}
var assignment = ast_assignment_statement_ptr(assign_to, to_assign)
return assignment

View File

@@ -76,7 +76,7 @@ obj code_triple (Object) {
obj c_generator (Object) {
var id_counter: int
var ast_to_syntax: map<*ast_node, *tree<symbol>>
var ast_name_map: map<*ast_node, string>
/*var ast_name_map: hash_map<*ast_node, string>*/
var closure_struct_map: map<set<*ast_node>, string>
var function_type_map: map<type, string>
var function_typedef_string: string
@@ -88,7 +88,7 @@ obj c_generator (Object) {
fun construct(): *c_generator {
id_counter = 0
ast_to_syntax.construct()
ast_name_map.construct()
/*ast_name_map.construct()*/
closure_struct_map.construct()
function_type_map.construct()
function_typedef_string.construct()
@@ -147,7 +147,7 @@ obj c_generator (Object) {
fun copy_construct(old: *c_generator) {
id_counter = old->id_counter
ast_to_syntax.copy_construct(&old->ast_to_syntax)
ast_name_map.copy_construct(&old->ast_name_map)
/*ast_name_map.copy_construct(&old->ast_name_map)*/
closure_struct_map.copy_construct(&old->closure_struct_map)
function_type_map.copy_construct(&old->function_type_map)
function_typedef_string.copy_construct(&old->function_typedef_string)
@@ -163,7 +163,7 @@ obj c_generator (Object) {
}
fun destruct() {
ast_to_syntax.destruct()
ast_name_map.destruct()
/*ast_name_map.destruct()*/
closure_struct_map.destruct()
function_type_map.destruct()
function_typedef_string.destruct()
@@ -379,7 +379,7 @@ obj c_generator (Object) {
// we do the declaration in the pre now so that we can take it's address to close over it for things like recursive closures
// we only make it first if it's a function type though, so that global levels still work
var pre_stuff = type_to_c(identifier->identifier.type) + " " + get_name(identifier)
if (node->declaration_statement.is_extern)
if (identifier->identifier.is_extern)
pre_stuff = string("extern ") + pre_stuff
var to_ret = code_triple(pre_stuff, string(), string())
if (node->declaration_statement.expression) {
@@ -503,7 +503,7 @@ obj c_generator (Object) {
}
if (need_variable) {
var temp_ident = ast_identifier_ptr(string("temporary_value")+get_id(), get_ast_type(node), null<ast_node>())
var declaration = ast_declaration_statement_ptr(temp_ident, null<ast_node>(), false)
var declaration = ast_declaration_statement_ptr(temp_ident, null<ast_node>())
// have to pass false to the declaration generator, so can't do it through generate_statement
var trip_ret = code_triple()
trip_ret.pre += generate_declaration_statement(declaration, null<ast_node>(), null<ast_node>(), false).one_string() + " = " + to_ret + ";\n"
@@ -577,7 +577,7 @@ obj c_generator (Object) {
if ( parameters.size == 2 && (func_name == "+" || func_name == "-" || func_name == "*" || func_name == "/"
|| func_name == "<" || func_name == ">" || func_name == "<=" || func_name == ">="
|| func_name == "==" || func_name == "!=" || func_name == "%" || func_name == "^"
|| func_name == "|" || func_name == "&"
|| func_name == "|" || func_name == "&" || func_name == ">>" || func_name == "<<"
))
return code_triple("(") + generate(parameters[0], enclosing_object, enclosing_func, false) + func_name + generate(parameters[1], enclosing_object, enclosing_func, false) + string(")")
if ( parameters.size == 2 && (func_name == "||" || func_name == "&&")) {
@@ -628,8 +628,8 @@ obj c_generator (Object) {
// temporary returns if we're asked for them or we need them for destruct
if (!func_return_type->is_ref && !func_return_type->is_void() && need_variable) {
// kind of ugly combo here of
var temp_ident = ast_identifier_ptr(string("temporary_return")+get_id(), func_return_type, null<ast_node>())
var declaration = ast_declaration_statement_ptr(temp_ident, null<ast_node>(), false)
var temp_ident = ast_identifier_ptr(string("temporary_return")+get_id() + "temporary_end1", func_return_type, null<ast_node>())
var declaration = ast_declaration_statement_ptr(temp_ident, null<ast_node>())
// have to pass false to the declaration generator, so can't do it through generate_statement
call_string.pre += generate_declaration_statement(declaration, enclosing_object, enclosing_func, false).one_string() + ";\n"
pre_call = generate_identifier(temp_ident, enclosing_object, enclosing_func).one_string()
@@ -646,8 +646,8 @@ obj c_generator (Object) {
if (!dot_style_method_call) {
// lambda
if (pre_call == "" && (!func_return_type->is_void() || func_return_type->indirection)) {
var temp_ident = ast_identifier_ptr(string("temporary_return")+get_id(), func_return_type, null<ast_node>())
var declaration = ast_declaration_statement_ptr(temp_ident, null<ast_node>(), false)
var temp_ident = ast_identifier_ptr(string("temporary_return")+get_id() + "temporary_end2", func_return_type, null<ast_node>())
var declaration = ast_declaration_statement_ptr(temp_ident, null<ast_node>())
// have to pass false to the declaration generator, so can't do it through generate_statement
call_string.pre += generate_declaration_statement(declaration, enclosing_object, enclosing_func, false).one_string() + ";\n"
pre_call = generate_identifier(temp_ident, enclosing_object, enclosing_func).one_string()
@@ -801,17 +801,17 @@ obj c_generator (Object) {
return string("impossible type") + indirection
}
fun get_name(node: *ast_node): string {
var maybe_it = ast_name_map.get_ptr_or_null(node);
if (maybe_it)
return *maybe_it
/*var maybe_it = ast_name_map.get_ptr_or_null(node);*/
/*if (maybe_it)*/
/*return *maybe_it*/
var result = string("impossible name")
var make_unique = true
match (*node) {
ast_node::type_def(backing) {
var upper = backing.scope[string("~enclosing_scope")][0]
/*var upper = backing.scope[string("~enclosing_scope")][0]*/
result = cify_name(backing.name)
if (is_template(upper))
upper->template.instantiated_map.reverse_get(node).for_each(fun(t: ref type) result += string("_") + type_decoration(&t);)
/*if (is_template(upper))*/
/*upper->template.instantiated_map.reverse_get(node).for_each(fun(t: ref type) result += string("_") + type_decoration(&t);)*/
}
ast_node::adt_def(backing) {
error("shouldn't have adt")
@@ -823,15 +823,15 @@ obj c_generator (Object) {
make_unique = false
} else {
result = "fun_"
var upper = backing.scope.get_with_default(string("~enclosing_scope"), vector(null<ast_node>()))[0]
if (upper && is_type_def(upper))
result += get_name(upper) + "_"
/*var upper = backing.scope.get_with_default(string("~enclosing_scope"), vector(null<ast_node>()))[0]*/
/*if (upper && is_type_def(upper))*/
/*result += get_name(upper) + "_"*/
result += cify_name(node->function.name)
node->function.parameters.for_each(fun(param: *ast_node) result += string("_") + type_decoration(param->identifier.type);)
/*node->function.parameters.for_each(fun(param: *ast_node) result += string("_") + type_decoration(param->identifier.type);)*/
}
}
ast_node::identifier(backing) {
if (backing.name == "this")
if (backing.name == "this" || backing.is_extern)
make_unique = false
result = backing.name
}
@@ -839,9 +839,13 @@ obj c_generator (Object) {
if (result == "impossible name")
error("HUGE PROBLEMS")
// TODO keyword avoid seems not to work
if (make_unique && (ast_name_map.contains_value(result) || c_keyword_avoid.contains(result)))
result += get_id()
ast_name_map.set(node, result)
/*if (make_unique && (ast_name_map.contains_value(result) || c_keyword_avoid.contains(result)))*/
/*result += get_id()*/
if (make_unique)
result += to_string(hash(node)) + "_end_of_hash"
/*println("the hash of the node is: " + to_string(hash(node)))*/
/*println("the result of the node is: " + result)*/
/*ast_name_map.set(node, result)*/
return result
}
fun cify_name(name: string): string {

View File

@@ -60,7 +60,7 @@ fun defer_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_t
if (get_ast_type(enclosing_function_stack.top())->return_type->is_ref)
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)
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>()))
block->code_block.children.add(assign_or_copy_construct_statement(temp_return, return_value))
// dereference so that the real ref can take it back
if (get_ast_type(enclosing_function_stack.top())->return_type->is_ref)

View File

@@ -595,7 +595,7 @@ fun setup_globals(name_ast_map: ref map<string, pair<*tree<symbol>,*ast_node>>):
if (is_declaration_statement(child)) {
var declaration = child->declaration_statement
var identifier = declaration.identifier->identifier
if (declaration.is_extern) {
if (identifier.is_extern) {
if (identifier.name == "stderr") {
var stderr_type = type_ptr(base_type::void_return(), 1)
var stderr_pointer = malloc(type_size(stderr_type))

View File

@@ -42,7 +42,7 @@ fun obj_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_
backing.condition = ast_value_ptr(string("true"), type_ptr(base_type::boolean()))
// objects do not coerce to booleans, so it should be ok for this not to be a ref
var condition_ident = ast_identifier_ptr("condition_temp", get_ast_type(condition), backing.statement)
backing.statement->code_block.children.add(0, ast_declaration_statement_ptr(condition_ident, condition, false))
backing.statement->code_block.children.add(0, ast_declaration_statement_ptr(condition_ident, condition))
var condition_if = ast_if_statement_ptr(make_operator_call("!", vector(condition_ident)))
condition_if->if_statement.then_part = ast_branching_statement_ptr(branching_type::break_stmt())
backing.statement->code_block.children.add(1, condition_if)
@@ -53,7 +53,7 @@ fun obj_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_
backing.init = null<ast_node>()
// the do_update goes in the block above the for
var update_ident = ast_identifier_ptr("do_update", type_ptr(base_type::boolean()), parent_chain->top())
add_before_in(ast_declaration_statement_ptr(update_ident, ast_value_ptr(string("false"), type_ptr(base_type::boolean())), false),
add_before_in(ast_declaration_statement_ptr(update_ident, ast_value_ptr(string("false"), type_ptr(base_type::boolean()))),
node, parent_chain->top())
var update_if = ast_if_statement_ptr(update_ident)
update_if->if_statement.then_part = ast_code_block_ptr(backing.update)
@@ -65,7 +65,7 @@ fun obj_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_
backing.condition = ast_value_ptr(string("true"), type_ptr(base_type::boolean()))
// objects do not coerce to booleans, so it should be ok for this not to be a ref
var condition_ident = ast_identifier_ptr("condition_temp", get_ast_type(condition), backing.body)
backing.body->code_block.children.add(2, ast_declaration_statement_ptr(condition_ident, condition, false))
backing.body->code_block.children.add(2, ast_declaration_statement_ptr(condition_ident, condition))
var condition_if = ast_if_statement_ptr(make_operator_call("!", vector(condition_ident)))
condition_if->if_statement.then_part = ast_branching_statement_ptr(branching_type::break_stmt())
backing.body->code_block.children.add(3, condition_if)
@@ -92,7 +92,7 @@ fun obj_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_
if (func_name == "||" || func_name == "&&") {
var enclosing_block_idx = parent_chain->index_from_top_satisfying(fun(i: *ast_node): bool return is_code_block(i);)
var short_circuit_result = ast_identifier_ptr("short_circut_result", type_ptr(base_type::boolean()), parent_chain->from_top(enclosing_block_idx))
var short_circuit_declaration = ast_declaration_statement_ptr(short_circuit_result, backing.parameters[0], false)
var short_circuit_declaration = ast_declaration_statement_ptr(short_circuit_result, backing.parameters[0])
var condition = short_circuit_result
if (func_name == "||")
condition = make_operator_call("!", vector(condition))
@@ -147,7 +147,7 @@ fun obj_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_
var param_type = get_ast_type(param)
if (!in_function_param_type->is_ref && param_type->indirection == 0 && (param_type->is_object() && has_method(param_type->type_def, "copy_construct", vector(param_type->clone_with_indirection(1))))) {
var temp_ident = ast_identifier_ptr("temporary_param_boom", param_type->clone_without_ref(), null<ast_node>())
var declaration = ast_declaration_statement_ptr(temp_ident, null<ast_node>(), false)
var declaration = ast_declaration_statement_ptr(temp_ident, null<ast_node>())
var copy_in = make_method_call(temp_ident, "copy_construct", vector(make_operator_call("&", vector(param))))
add_before_in(declaration, replace_before, replace_in)
add_before_in(copy_in, replace_before, replace_in)
@@ -157,7 +157,7 @@ fun obj_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_
var func_return_type = func_type->return_type
if (!func_return_type->is_ref && func_return_type->indirection == 0 && (func_return_type->is_object() && has_method(func_return_type->type_def, "destruct", vector<*type>()))) {
var temp_return = ast_identifier_ptr("temporary_return_boomchaka", func_return_type, null<ast_node>())
var declaration = ast_declaration_statement_ptr(temp_return, node, false)
var declaration = ast_declaration_statement_ptr(temp_return, node)
add_before_in(declaration, replace_before, replace_in)
add_before_in(ast_defer_statement_ptr(make_method_call(temp_return, "destruct", vector<*ast_node>())),
replace_before, replace_in)
@@ -188,7 +188,7 @@ fun obj_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_
if (!ident_type->is_ref && ident_type->indirection == 0 && ident_type->is_object()) {
if (backing.expression && has_method(ident_type->type_def, "copy_construct", vector(get_ast_type(backing.expression)->clone_with_increased_indirection()))) {
var temp_cpy_ctst = ast_identifier_ptr("temp_declaration_copy_construct", get_ast_type(backing.expression)->clone_without_ref(), null<ast_node>())
var declaration = ast_declaration_statement_ptr(temp_cpy_ctst, backing.expression, false)
var declaration = ast_declaration_statement_ptr(temp_cpy_ctst, backing.expression)
add_after_in(make_method_call(backing.identifier, "copy_construct", vector(make_operator_call("&", vector(temp_cpy_ctst)))),
node, parent_chain->top())
// do second so the order's right

View File

@@ -47,18 +47,28 @@ fun min<T>(a: T, b: T): T {
return a;
}
fun hash<T(Hashable)>(item: T): ulong return item.hash()
fun hash<T>(item: *T): ulong return (item) cast ulong
fun hash(item: char): ulong return (item) cast ulong
fun hash(item: uchar): ulong return (item) cast ulong
fun hash(item: short): ulong return (item) cast ulong
fun hash(item: ushort): ulong return (item) cast ulong
fun hash(item: int): ulong return (item) cast ulong
fun hash(item: uint): ulong return (item) cast ulong
fun hash(item: long): ulong return (item) cast ulong
fun hash(item: ulong): ulong return (item) cast ulong
// default hash
fun hash<T>(item: T): ulong {
var h = hash_first(item)
/*h ^= h >> 16*/
/*h *= 0x85ebca6b*/
/*h ^= h >> 13*/
/*h *= 0xc2b2ae35*/
/*h ^= h >> 16*/
return h
}
fun hash_first<T(Hashable)>(item: T): ulong return item.hash()
fun hash_first<T>(item: *T): ulong return (item) cast ulong
fun hash_first(item: char): ulong return (item) cast ulong
fun hash_first(item: uchar): ulong return (item) cast ulong
fun hash_first(item: short): ulong return (item) cast ulong
fun hash_first(item: ushort): ulong return (item) cast ulong
fun hash_first(item: int): ulong return (item) cast ulong
fun hash_first(item: uint): ulong return (item) cast ulong
fun hash_first(item: long): ulong return (item) cast ulong
fun hash_first(item: ulong): ulong return (item) cast ulong
// default hash
fun hash_first<T>(item: T): ulong {
io::println("using empty hash - please do not do!")
return (0) cast ulong
}