diff --git a/core/_preload.odin b/core/_preload.odin index e0dd616b3..6fa59aa39 100644 --- a/core/_preload.odin +++ b/core/_preload.odin @@ -36,8 +36,7 @@ Calling_Convention :: enum { Type_Info_Enum_Value :: union { rune, i8, i16, i32, i64, i128, int, - u8, u16, u32, u64, u128, uint, - uintptr, + u8, u16, u32, u64, u128, uint, uintptr, f32, f64, }; @@ -915,36 +914,13 @@ __default_hash :: proc(data: []byte) -> u128 { } __default_hash_string :: proc(s: string) -> u128 do return __default_hash(cast([]byte)s); -__dynamic_map_check_init :: proc(h: __Map_Header) { - if h.m.internal == nil { - h.m.internal = new(raw.Map_Internal); - } -} - -__dynamic_map_len :: inline proc "contextless" (p: rawptr) -> int { - if m := transmute(raw.Map)p; m.internal != nil { - return m.internal.entries.len; - } - return 0; -} - -__dynamic_map_cap :: inline proc "contextless" (p: rawptr) -> int { - if m := transmute(raw.Map)p; m.internal != nil { - return m.internal.entries.cap; - } - return 0; -} - __dynamic_map_reserve :: proc(using header: __Map_Header, cap: int, loc := #caller_location) { - __dynamic_map_check_init(header); __dynamic_array_reserve(&m.hashes, size_of(int), align_of(int), cap, loc); __dynamic_array_reserve(&m.entries, entry_size, entry_align, cap, loc); } __dynamic_map_rehash :: proc(using header: __Map_Header, new_count: int, loc := #caller_location) { - __dynamic_map_check_init(header); new_header: __Map_Header = header; nm: raw.Map; - nm.internal = new(raw.Map_Internal); new_header.m = &nm; header_hashes := cast(^raw.Dynamic_Array)&header.m.hashes; @@ -982,7 +958,6 @@ __dynamic_map_rehash :: proc(using header: __Map_Header, new_count: int, loc := } __dynamic_map_get :: proc(h: __Map_Header, key: __Map_Key) -> rawptr { - __dynamic_map_check_init(h); index := __dynamic_map_find(h, key).entry_index; if index >= 0 { data := cast(^byte)__dynamic_map_get_entry(h, index); @@ -992,7 +967,6 @@ __dynamic_map_get :: proc(h: __Map_Header, key: __Map_Key) -> rawptr { } __dynamic_map_set :: proc(h: __Map_Header, key: __Map_Key, value: rawptr, loc := #caller_location) { - __dynamic_map_check_init(h); index: int; assert(value != nil); @@ -1028,13 +1002,11 @@ __dynamic_map_set :: proc(h: __Map_Header, key: __Map_Key, value: rawptr, loc := __dynamic_map_grow :: proc(using h: __Map_Header, loc := #caller_location) { - __dynamic_map_check_init(h); new_count := max(2*m.entries.cap + 8, __INITIAL_MAP_CAP); __dynamic_map_rehash(h, new_count, loc); } __dynamic_map_full :: inline proc(using h: __Map_Header) -> bool { - __dynamic_map_check_init(h); return int(0.75 * f64(len(m.hashes))) <= m.entries.cap; } @@ -1048,7 +1020,6 @@ __dynamic_map_hash_equal :: proc(h: __Map_Header, a, b: __Map_Key) -> bool { } __dynamic_map_find :: proc(using h: __Map_Header, key: __Map_Key) -> __Map_Find_Result { - __dynamic_map_check_init(h); fr := __Map_Find_Result{-1, -1, -1}; if len(m.hashes) > 0 { fr.hash_index = int(key.hash % u128(len(m.hashes))); @@ -1064,7 +1035,6 @@ __dynamic_map_find :: proc(using h: __Map_Header, key: __Map_Key) -> __Map_Find_ } __dynamic_map_add_entry :: proc(using h: __Map_Header, key: __Map_Key, loc := #caller_location) -> int { - __dynamic_map_check_init(h); prev := m.entries.len; c := __dynamic_array_append_nothing(&m.entries, entry_size, entry_align, loc); if c != prev { @@ -1076,7 +1046,6 @@ __dynamic_map_add_entry :: proc(using h: __Map_Header, key: __Map_Key, loc := #c } __dynamic_map_delete :: proc(using h: __Map_Header, key: __Map_Key) { - __dynamic_map_check_init(h); fr := __dynamic_map_find(h, key); if fr.entry_index >= 0 { __dynamic_map_erase(h, fr); @@ -1084,13 +1053,11 @@ __dynamic_map_delete :: proc(using h: __Map_Header, key: __Map_Key) { } __dynamic_map_get_entry :: proc(using h: __Map_Header, index: int) -> ^__Map_Entry_Header { - __dynamic_map_check_init(h); assert(0 <= index && index < m.entries.len); return cast(^__Map_Entry_Header)(cast(^byte)m.entries.data + index*entry_size); } __dynamic_map_erase :: proc(using h: __Map_Header, fr: __Map_Find_Result) { - __dynamic_map_check_init(h); if fr.entry_prev < 0 { m.hashes[fr.hash_index] = __dynamic_map_get_entry(h, fr.entry_index).next; } else { diff --git a/core/fmt.odin b/core/fmt.odin index 81e067282..1ca26855c 100644 --- a/core/fmt.odin +++ b/core/fmt.odin @@ -815,8 +815,9 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) { write_string(fi.buf, "map["); defer write_byte(fi.buf, ']'); - if (^raw.Map)(v.data).internal != nil { - entries := &(^raw.Map)(v.data).entries; + m := (^raw.Map)(v.data); + if m != nil { + entries := &m.entries; gs := type_info_base(info.generated_struct).variant.(Type_Info_Struct); ed := type_info_base(gs.types[1]).variant.(Type_Info_Dynamic_Array); entry_type := ed.elem.variant.(Type_Info_Struct); diff --git a/core/raw.odin b/core/raw.odin index cfa072f99..9a9f9a77b 100644 --- a/core/raw.odin +++ b/core/raw.odin @@ -20,14 +20,11 @@ Dynamic_Array :: struct { allocator: Allocator, } -Map_Internal :: struct { +Map :: struct { hashes: [dynamic]int, entries: Dynamic_Array, } -Map :: struct { - using internal: ^Map_Internal, -} make_any :: inline proc(data: rawptr, type_info: ^Type_Info) -> any { return transmute(any)Any{data, type_info}; @@ -44,3 +41,5 @@ dynamic_array_data :: inline proc(a: $T/[dynamic]$E) -> ^E { } data :: proc[string_data, slice_data, dynamic_array_data]; + + diff --git a/src/check_type.cpp b/src/check_type.cpp index 8374fd269..3736a7bca 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -1200,6 +1200,18 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *_params, bool *is_vari } } + if (p->flags&FieldFlag_in) { + if (is_type_param) { + error(param, "'in' cannot be applied to a type parameter"); + p->flags &= ~FieldFlag_in; + } else if (is_variadic) { + error(param, "'in' cannot be applied to a variadic parameter"); + p->flags &= ~FieldFlag_in; + } + } + + bool is_in = (p->flags&FieldFlag_in) != 0; + for_array(j, p->names) { AstNode *name = p->names[j]; if (!ast_node_expect(name, AstNode_Ident)) { @@ -1263,7 +1275,7 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *_params, bool *is_vari } } - param = make_entity_param(c->allocator, scope, name->Ident.token, type, is_using, false); + param = make_entity_param(c->allocator, scope, name->Ident.token, type, is_using, is_in); param->Variable.default_value = value; param->Variable.default_is_nil = default_is_nil; param->Variable.default_is_location = default_is_location; @@ -1812,7 +1824,9 @@ void generate_map_entry_type(gbAllocator a, Type *type) { void generate_map_internal_types(gbAllocator a, Type *type) { GB_ASSERT(type->kind == Type_Map); generate_map_entry_type(a, type); + if (type->Map.internal_type != nullptr) return; if (type->Map.generated_struct_type != nullptr) return; + Type *key = type->Map.key; Type *value = type->Map.value; GB_ASSERT(key != nullptr); @@ -1844,7 +1858,7 @@ void generate_map_internal_types(gbAllocator a, Type *type) { type_set_offsets(a, generated_struct_type); type->Map.generated_struct_type = generated_struct_type; - type->Map.internal_type = make_type_pointer(a, generated_struct_type); + type->Map.internal_type = generated_struct_type; type->Map.lookup_result_type = make_optional_ok_type(a, value); } diff --git a/src/ir.cpp b/src/ir.cpp index 230f8de6a..d30fb958b 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -388,9 +388,10 @@ struct irValueGlobal { enum irParamPasskind { - irParamPass_Value, // Pass by value - irParamPass_Pointer, // Pass as a pointer rather than by value - irParamPass_Integer, // Pass as an integer of the same size + irParamPass_Value, // Pass by value + irParamPass_Pointer, // Pass as a pointer rather than by value + irParamPass_Integer, // Pass as an integer of the same size + irParamPass_ConstRef, // Pass as a pointer but the value is immutable }; struct irValueParam { @@ -846,7 +847,11 @@ irValue *ir_value_param(gbAllocator a, irProcedure *parent, Entity *e, Type *abi if (abi_type != e->type) { if (is_type_pointer(abi_type)) { + GB_ASSERT(e->kind == Entity_Variable); v->Param.kind = irParamPass_Pointer; + if (e->flags&EntityFlag_Value) { + v->Param.kind = irParamPass_ConstRef; + } } else if (is_type_integer(abi_type)) { v->Param.kind = irParamPass_Integer; } else { @@ -1445,16 +1450,20 @@ irValue *ir_add_param(irProcedure *proc, Entity *e, AstNode *expr, Type *abi_typ ir_emit_store(proc, l, v); return v; } - case irParamPass_Pointer: { + case irParamPass_Pointer: ir_module_add_value(proc->module, e, v); return ir_emit_load(proc, v); - } + case irParamPass_Integer: { irValue *l = ir_add_local(proc, e, expr, false); irValue *iptr = ir_emit_conv(proc, l, make_type_pointer(proc->module->allocator, p->type)); ir_emit_store(proc, iptr, v); return ir_emit_load(proc, l); } + + case irParamPass_ConstRef: + ir_module_add_value(proc->module, e, v); + return ir_emit_load(proc, v); } GB_PANIC("Unreachable"); @@ -1570,7 +1579,7 @@ irValue *ir_emit_bitcast(irProcedure *proc, irValue *data, Type *type) { } irValue *ir_emit_transmute(irProcedure *proc, irValue *value, Type *t); - +irValue *ir_address_from_load_or_generate_local(irProcedure *proc, irValue *val); irValue *ir_find_or_generate_context_ptr(irProcedure *proc) { if (proc->context_stack.count > 0) { @@ -1605,11 +1614,16 @@ irValue *ir_emit_call(irProcedure *p, irValue *value, irValue **args, isize arg_ continue; } GB_ASSERT(e->flags & EntityFlag_Param); + Type *original_type = e->type; Type *new_type = pt->Proc.abi_compat_params[i]; if (original_type != new_type) { if (is_type_pointer(new_type)) { - args[i] = ir_copy_value_to_ptr(p, args[i], original_type, 16); + if (e->flags&EntityFlag_Value) { + args[i] = ir_address_from_load_or_generate_local(p, args[i]); + } else { + args[i] = ir_copy_value_to_ptr(p, args[i], original_type, 16); + } } else if (is_type_integer(new_type)) { args[i] = ir_emit_transmute(p, args[i], new_type); } @@ -2073,19 +2087,41 @@ irValue *ir_build_addr_ptr(irProcedure *proc, AstNode *expr) { } +irValue *ir_dynamic_array_len(irProcedure *proc, irValue *da); +irValue *ir_dynamic_array_cap(irProcedure *proc, irValue *da); -irValue *ir_map_count(irProcedure *proc, irValue *value) { - GB_ASSERT(is_type_map(ir_type(value))); - irValue **args = gb_alloc_array(proc->module->allocator, irValue *, 1); - args[0] = ir_emit_transmute(proc, value, t_rawptr); - return ir_emit_global_call(proc, "__dynamic_map_len", args, 1); + +irValue *ir_map_entries(irProcedure *proc, irValue *value) { + gbAllocator a = proc->module->allocator; + Type *t = base_type(ir_type(value)); + GB_ASSERT_MSG(t->kind == Type_Map, "%s", type_to_string(t)); + generate_map_internal_types(a, t); + Type *gst = t->Map.generated_struct_type; + isize index = 1; + irValue *entries = ir_emit(proc, ir_instr_struct_extract_value(proc, value, index, gst->Struct.fields[index]->type)); + return entries; } -irValue *ir_map_capacity(irProcedure *proc, irValue *value) { - GB_ASSERT(is_type_map(ir_type(value))); - irValue **args = gb_alloc_array(proc->module->allocator, irValue *, 1); - args[0] = ir_emit_transmute(proc, value, t_rawptr); - return ir_emit_global_call(proc, "__dynamic_map_cap", args, 1); +irValue *ir_map_entries_ptr(irProcedure *proc, irValue *value) { + gbAllocator a = proc->module->allocator; + Type *t = base_type(type_deref(ir_type(value))); + GB_ASSERT_MSG(t->kind == Type_Map, "%s", type_to_string(t)); + generate_map_internal_types(a, t); + Type *gst = t->Map.generated_struct_type; + isize index = 1; + Type *ptr_t = make_type_pointer(a, gst->Struct.fields[index]->type); + irValue *entries = ir_emit(proc, ir_instr_struct_element_ptr(proc, value, index, ptr_t)); + return entries; +} + +irValue *ir_map_len(irProcedure *proc, irValue *value) { + irValue *entries = ir_map_entries(proc, value); + return ir_dynamic_array_len(proc, entries); +} + +irValue *ir_map_cap(irProcedure *proc, irValue *value) { + irValue *entries = ir_map_entries(proc, value); + return ir_dynamic_array_cap(proc, entries); } @@ -2366,7 +2402,7 @@ irValue *ir_emit_comp_against_nil(irProcedure *proc, TokenKind op_kind, irValue return ir_emit_arith(proc, Token_And, a, b, t_bool); } } else if (is_type_map(t)) { - irValue *len = ir_map_count(proc, x); + irValue *len = ir_map_len(proc, x); return ir_emit_comp(proc, op_kind, len, v_zero); } else if (is_type_union(t)) { irValue *tag = ir_emit_union_tag_value(proc, x); @@ -2765,7 +2801,7 @@ irValue *ir_slice_elem(irProcedure *proc, irValue *slice) { GB_ASSERT(is_type_slice(ir_type(slice))); return ir_emit_struct_ev(proc, slice, 0); } -irValue *ir_slice_count(irProcedure *proc, irValue *slice) { +irValue *ir_slice_len(irProcedure *proc, irValue *slice) { GB_ASSERT(is_type_slice(ir_type(slice))); return ir_emit_struct_ev(proc, slice, 1); } @@ -2773,11 +2809,11 @@ irValue *ir_dynamic_array_elem(irProcedure *proc, irValue *da) { GB_ASSERT(is_type_dynamic_array(ir_type(da))); return ir_emit_struct_ev(proc, da, 0); } -irValue *ir_dynamic_array_count(irProcedure *proc, irValue *da) { +irValue *ir_dynamic_array_len(irProcedure *proc, irValue *da) { GB_ASSERT(is_type_dynamic_array(ir_type(da))); return ir_emit_struct_ev(proc, da, 1); } -irValue *ir_dynamic_array_capacity(irProcedure *proc, irValue *da) { +irValue *ir_dynamic_array_cap(irProcedure *proc, irValue *da) { GB_ASSERT(is_type_dynamic_array(ir_type(da))); return ir_emit_struct_ev(proc, da, 2); } @@ -2836,7 +2872,7 @@ irValue *ir_add_local_slice(irProcedure *proc, Type *slice_type, irValue *base, if (high == nullptr) { switch (bt->kind) { case Type_Array: high = ir_array_len(proc, base); break; - case Type_Slice: high = ir_slice_count(proc, base); break; + case Type_Slice: high = ir_slice_len(proc, base); break; case Type_Pointer: high = v_one; break; } } @@ -3181,7 +3217,7 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) { // []byte/[]u8 <-> string if (is_type_u8_slice(src) && is_type_string(dst)) { irValue *elem = ir_slice_elem(proc, value); - irValue *len = ir_slice_count(proc, value); + irValue *len = ir_slice_len(proc, value); return ir_emit_string(proc, elem, len); } if (is_type_string(src) && is_type_u8_slice(dst)) { @@ -4055,11 +4091,11 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv } else if (is_type_array(t)) { GB_PANIC("Array lengths are constant"); } else if (is_type_slice(t)) { - return ir_slice_count(proc, v); + return ir_slice_len(proc, v); } else if (is_type_dynamic_array(t)) { - return ir_dynamic_array_count(proc, v); + return ir_dynamic_array_len(proc, v); } else if (is_type_map(t)) { - return ir_map_count(proc, v); + return ir_map_len(proc, v); } GB_PANIC("Unreachable"); @@ -4079,11 +4115,11 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv } else if (is_type_array(t)) { GB_PANIC("Array lengths are constant"); } else if (is_type_slice(t)) { - return ir_slice_count(proc, v); + return ir_slice_len(proc, v); } else if (is_type_dynamic_array(t)) { - return ir_dynamic_array_capacity(proc, v); + return ir_dynamic_array_cap(proc, v); } else if (is_type_map(t)) { - return ir_map_capacity(proc, v); + return ir_map_cap(proc, v); } GB_PANIC("Unreachable"); @@ -4463,7 +4499,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv irValue *item_slice = args[1]; irValue *items = ir_slice_elem(proc, item_slice); - irValue *item_count = ir_slice_count(proc, item_slice); + irValue *item_count = ir_slice_len(proc, item_slice); irValue **daa_args = gb_alloc_array(a, irValue *, 5); daa_args[0] = array_ptr; @@ -5515,7 +5551,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { } irValue *elem = ir_slice_elem(proc, slice); irValue *index = ir_emit_conv(proc, ir_build_expr(proc, ie->index), t_int); - irValue *len = ir_slice_count(proc, slice); + irValue *len = ir_slice_len(proc, slice); ir_emit_bounds_check(proc, ast_node_token(ie->index), index, len); irValue *v = ir_emit_ptr_offset(proc, elem, index); return ir_addr(v); @@ -5533,7 +5569,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { } } irValue *elem = ir_dynamic_array_elem(proc, dynamic_array); - irValue *len = ir_dynamic_array_count(proc, dynamic_array); + irValue *len = ir_dynamic_array_len(proc, dynamic_array); irValue *index = ir_emit_conv(proc, ir_build_expr(proc, ie->index), t_int); ir_emit_bounds_check(proc, ast_node_token(ie->index), index, len); irValue *v = ir_emit_ptr_offset(proc, elem, index); @@ -5596,7 +5632,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { case Type_Slice: { Type *slice_type = type; - if (high == nullptr) high = ir_slice_count(proc, base); + if (high == nullptr) high = ir_slice_len(proc, base); ir_emit_slice_bounds_check(proc, se->open, low, high, false); @@ -5612,8 +5648,8 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { Type *elem_type = type->DynamicArray.elem; Type *slice_type = make_type_slice(a, elem_type); - if (high == nullptr) high = ir_dynamic_array_count(proc, base); - irValue *cap = ir_dynamic_array_capacity(proc, base); + if (high == nullptr) high = ir_dynamic_array_len(proc, base); + irValue *cap = ir_dynamic_array_cap(proc, base); ir_emit_dynamic_array_bounds_check(proc, se->open, low, high, cap); @@ -6247,11 +6283,7 @@ void ir_build_range_indexed(irProcedure *proc, irValue *expr, Type *val_type, ir case Type_Map: { irValue *key = ir_add_local_generated(proc, expr_type->Map.key); - Type *itp = make_type_pointer(proc->module->allocator, expr_type->Map.internal_type); - irValue *data_ptr = ir_emit_transmute(proc, expr, itp); - irValue *internal_ptr = ir_emit_load(proc, data_ptr); - - irValue *entries = ir_emit_struct_ep(proc, internal_ptr, 1); + irValue *entries = ir_map_entries_ptr(proc, expr); irValue *elem = ir_emit_struct_ep(proc, entries, 0); elem = ir_emit_load(proc, elem); @@ -6902,28 +6934,9 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) { if (is_type_pointer(type_deref(ir_addr_type(addr)))) { map = ir_addr_load(proc, addr); } - irValue *count_ptr = ir_add_local_generated(proc, t_int); - irValue *count_ptr_ptr = ir_add_local_generated(proc, t_int_ptr); - ir_emit_store(proc, count_ptr_ptr, count_ptr); - - irBlock *not_nil_block = ir_new_block(proc, nullptr, "map.not.nil.block"); - irBlock *end_nil_block = ir_new_block(proc, nullptr, "map.end.nil.block"); - { - Type *itp = make_type_pointer(a, et->Map.internal_type); - irValue *data_ptr = ir_emit_transmute(proc, map, itp); - irValue *internal_ptr = ir_emit_load(proc, data_ptr); - - irValue *cond = ir_emit_comp(proc, Token_NotEq, internal_ptr, v_raw_nil); - ir_emit_if(proc, cond, not_nil_block, end_nil_block); - ir_start_block(proc, not_nil_block); - - irValue *entries_ptr = ir_emit_struct_ep(proc, internal_ptr, 1); - irValue *cp = ir_emit_struct_ep(proc, entries_ptr, 1); - ir_emit_store(proc, count_ptr_ptr, cp); - ir_emit_jump(proc, end_nil_block); - } - ir_start_block(proc, end_nil_block); - ir_build_range_indexed(proc, map, val1_type, ir_emit_load(proc, count_ptr_ptr), &val, &key, &loop, &done); + irValue *entries_ptr = ir_map_entries_ptr(proc, map); + irValue *count_ptr = ir_emit_struct_ep(proc, entries_ptr, 1); + ir_build_range_indexed(proc, map, val1_type, count_ptr, &val, &key, &loop, &done); break; } case Type_Array: { @@ -6955,7 +6968,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) { slice = ir_emit_load(proc, slice); } else { count_ptr = ir_add_local_generated(proc, t_int); - ir_emit_store(proc, count_ptr, ir_slice_count(proc, slice)); + ir_emit_store(proc, count_ptr, ir_slice_len(proc, slice)); } ir_build_range_indexed(proc, slice, val0_type, count_ptr, &val, &key, &loop, &done); break; diff --git a/src/parser.cpp b/src/parser.cpp index f24569790..8c98effe2 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -127,7 +127,9 @@ enum FieldFlag { FieldFlag_using = 1<<1, FieldFlag_no_alias = 1<<2, FieldFlag_c_vararg = 1<<3, + FieldFlag_in = 1<<4, + // FieldFlag_Signature = FieldFlag_ellipsis|FieldFlag_using|FieldFlag_no_alias|FieldFlag_c_vararg|FieldFlag_in, FieldFlag_Signature = FieldFlag_ellipsis|FieldFlag_using|FieldFlag_no_alias|FieldFlag_c_vararg, FieldFlag_Struct = FieldFlag_using, }; @@ -2778,32 +2780,23 @@ AstNode *parse_atom_expr(AstFile *f, AstNode *operand, bool lhs) { AstNode *parse_unary_expr(AstFile *f, bool lhs) { switch (f->curr_token.kind) { + case Token_transmute: + case Token_cast: { + Token token = advance_token(f); + expect_token(f, Token_OpenParen); + AstNode *type = parse_type(f); + expect_token(f, Token_CloseParen); + return ast_type_cast(f, token, type, parse_unary_expr(f, lhs)); + } case Token_Add: case Token_Sub: case Token_Not: case Token_Xor: - case Token_And: { - Token op = advance_token(f); - return ast_unary_expr(f, op, parse_unary_expr(f, lhs)); - } break; - case Token_cast: { - Token token = expect_token(f, Token_cast); - Token open = expect_token_after(f, Token_OpenParen, "cast"); - AstNode *type = parse_type(f); - Token close = expect_token(f, Token_CloseParen); - return ast_type_cast(f, token, type, parse_unary_expr(f, lhs)); - } break; - case Token_transmute: { - Token token = expect_token(f, Token_transmute); - Token open = expect_token_after(f, Token_OpenParen, "transmute"); - AstNode *type = parse_type(f); - Token close = expect_token(f, Token_CloseParen); - return ast_type_cast(f, token, type, parse_unary_expr(f, lhs)); - } break; + case Token_And: + return ast_unary_expr(f, advance_token(f), parse_unary_expr(f, lhs)); } - AstNode *operand = parse_operand(f, lhs); - return parse_atom_expr(f, operand, lhs); + return parse_atom_expr(f, parse_operand(f, lhs), lhs); } bool is_ast_node_a_range(AstNode *expr) { @@ -2829,10 +2822,10 @@ i32 token_precedence(AstFile *f, TokenKind t) { return 1; case Token_Ellipsis: case Token_HalfClosed: - if (f->allow_range) { - return 2; + if (!f->allow_range) { + return 0; } - return 0; + return 2; case Token_CmpOr: return 3; case Token_CmpAnd: @@ -2938,17 +2931,8 @@ Array parse_ident_list(AstFile *f) { return list; } - -AstNode *parse_type_attempt(AstFile *f) { - AstNode *type = parse_type_or_ident(f); - if (type != nullptr) { - // TODO(bill): Handle? - } - return type; -} - AstNode *parse_type(AstFile *f) { - AstNode *type = parse_type_attempt(f); + AstNode *type = parse_type_or_ident(f); if (type == nullptr) { Token token = advance_token(f); syntax_error(token, "Expected a type"); @@ -3021,7 +3005,7 @@ AstNode *parse_value_decl(AstFile *f, Array names, CommentGroup docs) type = ast_type_type(f, advance_token(f), nullptr); is_mutable = false; } else { - type = parse_type_attempt(f); + type = parse_type_or_ident(f); } if (f->curr_token.kind == Token_Eq || @@ -3293,12 +3277,7 @@ AstNode *parse_var_type(AstFile *f, bool allow_ellipsis, bool allow_type_token) } type = ast_type_type(f, token, specialization); } else { - type = parse_type_attempt(f); - } - if (type == nullptr) { - Token tok = f->curr_token; - syntax_error(tok, "Expected a type"); - type = ast_bad_expr(f, tok, f->curr_token); + type = parse_type(f); } return type; } @@ -3311,6 +3290,7 @@ enum FieldPrefixKind { FieldPrefix_using, FieldPrefix_no_alias, FieldPrefix_c_var_arg, + FieldPrefix_in, }; FieldPrefixKind is_token_field_prefix(AstFile *f) { @@ -3321,6 +3301,9 @@ FieldPrefixKind is_token_field_prefix(AstFile *f) { case Token_using: return FieldPrefix_using; + case Token_in: + return FieldPrefix_in; + case Token_Hash: advance_token(f); switch (f->curr_token.kind) { @@ -3342,6 +3325,7 @@ u32 parse_field_prefixes(AstFile *f) { i32 using_count = 0; i32 no_alias_count = 0; i32 c_vararg_count = 0; + i32 in_count = 0; for (;;) { FieldPrefixKind kind = is_token_field_prefix(f); @@ -3358,17 +3342,20 @@ u32 parse_field_prefixes(AstFile *f) { case FieldPrefix_using: using_count += 1; advance_token(f); break; case FieldPrefix_no_alias: no_alias_count += 1; advance_token(f); break; case FieldPrefix_c_var_arg: c_vararg_count += 1; advance_token(f); break; + case FieldPrefix_in: in_count += 1; advance_token(f); break; } } if (using_count > 1) syntax_error(f->curr_token, "Multiple 'using' in this field list"); if (no_alias_count > 1) syntax_error(f->curr_token, "Multiple '#no_alias' in this field list"); if (c_vararg_count > 1) syntax_error(f->curr_token, "Multiple '#c_vararg' in this field list"); + if (in_count > 1) syntax_error(f->curr_token, "Multiple 'in' in this field list"); u32 field_flags = 0; if (using_count > 0) field_flags |= FieldFlag_using; if (no_alias_count > 0) field_flags |= FieldFlag_no_alias; if (c_vararg_count > 0) field_flags |= FieldFlag_c_vararg; + if (in_count > 0) field_flags |= FieldFlag_in; return field_flags; } @@ -3632,12 +3619,17 @@ AstNode *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, Tok AstNode *parse_type_or_ident(AstFile *f) { bool prev_allow_type = f->allow_type; isize prev_expr_level = f->expr_level; - defer (f->allow_type = prev_allow_type); - defer (f->expr_level = prev_expr_level); + defer ({ + f->allow_type = prev_allow_type; + f->expr_level = prev_expr_level; + }); + f->allow_type = true; f->expr_level = -1; - AstNode *operand = parse_operand(f, true); - AstNode *type = parse_atom_expr(f, operand, true); + + bool lhs = true; + AstNode *operand = parse_operand(f, lhs); + AstNode *type = parse_atom_expr(f, operand, lhs); return type; } @@ -3810,29 +3802,6 @@ AstNode *parse_return_stmt(AstFile *f) { return ast_return_stmt(f, token, results); } - -// AstNode *parse_give_stmt(AstFile *f) { -// if (f->curr_proc == nullptr) { -// syntax_error(f->curr_token, "You cannot use a give statement in the file scope"); -// return ast_bad_stmt(f, f->curr_token, f->curr_token); -// } -// if (f->expr_level == 0) { -// syntax_error(f->curr_token, "A give statement must be used within an expression"); -// return ast_bad_stmt(f, f->curr_token, f->curr_token); -// } - -// Token token = expect_token(f, Token_give); -// Array results; -// if (f->curr_token.kind != Token_Semicolon && f->curr_token.kind != Token_CloseBrace) { -// results = parse_rhs_expr_list(f); -// } else { -// results = make_ast_node_array(f); -// } -// AstNode *ge = ast_give_expr(f, token, results); -// expect_semicolon(f, ge); -// return ast_expr_stmt(f, ge); -// } - AstNode *parse_for_stmt(AstFile *f) { if (f->curr_proc == nullptr) { syntax_error(f->curr_token, "You cannot use a for statement in the file scope"); diff --git a/src/types.cpp b/src/types.cpp index 9ccb97a6e..34ba4cddc 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -1871,9 +1871,7 @@ i64 type_align_of_internal(gbAllocator allocator, Type *t, TypePath *path) { case Type_Map: generate_map_internal_types(allocator, t); - // return type_align_of_internal(allocator, t->Map.generated_struct_type, path); - return build_context.word_size; - + return type_align_of_internal(allocator, t->Map.internal_type, path); case Type_Enum: return type_align_of_internal(allocator, t->Enum.base_type, path); @@ -2065,8 +2063,7 @@ i64 type_size_of_internal(gbAllocator allocator, Type *t, TypePath *path) { case Type_Map: generate_map_internal_types(allocator, t); - // return type_size_of_internal(allocator, t->Map.generated_struct_type, path); - return build_context.word_size; + return type_size_of_internal(allocator, t->Map.internal_type, path); case Type_Tuple: { i64 count, align, size;