diff --git a/krakenGrammer.kgm b/krakenGrammer.kgm index e85810c..da5fcc9 100644 --- a/krakenGrammer.kgm +++ b/krakenGrammer.kgm @@ -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])+" ; diff --git a/stdlib/adt_lower.krak b/stdlib/adt_lower.krak index c674cc9..4c4132c 100644 --- a/stdlib/adt_lower.krak +++ b/stdlib/adt_lower.krak @@ -29,16 +29,16 @@ fun adt_lower(name_ast_map: *map,*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(), false)) + option_union->type_def.variables.add(ast_declaration_statement_ptr(opt, null())) 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(), false)) + replacement->type_def.variables.add(ast_declaration_statement_ptr(option_union_ident, null())) 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(), false)) + replacement->type_def.variables.add(ast_declaration_statement_ptr(flag, null())) 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,*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(), false)) + block->code_block.children.add(ast_declaration_statement_ptr(to_ret, null())) 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,*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(), false)) + block->code_block.children.add(ast_declaration_statement_ptr(holder, null())) 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,*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 diff --git a/stdlib/ast_nodes.krak b/stdlib/ast_nodes.krak index d837919..db98ba0 100644 --- a/stdlib/ast_nodes.krak +++ b/stdlib/ast_nodes.krak @@ -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() ptr->copy_construct(&ast_node::identifier(to_ret)) return ptr @@ -164,11 +167,13 @@ obj identifier (Object) { var scope: map> 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() 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() - 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 { diff --git a/stdlib/ast_transformation.krak b/stdlib/ast_transformation.krak index 0d98dfc..ab1024e 100644 --- a/stdlib/ast_transformation.krak +++ b/stdlib/ast_transformation.krak @@ -631,7 +631,7 @@ obj ast_transformation (Object) { var expression_syntax_node = get_node("boolean_expression", node) var expression = null() // 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(), scope) + var identifier = ast_identifier_ptr(name, null(), scope, get_node("\"ext\"", node) != null>()) 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>()) + 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): *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 diff --git a/stdlib/c_generator.krak b/stdlib/c_generator.krak index 55b45ce..b9bd3a7 100644 --- a/stdlib/c_generator.krak +++ b/stdlib/c_generator.krak @@ -76,7 +76,7 @@ obj code_triple (Object) { obj c_generator (Object) { var id_counter: int var ast_to_syntax: map<*ast_node, *tree> - var ast_name_map: map<*ast_node, string> + /*var ast_name_map: hash_map<*ast_node, string>*/ var closure_struct_map: map, string> var function_type_map: map 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()) - var declaration = ast_declaration_statement_ptr(temp_ident, null(), false) + var declaration = ast_declaration_statement_ptr(temp_ident, null()) // 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(), null(), 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()) - var declaration = ast_declaration_statement_ptr(temp_ident, null(), false) + var temp_ident = ast_identifier_ptr(string("temporary_return")+get_id() + "temporary_end1", func_return_type, null()) + var declaration = ast_declaration_statement_ptr(temp_ident, null()) // 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()) - var declaration = ast_declaration_statement_ptr(temp_ident, null(), false) + var temp_ident = ast_identifier_ptr(string("temporary_return")+get_id() + "temporary_end2", func_return_type, null()) + var declaration = ast_declaration_statement_ptr(temp_ident, null()) // 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()))[0] - if (upper && is_type_def(upper)) - result += get_name(upper) + "_" + /*var upper = backing.scope.get_with_default(string("~enclosing_scope"), vector(null()))[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 { diff --git a/stdlib/defer_lower.krak b/stdlib/defer_lower.krak index 83447ae..36f6b13 100644 --- a/stdlib/defer_lower.krak +++ b/stdlib/defer_lower.krak @@ -60,7 +60,7 @@ fun defer_lower(name_ast_map: *map,*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(), false)) + block->code_block.children.add(ast_declaration_statement_ptr(temp_return, null())) 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) diff --git a/stdlib/interpreter.krak b/stdlib/interpreter.krak index 683bfda..50dd110 100644 --- a/stdlib/interpreter.krak +++ b/stdlib/interpreter.krak @@ -595,7 +595,7 @@ fun setup_globals(name_ast_map: ref map,*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)) diff --git a/stdlib/obj_lower.krak b/stdlib/obj_lower.krak index 4fc458a..ca66f7c 100644 --- a/stdlib/obj_lower.krak +++ b/stdlib/obj_lower.krak @@ -42,7 +42,7 @@ fun obj_lower(name_ast_map: *map,*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,*ast_node>>, ast_to_ backing.init = null() // 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,*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,*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,*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()) - var declaration = ast_declaration_statement_ptr(temp_ident, null(), false) + var declaration = ast_declaration_statement_ptr(temp_ident, null()) 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,*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()) - 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,*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()) - 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 diff --git a/stdlib/util.krak b/stdlib/util.krak index dca1361..c05d8c1 100644 --- a/stdlib/util.krak +++ b/stdlib/util.krak @@ -47,18 +47,28 @@ fun min(a: T, b: T): T { return a; } -fun hash(item: T): ulong return item.hash() -fun hash(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(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(item: T): ulong return item.hash() +fun hash_first(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(item: T): ulong { io::println("using empty hash - please do not do!") return (0) cast ulong }