diff --git a/code/demo.odin b/code/demo.odin index 91f3e132e..4c5039f13 100644 --- a/code/demo.odin +++ b/code/demo.odin @@ -19,6 +19,7 @@ import ( */ ) + general_stuff :: proc() { // Complex numbers a := 3 + 4i; @@ -316,7 +317,7 @@ explicit_parametric_polymorphic_procedures :: proc() { } new_batch := new(EntityBatch); - append(manager.batches, new_batch); + append(&manager.batches, new_batch); new_batch.batch_index = u32(len(manager.batches)-1); return use_empty_slot(manager, new_batch); @@ -324,14 +325,14 @@ explicit_parametric_polymorphic_procedures :: proc() { - new_entity :: proc(manager: ^EntityManager, T: type, x, y: int) -> ^T { + new_entity :: proc(manager: ^EntityManager, T: type, x, y: f32) -> ^T { result := new(T); result.entity = gen_new_entity(manager); result.derived.data = result; result.derived.type_info = type_info(T); - result.position.x = f32(x); - result.position.y = f32(y); + result.position.x = x; + result.position.y = y; return result; } @@ -352,7 +353,7 @@ explicit_parametric_polymorphic_procedures :: proc() { T = Monster, ); - append(entities, rock, door, monster); + append(&entities, rock, door, monster); // An alternative to `union`s for entity in entities { @@ -365,7 +366,32 @@ explicit_parametric_polymorphic_procedures :: proc() { } +pop :: proc(array: ^[]$T) -> T { + last: T; + if len(array) == 0 { + panic("Attempt to pop an empty slice"); + return last; + } + + last = array[len(array)-1]; + ^raw.Slice(array).len -= 1; + return last; +} +pop :: proc(a: ^[dynamic]$T) -> T { + last: T; + if len(a) == 0 { + panic("Attempt to pop an empty dynamic array"); + return last; + } + + last = array[len(array)-1]; + ^raw.DynamicArray(array).len -= 1; + return last; +} + + main :: proc() { +when true { foo :: proc(x: i64, y: f32) do fmt.println("#1", x, y); foo :: proc(x: type, y: f32) do fmt.println("#2", type_info(x), y); foo :: proc(x: type) do fmt.println("#3", type_info(x)); @@ -375,7 +401,6 @@ main :: proc() { f(y = 3785.1546, x = 123); f(x = int, y = 897.513); f(x = f32); -/* general_stuff(); foreign_blocks(); default_arguments(); @@ -402,7 +427,7 @@ main :: proc() { fmt.printf("The program \"%s\" calculates the value %d\n", program, accumulator); -*/ +} } diff --git a/core/_preload.odin b/core/_preload.odin index 94ce0d8f6..70532fa4e 100644 --- a/core/_preload.odin +++ b/core/_preload.odin @@ -255,50 +255,51 @@ resize :: proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_AL return a.procedure(a.data, AllocatorMode.Resize, new_size, alignment, ptr, old_size, 0); } -// append :: proc(s: ^[]$T, args: ..T) -> int { -// if s == nil { -// return 0; -// } -// slice := ^raw.Slice(s); -// arg_len := len(args); -// if arg_len <= 0 { -// return slice.len; -// } -// arg_len = min(slice.cap-slice.len, arg_len); -// if arg_len > 0 { -// data := ^T(slice.data); -// assert(data != nil); -// sz :: size_of(T); -// __mem_copy(data + slice.len, &args[0], sz*arg_len); -// slice.len += arg_len; -// } -// return slice.len; -// } +append :: proc(array: ^[]$T, args: ..T) -> int { + if array == nil { + return 0; + } + slice := ^raw.Slice(array); + arg_len := len(args); + if arg_len <= 0 { + return slice.len; + } -// append :: proc(a: ^[dynamic]$T, args: ..T) -> int { -// array := ^raw.DynamicArray(a); + arg_len = min(slice.cap-slice.len, arg_len); + if arg_len > 0 { + data := ^T(slice.data); + assert(data != nil); + sz :: size_of(T); + __mem_copy(data + slice.len, &args[0], sz*arg_len); + slice.len += arg_len; + } + return slice.len; +} -// arg_len := len(args); -// if arg_len <= 0 || items == nil { -// return array.len; -// } +append :: proc(array_: ^[dynamic]$T, args: ..T) -> int { + array := ^raw.DynamicArray(array_); + + arg_len := len(args); + if arg_len <= 0 { + return array.len; + } -// ok := true; -// if array.cap <= array.len+arg_len { -// cap := 2 * array.cap + max(8, arg_len); -// ok = __dynamic_array_reserve(array, size_of(T), align_of(T), cap); -// } -// // TODO(bill): Better error handling for failed reservation -// if !ok do return array.len; + ok := true; + if array.cap <= array.len+arg_len { + cap := 2 * array.cap + max(8, arg_len); + ok = __dynamic_array_reserve(array, size_of(T), align_of(T), cap); + } + // TODO(bill): Better error handling for failed reservation + if !ok do return array.len; -// data := ^T(array.data); -// assert(data != nil); -// __mem_copy(data + array.len, items, size_of(T) * arg_len); -// array.len += arg_len; -// return array.len; -// } + data := ^T(array.data); + assert(data != nil); + __mem_copy(data + array.len, &args[0], size_of(T) * arg_len); + array.len += arg_len; + return array.len; +} copy :: proc(dst, src: []$T) -> int #cc_contextless { n := max(0, min(len(dst), len(src))); @@ -309,12 +310,10 @@ copy :: proc(dst, src: []$T) -> int #cc_contextless { new :: proc(T: type) -> ^T #inline do return ^T(alloc(size_of(T), align_of(T))); -/* free :: proc(array: [dynamic]$T) do free_ptr(^raw.DynamicArray(&array).data); free :: proc(slice: []$T) do free_ptr(^raw.Slice(&slice).data); free :: proc(str: string) do free_ptr(^raw.String(&str).data); free :: proc(ptr: rawptr) do free_ptr(ptr); -*/ @@ -814,7 +813,6 @@ __dynamic_map_add_entry :: proc(using h: __MapHeader, key: __MapKey) -> int { return prev; } - __dynamic_map_delete :: proc(using h: __MapHeader, key: __MapKey) { fr := __dynamic_map_find(h, key); if fr.entry_index >= 0 { diff --git a/core/fmt.odin b/core/fmt.odin index 499c5e1dc..2953adf00 100644 --- a/core/fmt.odin +++ b/core/fmt.odin @@ -70,17 +70,17 @@ write_string :: proc(buf: ^StringBuffer, s: string) { write_bytes :: proc(buf: ^StringBuffer, data: []u8) { match b in buf { case StringBuffer.Static: - append(b.buf, ..data); + append(&b.buf, ..data); case StringBuffer.Dynamic: - append(b.buf, ..data); + append(&b.buf, ..data); } } write_byte :: proc(buf: ^StringBuffer, data: u8) { match b in buf { case StringBuffer.Static: - append(b.buf, data); + append(&b.buf, data); case StringBuffer.Dynamic: - append(b.buf, data); + append(&b.buf, data); } } write_rune :: proc(buf: ^StringBuffer, r: rune) { @@ -484,7 +484,7 @@ fmt_bool :: proc(using fi: ^FmtInfo, b: bool, verb: rune) { fmt_write_padding :: proc(fi: ^FmtInfo, width: int) { if width <= 0 do return; - pad_byte: u8 = fi.space ? ' ' : '0'; + pad_byte := u8(fi.space ? ' ' : '0'); data := string_buffer_data(fi.buf^); count := min(width, cap(data)-len(data)); diff --git a/core/os_windows.odin b/core/os_windows.odin index 38d16a262..ccc0eb9f8 100644 --- a/core/os_windows.odin +++ b/core/os_windows.odin @@ -103,8 +103,8 @@ open :: proc(path: string, mode: int = O_RDONLY, perm: u32 = 0) -> (Handle, Errn handle := Handle(win32.create_file_a(&buf[0], access, share_mode, sa, create_mode, win32.FILE_ATTRIBUTE_NORMAL, nil)); if handle != INVALID_HANDLE do return handle, ERROR_NONE; - err := win32.get_last_error(); - return INVALID_HANDLE, Errno(err); + err := Errno(win32.get_last_error()); + return INVALID_HANDLE, err; } close :: proc(fd: Handle) { @@ -126,8 +126,8 @@ write :: proc(fd: Handle, data: []u8) -> (int, Errno) { e := win32.write_file(win32.Handle(fd), &data[total_write], to_write, &single_write_length, nil); if single_write_length <= 0 || e == win32.FALSE { - err := win32.get_last_error(); - return int(total_write), Errno(e); + err := Errno(win32.get_last_error()); + return int(total_write), err; } total_write += i64(single_write_length); } @@ -148,8 +148,8 @@ read :: proc(fd: Handle, data: []u8) -> (int, Errno) { e := win32.read_file(win32.Handle(fd), &data[total_read], to_read, &single_read_length, nil); if single_read_length <= 0 || e == win32.FALSE { - err := win32.get_last_error(); - return int(total_read), Errno(e); + err := Errno(win32.get_last_error()); + return int(total_read), err; } total_read += i64(single_read_length); } @@ -170,8 +170,8 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) { dw_ptr := win32.set_file_pointer(win32.Handle(fd), lo, &hi, w); if dw_ptr == win32.INVALID_SET_FILE_POINTER { - err := win32.get_last_error(); - return 0, Errno(err); + err := Errno(win32.get_last_error()); + return 0, err; } return i64(hi)<<32 + i64(dw_ptr), ERROR_NONE; } diff --git a/core/strconv.odin b/core/strconv.odin index 94b76da75..d3d6d193b 100644 --- a/core/strconv.odin +++ b/core/strconv.odin @@ -191,7 +191,7 @@ parse_f64 :: proc(s: string) -> f64 { append_bool :: proc(buf: []u8, b: bool) -> string { s := b ? "true" : "false"; - append(buf, ..[]u8(s)); + append(&buf, ..[]u8(s)); return string(buf); } @@ -257,7 +257,7 @@ generic_ftoa :: proc(buf: []u8, val: f64, fmt: u8, prec, bit_size: int) -> []u8 } else { s = "+Inf"; } - append(buf, ..[]u8(s)); + append(&buf, ..[]u8(s)); return buf; case 0: // denormalized @@ -304,29 +304,29 @@ generic_ftoa :: proc(buf: []u8, val: f64, fmt: u8, prec, bit_size: int) -> []u8 format_digits :: proc(buf: []u8, shortest: bool, neg: bool, digs: DecimalSlice, prec: int, fmt: u8) -> []u8 { match fmt { case 'f', 'F': - append(buf, neg ? '-' : '+'); + append(&buf, neg ? '-' : '+'); // integer, padded with zeros when needed if digs.decimal_point > 0 { m := min(digs.count, digs.decimal_point); - append(buf, ..digs.digits[0.. 0 { - append(buf, '.'); + append(&buf, '.'); for i in 0..kind = Entity_TypeName; DeclInfo *d = c->context.decl; + if (d->type_expr != NULL) { + error(e->token, "A type declaration cannot have an type parameter"); + } d->type_expr = d->init_expr; check_type_decl(c, e, d->type_expr, named_type); return; @@ -433,7 +436,7 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) { } if (is_foreign) { - error(e->token, "A foreign procedures cannot be a polymorphic"); + error(e->token, "A foreign procedure cannot be a polymorphic"); return; } } @@ -443,13 +446,15 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) { error(pl->body, "A foreign procedure cannot have a body"); } if (proc_type->Proc.c_vararg) { - error(pl->body, "A procedure with a `#c_vararg` field cannot have a body"); + error(pl->body, "A procedure with a `#c_vararg` field cannot have a body and must be foreign"); } d->scope = c->context.scope; GB_ASSERT(pl->body->kind == AstNode_BlockStmt); - check_procedure_later(c, c->curr_ast_file, e->token, d, proc_type, pl->body, pl->tags); + if (!pt->is_polymorphic) { + check_procedure_later(c, c->curr_ast_file, e->token, d, proc_type, pl->body, pl->tags); + } } else if (!is_foreign) { error(e->token, "Only a foreign procedure cannot have a body"); } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index b2dd98fa9..38c1a0477 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -193,6 +193,11 @@ i64 check_distance_between_types(Checker *c, Operand *operand, Type *type) { if (check_representable_as_constant(c, operand->value, dst, NULL)) { if (is_type_typed(dst) && src->kind == Type_Basic) { switch (src->Basic.kind) { + case Basic_UntypedRune: + if (is_type_integer(dst) || is_type_rune(dst)) { + return 1; + } + break; case Basic_UntypedInteger: if (is_type_integer(dst) || is_type_rune(dst)) { return 1; @@ -214,6 +219,15 @@ i64 check_distance_between_types(Checker *c, Operand *operand, Type *type) { } return -1; } + if (src->kind == Type_Basic && src->Basic.kind == Basic_UntypedRune) { + if (is_type_integer(dst) || is_type_rune(dst)) { + if (is_type_typed(type)) { + return 2; + } + return 1; + } + return -1; + } if (src->kind == Type_Basic && src->Basic.kind == Basic_UntypedBool) { if (is_type_boolean(dst)) { if (is_type_typed(type)) { @@ -1098,8 +1112,7 @@ bool is_polymorphic_type_assignable(Checker *c, Type *poly, Type *source, bool c } case Type_Pointer: if (source->kind == Type_Pointer) { - if (compound) return are_types_identical(poly, source); - return check_is_assignable_to(c, &o, poly); + return is_polymorphic_type_assignable(c, poly->Pointer.elem, source->Atomic.elem, true, modify_type); } return false; case Type_Atomic: @@ -3983,10 +3996,10 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id bool vari_expand = (ce->ellipsis.pos.line != 0); - if (vari_expand && id != BuiltinProc_append) { + // if (vari_expand && id != BuiltinProc_append) { // error(ce->ellipsis, "Invalid use of `..` with built-in procedure `append`"); - return false; - } + // return false; + // } switch (id) { @@ -4268,6 +4281,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id operand->mode = Addressing_NoValue; } break; + #if 0 case BuiltinProc_append: { // proc append([dynamic]Type, item: ..Type) // proc append([]Type, item: ..Type) @@ -4315,6 +4329,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id operand->mode = Addressing_Value; operand->type = t_int; } break; + #endif case BuiltinProc_delete: { // proc delete(map[Key]Value, key: Key) @@ -5155,6 +5170,7 @@ Entity *find_or_generate_polymorphic_procedure(Checker *c, AstNode *call, Entity Scope *scope = make_scope(base_entity->scope, a); scope->is_proc = true; c->context.scope = scope; + c->context.allow_polymorphic_types = true; bool generate_type_again = c->context.no_polymorphic_errors; @@ -5219,6 +5235,7 @@ Entity *find_or_generate_polymorphic_procedure(Checker *c, AstNode *call, Entity // NOTE(bill): Associate the scope declared above with this procedure declaration's type add_scope(c, pl->type, final_proc_type->Proc.scope); final_proc_type->Proc.is_poly_specialized = true; + final_proc_type->Proc.is_polymorphic = true; u64 tags = base_entity->Procedure.tags; AstNode *ident = clone_ast_node(a, base_entity->identifier); @@ -5236,17 +5253,24 @@ Entity *find_or_generate_polymorphic_procedure(Checker *c, AstNode *call, Entity // NOTE(bill): Set the scope afterwards as this is not real overloading entity->scope = scope->parent; - ProcedureInfo proc_info = {}; - if (success) { - proc_info.file = c->curr_ast_file; - proc_info.token = token; - proc_info.decl = d; - proc_info.type = final_proc_type; - proc_info.body = pl->body; - proc_info.tags = tags; - proc_info.generated_from_polymorphic = true; + AstFile *file = NULL; + { + Scope *s = entity->scope; + while (s != NULL && s->file == NULL) { + s = s->parent; + } + file = s->file; } + ProcedureInfo proc_info = {}; + proc_info.file = file; + proc_info.token = token; + proc_info.decl = d; + proc_info.type = final_proc_type; + proc_info.body = pl->body; + proc_info.tags = tags; + proc_info.generated_from_polymorphic = true; + if (found_gen_procs) { array_add(found_gen_procs, entity); } else { @@ -5436,6 +5460,10 @@ CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { } } + if (gen_entity != NULL && gen_entity->token.string == "append" && err != CallArgumentError_None) { + gb_printf_err("append %s with score %lld %d\n", type_to_string(final_proc_type), score, err); + } + if (gen_entity != NULL && err == CallArgumentError_None) { if (proc_info.decl != NULL) { // NOTE(bill): Check the newly generated procedure body @@ -5690,11 +5718,13 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t Entity *p = procs[i]; Type *pt = base_type(p->type); if (pt != NULL && is_type_proc(pt)) { + CallArgumentError err = CallArgumentError_None; CallArgumentData data = {}; - bool prev = c->context.no_polymorphic_errors; - defer (c->context.no_polymorphic_errors = prev); + CheckerContext prev_context = c->context; c->context.no_polymorphic_errors = true; - CallArgumentError err = call_checker(c, call, pt, p, operands, CallArgumentMode_NoErrors, &data); + c->context.allow_polymorphic_types = is_type_polymorphic(pt); + err = call_checker(c, call, pt, p, operands, CallArgumentMode_NoErrors, &data); + c->context = prev_context; if (err == CallArgumentError_None) { valids[valid_count].index = i; @@ -5747,24 +5777,39 @@ CallArgumentData check_call_arguments(Checker *c, Operand *operand, Type *proc_t } result_type = t_invalid; } else { - AstNode *expr = operand->expr; - while (expr->kind == AstNode_SelectorExpr) { - expr = expr->SelectorExpr.selector; + AstNode *ident = operand->expr; + while (ident->kind == AstNode_SelectorExpr) { + AstNode *s = ident->SelectorExpr.selector; + ident = s; } - GB_ASSERT(expr->kind == AstNode_Ident); + Entity *e = procs[valids[0].index]; - add_entity_use(c, expr, e); + proc_type = e->type; CallArgumentData data = {}; CallArgumentError err = call_checker(c, call, proc_type, e, operands, CallArgumentMode_ShowErrors, &data); - if (data.gen_entity != NULL) add_entity_use(c, ce->proc, data.gen_entity); + if (data.gen_entity != NULL) { + add_entity_use(c, ident, data.gen_entity); + } else { + add_entity_use(c, ident, e); + } return data; } } else { - Entity *e = entity_of_ident(&c->info, operand->expr); + AstNode *ident = operand->expr; + while (ident->kind == AstNode_SelectorExpr) { + AstNode *s = ident->SelectorExpr.selector; + ident = s; + } + + Entity *e = entity_of_ident(&c->info, ident); CallArgumentData data = {}; CallArgumentError err = call_checker(c, call, proc_type, e, operands, CallArgumentMode_ShowErrors, &data); - if (data.gen_entity != NULL) add_entity_use(c, ce->proc, data.gen_entity); + if (data.gen_entity != NULL) { + add_entity_use(c, ident, data.gen_entity); + } else { + add_entity_use(c, ident, e); + } return data; } @@ -5908,9 +5953,6 @@ ExprKind check_call_expr(Checker *c, Operand *operand, AstNode *call) { CallArgumentData data = check_call_arguments(c, operand, proc_type, call); Type *result_type = data.result_type; - if (data.gen_entity != NULL) { - add_entity_use(c, ce->proc, data.gen_entity); - } gb_zero_item(operand); operand->expr = call; @@ -7130,6 +7172,15 @@ gbString write_expr_to_string(gbString str, AstNode *node) { str = write_expr_to_string(str, be->right); case_end; + case_ast_node(te, TernaryExpr, node); + str = write_expr_to_string(str, te->cond); + str = gb_string_appendc(str, " ? "); + str = write_expr_to_string(str, te->x); + str = gb_string_appendc(str, " : "); + str = write_expr_to_string(str, te->y); + case_end; + + case_ast_node(pe, ParenExpr, node); str = gb_string_appendc(str, "("); str = write_expr_to_string(str, pe->expr); @@ -7171,6 +7222,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) { case_ast_node(e, Ellipsis, node); str = gb_string_appendc(str, ".."); + str = write_expr_to_string(str, e->expr); case_end; case_ast_node(fv, FieldValue, node); @@ -7184,6 +7236,12 @@ gbString write_expr_to_string(gbString str, AstNode *node) { str = write_expr_to_string(str, ht->type); case_end; + + case_ast_node(pt, PolyType, node); + str = gb_string_appendc(str, "$"); + str = write_expr_to_string(str, pt->type); + case_end; + case_ast_node(pt, PointerType, node); str = gb_string_appendc(str, "^"); str = write_expr_to_string(str, pt->type); @@ -7203,7 +7261,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) { case_end; case_ast_node(at, DynamicArrayType, node); - str = gb_string_appendc(str, "[..]"); + str = gb_string_appendc(str, "[dynamic]"); str = write_expr_to_string(str, at->elem); case_end; @@ -7235,9 +7293,6 @@ gbString write_expr_to_string(gbString str, AstNode *node) { if (f->names.count > 0) { str = gb_string_appendc(str, ": "); } - if (f->flags&FieldFlag_ellipsis) { - str = gb_string_appendc(str, ".."); - } str = write_expr_to_string(str, f->type); case_end; @@ -7261,7 +7316,6 @@ gbString write_expr_to_string(gbString str, AstNode *node) { } } - for_array(i, f->list) { if (i > 0) { str = gb_string_appendc(str, ", "); diff --git a/src/checker.cpp b/src/checker.cpp index 3586f7986..6ea755d38 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -33,7 +33,7 @@ enum BuiltinProcId { BuiltinProc_reserve, BuiltinProc_clear, - BuiltinProc_append, + // BuiltinProc_append, BuiltinProc_delete, BuiltinProc_size_of, @@ -85,7 +85,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT("reserve"), 2, false, Expr_Stmt}, {STR_LIT("clear"), 1, false, Expr_Stmt}, - {STR_LIT("append"), 1, true, Expr_Expr}, + // {STR_LIT("append"), 1, true, Expr_Expr}, {STR_LIT("delete"), 2, false, Expr_Stmt}, {STR_LIT("size_of"), 1, false, Expr_Expr}, @@ -591,11 +591,9 @@ Entity *scope_insert_entity(Scope *s, Entity *entity) { } } - if (prev != NULL && - entity->kind == Entity_Procedure) { - if (s->is_global) { - return prev; - } + if (prev != NULL && entity->kind == Entity_Procedure) { + // if (s->is_global) return prev; + multi_map_insert(&s->elements, key, entity); } else { map_set(&s->elements, key, entity); @@ -1709,6 +1707,9 @@ void check_collect_entities(Checker *c, Array nodes, bool is_file_sco if (is_ast_node_type(init)) { e = make_entity_type_name(c->allocator, d->scope, name->Ident.token, NULL); + if (vd->type != NULL) { + error(name, "A type declaration cannot have an type parameter"); + } d->type_expr = init; d->init_expr = init; } else if (init->kind == AstNode_ProcLit) { @@ -2285,10 +2286,9 @@ void check_parsed_files(Checker *c) { defer (c->context = prev_context); TypeProc *pt = &pi->type->Proc; + String name = pi->token.string; if (pt->is_polymorphic) { - if (pi->decl->gen_proc_type == NULL) { - continue; - } + GB_ASSERT_MSG(pt->is_poly_specialized, "%.*s", LIT(name)); } add_curr_ast_file(c, pi->file); diff --git a/src/ir.cpp b/src/ir.cpp index ed1988a5b..549e86cd3 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -4059,6 +4059,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv return NULL; } break; + #if 0 case BuiltinProc_append: { ir_emit_comment(proc, str_lit("append")); gbAllocator a = proc->module->allocator; @@ -4167,6 +4168,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv } return ir_emit_global_call(proc, "__dynamic_array_append", daa_args, 5); } break; + #endif case BuiltinProc_delete: { ir_emit_comment(proc, str_lit("delete")); @@ -7422,9 +7424,6 @@ void ir_gen_tree(irGen *s) { } } else if (check_is_entity_overloaded(e)) { name = ir_mangle_name(s, e->token.pos.file, e); - - gb_printf_err("%.*s|%.*s :: %s\n", LIT(original_name), LIT(name), type_to_string(e->type)); - } map_set(&m->entity_names, hash_entity(e), name); diff --git a/src/parser.cpp b/src/parser.cpp index 2d134d420..364f2f339 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -664,7 +664,7 @@ AstNode *clone_ast_node(gbAllocator a, AstNode *node) { n->RunExpr.expr = clone_ast_node(a, n->RunExpr.expr); break; case AstNode_UnaryExpr: - n->RunExpr.expr = clone_ast_node(a, n->RunExpr.expr); + n->UnaryExpr.expr = clone_ast_node(a, n->UnaryExpr.expr); break; case AstNode_BinaryExpr: n->BinaryExpr.left = clone_ast_node(a, n->BinaryExpr.left); diff --git a/src/types.cpp b/src/types.cpp index 8d7466a32..98aa1e73e 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -2445,7 +2445,7 @@ gbString write_type_to_string(gbString str, Type *type) { if (var->flags&EntityFlag_Ellipsis) { Type *slice = base_type(var->type); str = gb_string_appendc(str, ".."); - GB_ASSERT(is_type_slice(var->type)); + GB_ASSERT(var->type->kind == Type_Slice); str = write_type_to_string(str, slice->Slice.elem); } else { str = write_type_to_string(str, var->type);