Change record field syntax

This commit is contained in:
Ginger Bill
2016-12-18 22:23:34 +00:00
parent e370337f97
commit 4c10fbdcd4
11 changed files with 193 additions and 304 deletions
+55 -55
View File
@@ -13,67 +13,67 @@
// IMPORTANT NOTE(bill): Do not change the order of any of this data // IMPORTANT NOTE(bill): Do not change the order of any of this data
// The compiler relies upon this _exact_ order // The compiler relies upon this _exact_ order
type Type_Info_Member struct #ordered { type Type_Info_Member struct #ordered {
name: string; // can be empty if tuple name string; // can be empty if tuple
type_info: ^Type_Info; type_info ^Type_Info;
offset: int; // offsets are not used in tuples offset int; // offsets are not used in tuples
}; }
type Type_Info_Record struct #ordered { type Type_Info_Record struct #ordered {
fields: []Type_Info_Member; fields []Type_Info_Member;
size: int; // in bytes size int; // in bytes
align: int; // in bytes align int; // in bytes
packed: bool; packed bool;
ordered: bool; ordered bool;
}; }
type Type_Info union { type Type_Info union {
Named: struct #ordered { Named struct #ordered {
name: string; name string;
base: ^Type_Info; // This will _not_ be a Type_Info.Named base ^Type_Info; // This will _not_ be a Type_Info.Named
}; };
Integer: struct #ordered { Integer struct #ordered {
size: int; // in bytes size int; // in bytes
signed: bool; signed bool;
}; };
Float: struct #ordered { Float struct #ordered {
size: int; // in bytes size int; // in bytes
}; };
Any: struct #ordered {}; Any struct #ordered {};
String: struct #ordered {}; String struct #ordered {};
Boolean: struct #ordered {}; Boolean struct #ordered {};
Pointer: struct #ordered { Pointer struct #ordered {
elem: ^Type_Info; // nil -> rawptr elem ^Type_Info; // nil -> rawptr
}; };
Maybe: struct #ordered { Maybe struct #ordered {
elem: ^Type_Info; elem ^Type_Info;
}; };
Procedure: struct #ordered { Procedure struct #ordered {
params: ^Type_Info; // Type_Info.Tuple params ^Type_Info; // Type_Info.Tuple
results: ^Type_Info; // Type_Info.Tuple results ^Type_Info; // Type_Info.Tuple
variadic: bool; variadic bool;
}; };
Array: struct #ordered { Array struct #ordered {
elem: ^Type_Info; elem ^Type_Info;
elem_size: int; elem_size int;
count: int; count int;
}; };
Slice: struct #ordered { Slice struct #ordered {
elem: ^Type_Info; elem ^Type_Info;
elem_size: int; elem_size int;
}; };
Vector: struct #ordered { Vector struct #ordered {
elem: ^Type_Info; elem ^Type_Info;
elem_size: int; elem_size int;
count: int; count int;
align: int; align int;
}; };
Tuple: Type_Info_Record; Tuple Type_Info_Record;
Struct: Type_Info_Record; Struct Type_Info_Record;
Union: Type_Info_Record; Union Type_Info_Record;
Raw_Union: Type_Info_Record; Raw_Union Type_Info_Record;
Enum: struct #ordered { Enum struct #ordered {
base: ^Type_Info; base ^Type_Info;
values: []i64; values []i64;
names: []string; names []string;
}; };
}; };
@@ -126,18 +126,18 @@ type Allocator_Proc proc(allocator_data rawptr, mode Allocator_Mode,
type Allocator struct #ordered { type Allocator struct #ordered {
procedure: Allocator_Proc; procedure Allocator_Proc;
data: rawptr; data rawptr;
} }
type Context struct #ordered { type Context struct #ordered {
thread_id: int; thread_id int;
allocator: Allocator; allocator Allocator;
user_data: rawptr; user_data rawptr;
user_index: int; user_index int;
} }
#thread_local var __context Context; #thread_local var __context Context;
+6 -6
View File
@@ -90,7 +90,7 @@ proc align_forward(ptr rawptr, align int) -> rawptr {
type Allocation_Header struct { type Allocation_Header struct {
size: int; size int;
} }
proc allocation_header_fill(header ^Allocation_Header, data rawptr, size int) { proc allocation_header_fill(header ^Allocation_Header, data rawptr, size int) {
header.size = size; header.size = size;
@@ -115,14 +115,14 @@ proc allocation_header(data rawptr) -> ^Allocation_Header {
// Custom allocators // Custom allocators
type Arena struct { type Arena struct {
backing: Allocator; backing Allocator;
memory: []byte; memory []byte;
temp_count: int; temp_count int;
} }
type Arena_Temp_Memory struct { type Arena_Temp_Memory struct {
arena: ^Arena; arena ^Arena;
original_count: int; original_count int;
} }
+4 -4
View File
@@ -4,13 +4,13 @@
type File_Time u64; type File_Time u64;
type File_Handle raw_union { type File_Handle raw_union {
p: rawptr; p rawptr;
i: int; i int;
} }
type File struct { type File struct {
handle: File_Handle; handle File_Handle;
last_write_time: File_Time; last_write_time File_Time;
} }
proc open(name string) -> (File, bool) { proc open(name string) -> (File, bool) {
+5 -5
View File
@@ -2,14 +2,14 @@
#import "atomic.odin"; #import "atomic.odin";
type Semaphore struct { type Semaphore struct {
handle: win32.HANDLE; handle win32.HANDLE;
} }
type Mutex struct { type Mutex struct {
semaphore: Semaphore; semaphore Semaphore;
counter: i32; counter i32;
owner: i32; owner i32;
recursion: i32; recursion i32;
} }
+45 -45
View File
@@ -51,62 +51,62 @@ const SM_CYSCREEN = 1;
const SW_SHOW = 5; const SW_SHOW = 5;
type POINT struct #ordered { type POINT struct #ordered {
x, y: i32; x, y i32;
} }
type WNDCLASSEXA struct #ordered { type WNDCLASSEXA struct #ordered {
size, style: u32; size, style u32;
wnd_proc: WNDPROC; wnd_proc WNDPROC;
cls_extra, wnd_extra: i32; cls_extra, wnd_extra i32;
instance: HINSTANCE; instance HINSTANCE;
icon: HICON; icon HICON;
cursor: HCURSOR; cursor HCURSOR;
background: HBRUSH; background HBRUSH;
menu_name, class_name: ^u8; menu_name, class_name ^u8;
sm: HICON; sm HICON;
} }
type MSG struct #ordered { type MSG struct #ordered {
hwnd: HWND; hwnd HWND;
message: u32; message u32;
wparam: WPARAM; wparam WPARAM;
lparam: LPARAM; lparam LPARAM;
time: u32; time u32;
pt: POINT; pt POINT;
} }
type RECT struct #ordered { type RECT struct #ordered {
left: i32; left i32;
top: i32; top i32;
right: i32; right i32;
bottom: i32; bottom i32;
} }
type FILETIME struct #ordered { type FILETIME struct #ordered {
low_date_time, high_date_time: u32; low_date_time, high_date_time u32;
} }
type BY_HANDLE_FILE_INFORMATION struct #ordered { type BY_HANDLE_FILE_INFORMATION struct #ordered {
file_attributes: u32; file_attributes u32;
creation_time, creation_time,
last_access_time, last_access_time,
last_write_time: FILETIME; last_write_time FILETIME;
volume_serial_number, volume_serial_number,
file_size_high, file_size_high,
file_size_low, file_size_low,
number_of_links, number_of_links,
file_index_high, file_index_high,
file_index_low: u32; file_index_low u32;
} }
type WIN32_FILE_ATTRIBUTE_DATA struct #ordered { type WIN32_FILE_ATTRIBUTE_DATA struct #ordered {
file_attributes: u32; file_attributes u32;
creation_time, creation_time,
last_access_time, last_access_time,
last_write_time: FILETIME; last_write_time FILETIME;
file_size_high, file_size_high,
file_size_low: u32; file_size_low u32;
} }
type GET_FILEEX_INFO_LEVELS i32; type GET_FILEEX_INFO_LEVELS i32;
@@ -209,9 +209,9 @@ const HEAP_ZERO_MEMORY = 0x00000008;
// Synchronization // Synchronization
type SECURITY_ATTRIBUTES struct #ordered { type SECURITY_ATTRIBUTES struct #ordered {
length: u32; length u32;
security_descriptor: rawptr; security_descriptor rawptr;
inherit_handle: BOOL; inherit_handle BOOL;
} }
const INFINITE = 0xffffffff; const INFINITE = 0xffffffff;
@@ -242,24 +242,24 @@ proc ReadBarrier () #foreign
// GDI // GDI
type BITMAPINFOHEADER struct #ordered { type BITMAPINFOHEADER struct #ordered {
size: u32; size u32;
width, height: i32; width, height i32;
planes, bit_count: i16; planes, bit_count i16;
compression: u32; compression u32;
size_image: u32; size_image u32;
x_pels_per_meter: i32; x_pels_per_meter i32;
y_pels_per_meter: i32; y_pels_per_meter i32;
clr_used: u32; clr_used u32;
clr_important: u32; clr_important u32;
} }
type BITMAPINFO struct #ordered { type BITMAPINFO struct #ordered {
using header: BITMAPINFOHEADER; using header BITMAPINFOHEADER;
colors: [1]RGBQUAD; colors [1]RGBQUAD;
} }
type RGBQUAD struct #ordered { type RGBQUAD struct #ordered {
blue, green, red, reserved: byte; blue, green, red, reserved byte;
} }
const BI_RGB = 0; const BI_RGB = 0;
@@ -315,7 +315,7 @@ type wglCreateContextAttribsARBType proc(hdc HDC, hshareContext rawptr, attribLi
type PIXELFORMATDESCRIPTOR struct #ordered { type PIXELFORMATDESCRIPTOR struct #ordered {
size, size,
version, version,
flags: u32; flags u32;
pixel_type, pixel_type,
color_bits, color_bits,
@@ -336,11 +336,11 @@ type PIXELFORMATDESCRIPTOR struct #ordered {
stencil_bits, stencil_bits,
aux_buffers, aux_buffers,
layer_type, layer_type,
reserved: byte; reserved byte;
layer_mask, layer_mask,
visible_mask, visible_mask,
damage_mask: u32; damage_mask u32;
} }
proc GetDC (h HANDLE) -> HDC #foreign proc GetDC (h HANDLE) -> HDC #foreign
+1 -1
View File
@@ -11,7 +11,7 @@ const SURROGATE_MAX = 0xdfff;
type Accept_Range struct { type Accept_Range struct {
lo, hi: u8; lo, hi u8;
}; };
accept_ranges := [5]Accept_Range{ accept_ranges := [5]Accept_Range{
+34 -78
View File
@@ -464,37 +464,29 @@ void populate_using_entity_map(Checker *c, AstNode *node, Type *t, MapEntity *en
void check_fields(Checker *c, AstNode *node, AstNodeArray decls, void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
Entity **fields, isize field_count, Entity **fields, isize field_count,
Entity **other_fields, isize other_field_count,
String context) { String context) {
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena); gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
MapEntity entity_map = {0}; MapEntity entity_map = {0};
map_entity_init_with_reserve(&entity_map, c->tmp_allocator, 2*(field_count+other_field_count)); map_entity_init_with_reserve(&entity_map, c->tmp_allocator, 2*field_count);
isize other_field_index = 0; isize other_field_index = 0;
Entity *using_index_expr = NULL; Entity *using_index_expr = NULL;
DelayedOtherFields dof = {0};
dof.other_fields = other_fields;
dof.other_field_count = other_field_count;
dof.entity_map = &entity_map;
check_scope_decls(c, decls, 1.2*other_field_count, &dof);
if (node->kind == AstNode_UnionType) { if (node->kind == AstNode_UnionType) {
isize field_index = 0; isize field_index = 0;
fields[field_index++] = make_entity_type_name(c->allocator, c->context.scope, empty_token, NULL); fields[field_index++] = make_entity_type_name(c->allocator, c->context.scope, empty_token, NULL);
for_array(decl_index, decls) { for_array(decl_index, decls) {
AstNode *decl = decls.e[decl_index]; AstNode *decl = decls.e[decl_index];
if (decl->kind != AstNode_VarDecl) { if (decl->kind != AstNode_Parameter) {
continue; continue;
} }
ast_node(vd, VarDecl, decl); ast_node(p, Parameter, decl);
Type *base_type = check_type_extra(c, vd->type, NULL); Type *base_type = check_type_extra(c, p->type, NULL);
for_array(name_index, vd->names) { for_array(name_index, p->names) {
AstNode *name = vd->names.e[name_index]; AstNode *name = p->names.e[name_index];
if (!ast_node_expect(name, AstNode_Ident)) { if (!ast_node_expect(name, AstNode_Ident)) {
continue; continue;
} }
@@ -526,28 +518,28 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
isize field_index = 0; isize field_index = 0;
for_array(decl_index, decls) { for_array(decl_index, decls) {
AstNode *decl = decls.e[decl_index]; AstNode *decl = decls.e[decl_index];
if (decl->kind != AstNode_VarDecl) { if (decl->kind != AstNode_Parameter) {
continue; continue;
} }
ast_node(vd, VarDecl, decl); ast_node(param, Parameter, decl);
Type *type = check_type_extra(c, vd->type, NULL); Type *type = check_type_extra(c, param->type, NULL);
if (vd->is_using) { if (param->is_using) {
if (vd->names.count > 1) { if (param->names.count > 1) {
error_node(vd->names.e[0], "Cannot apply `using` to more than one of the same type"); error_node(param->names.e[0], "Cannot apply `using` to more than one of the same type");
} }
} }
for_array(name_index, vd->names) { for_array(name_index, param->names) {
AstNode *name = vd->names.e[name_index]; AstNode *name = param->names.e[name_index];
if (!ast_node_expect(name, AstNode_Ident)) { if (!ast_node_expect(name, AstNode_Ident)) {
continue; continue;
} }
Token name_token = name->Ident; Token name_token = name->Ident;
Entity *e = make_entity_field(c->allocator, c->context.scope, name_token, type, vd->is_using, cast(i32)field_index); Entity *e = make_entity_field(c->allocator, c->context.scope, name_token, type, param->is_using, cast(i32)field_index);
e->identifier = name; e->identifier = name;
if (str_eq(name_token.string, str_lit("_"))) { if (str_eq(name_token.string, str_lit("_"))) {
fields[field_index++] = e; fields[field_index++] = e;
@@ -566,19 +558,19 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
} }
if (vd->is_using) { if (param->is_using) {
Type *t = base_type(type_deref(type)); Type *t = base_type(type_deref(type));
if (!is_type_struct(t) && !is_type_raw_union(t) && if (!is_type_struct(t) && !is_type_raw_union(t) &&
vd->names.count >= 1 && param->names.count >= 1 &&
vd->names.e[0]->kind == AstNode_Ident) { param->names.e[0]->kind == AstNode_Ident) {
Token name_token = vd->names.e[0]->Ident; Token name_token = param->names.e[0]->Ident;
if (is_type_indexable(t)) { if (is_type_indexable(t)) {
bool ok = true; bool ok = true;
for_array(emi, entity_map.entries) { for_array(emi, entity_map.entries) {
Entity *e = entity_map.entries.e[emi].value; Entity *e = entity_map.entries.e[emi].value;
if (e->kind == Entity_Variable && e->flags & EntityFlag_Anonymous) { if (e->kind == Entity_Variable && e->flags & EntityFlag_Anonymous) {
if (is_type_indexable(e->type)) { if (is_type_indexable(e->type)) {
if (e->identifier != vd->names.e[0]) { if (e->identifier != param->names.e[0]) {
ok = false; ok = false;
using_index_expr = e; using_index_expr = e;
break; break;
@@ -643,36 +635,24 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node) {
ast_node(st, StructType, node); ast_node(st, StructType, node);
isize field_count = 0; isize field_count = 0;
isize other_field_count = 0;
for_array(field_index, st->fields) { for_array(field_index, st->fields) {
AstNode *field = st->fields.e[field_index]; AstNode *field = st->fields.e[field_index];
switch (field->kind) { switch (field->kind) {
case_ast_node(vd, VarDecl, field); case_ast_node(p, Parameter, field);
field_count += vd->names.count; field_count += p->names.count;
case_end;
case_ast_node(cd, ConstDecl, field);
other_field_count += cd->names.count;
case_end;
case_ast_node(td, TypeDecl, field);
other_field_count += 1;
case_end; case_end;
} }
} }
Entity **fields = gb_alloc_array(c->allocator, Entity *, field_count); Entity **fields = gb_alloc_array(c->allocator, Entity *, field_count);
Entity **other_fields = gb_alloc_array(c->allocator, Entity *, other_field_count);
check_fields(c, node, st->fields, fields, field_count, other_fields, other_field_count, str_lit("struct")); check_fields(c, node, st->fields, fields, field_count, str_lit("struct"));
struct_type->Record.struct_is_packed = st->is_packed; struct_type->Record.struct_is_packed = st->is_packed;
struct_type->Record.struct_is_ordered = st->is_ordered; struct_type->Record.struct_is_ordered = st->is_ordered;
struct_type->Record.fields = fields; struct_type->Record.fields = fields;
struct_type->Record.fields_in_src_order = fields; struct_type->Record.fields_in_src_order = fields;
struct_type->Record.field_count = field_count; struct_type->Record.field_count = field_count;
struct_type->Record.other_fields = other_fields;
struct_type->Record.other_field_count = other_field_count;
if (!st->is_packed && !st->is_ordered) { if (!st->is_packed && !st->is_ordered) {
// NOTE(bill): Reorder fields for reduced size/performance // NOTE(bill): Reorder fields for reduced size/performance
@@ -704,33 +684,21 @@ void check_union_type(Checker *c, Type *union_type, AstNode *node) {
ast_node(ut, UnionType, node); ast_node(ut, UnionType, node);
isize field_count = 1; isize field_count = 1;
isize other_field_count = 0;
for_array(field_index, ut->fields) { for_array(field_index, ut->fields) {
AstNode *field = ut->fields.e[field_index]; AstNode *field = ut->fields.e[field_index];
switch (field->kind) { switch (field->kind) {
case_ast_node(vd, VarDecl, field); case_ast_node(p, Parameter, field);
field_count += vd->names.count; field_count += p->names.count;
case_end;
case_ast_node(cd, ConstDecl, field);
other_field_count += cd->names.count;
case_end;
case_ast_node(td, TypeDecl, field);
other_field_count += 1;
case_end; case_end;
} }
} }
Entity **fields = gb_alloc_array(c->allocator, Entity *, field_count); Entity **fields = gb_alloc_array(c->allocator, Entity *, field_count);
Entity **other_fields = gb_alloc_array(c->allocator, Entity *, other_field_count);
check_fields(c, node, ut->fields, fields, field_count, other_fields, other_field_count, str_lit("union")); check_fields(c, node, ut->fields, fields, field_count, str_lit("union"));
union_type->Record.fields = fields; union_type->Record.fields = fields;
union_type->Record.field_count = field_count; union_type->Record.field_count = field_count;
union_type->Record.other_fields = other_fields;
union_type->Record.other_field_count = other_field_count;
} }
void check_raw_union_type(Checker *c, Type *union_type, AstNode *node) { void check_raw_union_type(Checker *c, Type *union_type, AstNode *node) {
@@ -739,33 +707,21 @@ void check_raw_union_type(Checker *c, Type *union_type, AstNode *node) {
ast_node(ut, RawUnionType, node); ast_node(ut, RawUnionType, node);
isize field_count = 0; isize field_count = 0;
isize other_field_count = 0;
for_array(field_index, ut->fields) { for_array(field_index, ut->fields) {
AstNode *field = ut->fields.e[field_index]; AstNode *field = ut->fields.e[field_index];
switch (field->kind) { switch (field->kind) {
case_ast_node(vd, VarDecl, field); case_ast_node(p, Parameter, field);
field_count += vd->names.count; field_count += p->names.count;
case_end;
case_ast_node(cd, ConstDecl, field);
other_field_count += cd->names.count;
case_end;
case_ast_node(td, TypeDecl, field);
other_field_count += 1;
case_end; case_end;
} }
} }
Entity **fields = gb_alloc_array(c->allocator, Entity *, field_count); Entity **fields = gb_alloc_array(c->allocator, Entity *, field_count);
Entity **other_fields = gb_alloc_array(c->allocator, Entity *, other_field_count);
check_fields(c, node, ut->fields, fields, field_count, other_fields, other_field_count, str_lit("raw union")); check_fields(c, node, ut->fields, fields, field_count, str_lit("raw_union"));
union_type->Record.fields = fields; union_type->Record.fields = fields;
union_type->Record.field_count = field_count; union_type->Record.field_count = field_count;
union_type->Record.other_fields = other_fields;
union_type->Record.other_field_count = other_field_count;
} }
GB_COMPARE_PROC(cmp_enum_order) { GB_COMPARE_PROC(cmp_enum_order) {
@@ -895,11 +851,11 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
gb_sort_array(fields, field_index, cmp_enum_order); gb_sort_array(fields, field_index, cmp_enum_order);
enum_type->Record.other_fields = fields; enum_type->Record.enum_values = fields;
enum_type->Record.other_field_count = field_index; enum_type->Record.enum_value_count = field_index;
enum_type->Record.enum_count = make_entity_constant(c->allocator, NULL, enum_type->Record.enum_count = make_entity_constant(c->allocator, NULL,
make_token_ident(str_lit("count")), t_int, make_exact_value_integer(enum_type->Record.other_field_count)); make_token_ident(str_lit("count")), t_int, make_exact_value_integer(enum_type->Record.enum_value_count));
enum_type->Record.min_value = make_entity_constant(c->allocator, NULL, enum_type->Record.min_value = make_entity_constant(c->allocator, NULL,
make_token_ident(str_lit("min_value")), constant_type, make_exact_value_integer(min_value)); make_token_ident(str_lit("min_value")), constant_type, make_exact_value_integer(min_value));
enum_type->Record.max_value = make_entity_constant(c->allocator, NULL, enum_type->Record.max_value = make_entity_constant(c->allocator, NULL,
@@ -3599,8 +3555,8 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
ExactValue value = make_exact_value_string(str_lit("")); ExactValue value = make_exact_value_string(str_lit(""));
if (operand->value.kind == ExactValue_Integer) { if (operand->value.kind == ExactValue_Integer) {
i64 index = operand->value.value_integer; i64 index = operand->value.value_integer;
for (isize i = 0; i < type->Record.other_field_count; i++) { for (isize i = 0; i < type->Record.enum_value_count; i++) {
Entity *f = type->Record.other_fields[i]; Entity *f = type->Record.enum_values[i];
if (f->kind == Entity_Constant && f->Constant.value.kind == ExactValue_Integer) { if (f->kind == Entity_Constant && f->Constant.value.kind == ExactValue_Integer) {
i64 fv = f->Constant.value.value_integer; i64 fv = f->Constant.value.value_integer;
if (index == fv) { if (index == fv) {
+3 -14
View File
@@ -907,9 +907,9 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
switch (e->kind) { switch (e->kind) {
case Entity_TypeName: { case Entity_TypeName: {
Type *t = base_type(e->type); Type *t = base_type(e->type);
if (is_type_struct(t) || is_type_enum(t)) { if (is_type_enum(t)) {
for (isize i = 0; i < t->Record.other_field_count; i++) { for (isize i = 0; i < t->Record.enum_value_count; i++) {
Entity *f = t->Record.other_fields[i]; Entity *f = t->Record.enum_values[i];
Entity *found = scope_insert_entity(c->context.scope, f); Entity *found = scope_insert_entity(c->context.scope, f);
if (found != NULL) { if (found != NULL) {
gbString expr_str = expr_to_string(expr); gbString expr_str = expr_to_string(expr);
@@ -931,17 +931,6 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
} }
f->using_parent = e; f->using_parent = e;
} }
for (isize i = 0; i < t->Record.other_field_count; i++) {
Entity *f = t->Record.other_fields[i];
Entity *found = scope_insert_entity(c->context.scope, f);
if (found != NULL) {
gbString expr_str = expr_to_string(expr);
error(us->token, "Namespace collision while `using` `%s` of: %.*s", expr_str, LIT(found->token.string));
gb_string_free(expr_str);
return;
}
f->using_parent = e;
}
} }
} break; } break;
+14 -16
View File
@@ -84,6 +84,8 @@ typedef struct TypeRecord {
Entity * enum_count; Entity * enum_count;
Entity * min_value; Entity * min_value;
Entity * max_value; Entity * max_value;
Entity **enum_values;
i32 enum_value_count;
}; };
struct { // struct only struct { // struct only
i64 * struct_offsets; i64 * struct_offsets;
@@ -93,10 +95,6 @@ typedef struct TypeRecord {
Entity **fields_in_src_order; // Entity_Variable Entity **fields_in_src_order; // Entity_Variable
}; };
}; };
// Entity_Constant or Entity_TypeName
Entity **other_fields;
i32 other_field_count;
} TypeRecord; } TypeRecord;
#define TYPE_KINDS \ #define TYPE_KINDS \
@@ -984,19 +982,19 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
} }
} }
for (isize i = 0; i < type->Record.other_field_count; i++) {
Entity *f = type->Record.other_fields[i];
GB_ASSERT(f->kind != Entity_Variable);
String str = f->token.string;
if (str_eq(field_name, str)) {
sel.entity = f;
selection_add_index(&sel, i);
return sel;
}
}
if (is_type_enum(type)) { if (is_type_enum(type)) {
for (isize i = 0; i < type->Record.enum_value_count; i++) {
Entity *f = type->Record.enum_values[i];
GB_ASSERT(f->kind != Entity_Variable);
String str = f->token.string;
if (str_eq(field_name, str)) {
sel.entity = f;
selection_add_index(&sel, i);
return sel;
}
}
if (str_eq(field_name, str_lit("count"))) { if (str_eq(field_name, str_lit("count"))) {
sel.entity = type->Record.enum_count; sel.entity = type->Record.enum_count;
return sel; return sel;
+21 -67
View File
@@ -1646,8 +1646,9 @@ AstNode *parse_atom_expr(AstFile *f, bool lhs) {
f->expr_level++; f->expr_level++;
open = expect_token(f, Token_OpenBracket); open = expect_token(f, Token_OpenBracket);
if (f->curr_token.kind != Token_Colon) if (f->curr_token.kind != Token_Colon) {
indices[0] = parse_expr(f, false); indices[0] = parse_expr(f, false);
}
isize colon_count = 0; isize colon_count = 0;
Token colons[2] = {0}; Token colons[2] = {0};
@@ -2062,8 +2063,9 @@ AstNode *parse_proc_type(AstFile *f) {
} }
AstNodeArray parse_parameter_list(AstFile *f, bool allow_using, TokenKind follow) { AstNodeArray parse_parameter_list(AstFile *f, isize *name_count_, bool allow_using, TokenKind separator, TokenKind follow) {
AstNodeArray params = make_ast_node_array(f); AstNodeArray params = make_ast_node_array(f);
isize name_count = 0;
while (f->curr_token.kind != follow && while (f->curr_token.kind != follow &&
f->curr_token.kind != Token_EOF) { f->curr_token.kind != Token_EOF) {
@@ -2088,6 +2090,8 @@ AstNodeArray parse_parameter_list(AstFile *f, bool allow_using, TokenKind follow
is_using = false; is_using = false;
} }
name_count += names.count;
// expect_token_after(f, Token_Colon, "parameter list"); // expect_token_after(f, Token_Colon, "parameter list");
AstNode *type = NULL; AstNode *type = NULL;
@@ -2114,77 +2118,27 @@ AstNodeArray parse_parameter_list(AstFile *f, bool allow_using, TokenKind follow
syntax_error(f->curr_token, "Expected a type for this parameter declaration"); syntax_error(f->curr_token, "Expected a type for this parameter declaration");
} }
array_add(&params, make_parameter(f, names, type, is_using)); AstNode *param = make_parameter(f, names, type, is_using);
if (!allow_token(f, Token_Comma)) { array_add(&params, param);
break;
if (separator == Token_Semicolon) {
expect_semicolon(f, param);
} else {
if (!allow_token(f, separator)) {
break;
}
} }
} }
if (name_count_) *name_count_ = name_count;
return params; return params;
} }
AstNodeArray parse_record_params(AstFile *f, isize *decl_count_, bool allow_using, String context) { AstNodeArray parse_record_params(AstFile *f, isize *field_count_, bool allow_using, String context) {
AstNodeArray decls = make_ast_node_array(f); return parse_parameter_list(f, field_count_, allow_using, Token_Semicolon, Token_CloseBrace);
isize decl_count = 0;
while (f->curr_token.kind != Token_CloseBrace &&
f->curr_token.kind != Token_EOF) {
AstNode *decl = parse_stmt(f);
if (is_ast_node_decl(decl) ||
decl->kind == AstNode_UsingStmt ||
decl->kind == AstNode_EmptyStmt) {
switch (decl->kind) {
case AstNode_EmptyStmt:
break;
case AstNode_ProcDecl:
syntax_error(f->curr_token, "Procedure declarations are not allowed within a %.*s", LIT(context));
break;
case AstNode_UsingStmt: {
bool is_using = true;
if (!allow_using) {
syntax_error(f->curr_token, "Cannot apply `using` to members of a %.*s", LIT(context));
is_using = false;
}
if (decl->UsingStmt.node->kind == AstNode_VarDecl) {
AstNode *vd = decl->UsingStmt.node;
vd->VarDecl.is_using = is_using && allow_using;
if (vd->VarDecl.values.count > 0) {
syntax_error(f->curr_token, "Default variable assignments within a %.*s will be ignored", LIT(context));
}
array_add(&decls, vd);
} else {
syntax_error_node(decl, "Illegal %.*s field", LIT(context));
}
} break;
case AstNode_VarDecl: {
if (decl->VarDecl.values.count > 0) {
syntax_error(f->curr_token, "Default variable assignments within a %.*s will be ignored", LIT(context));
}
array_add(&decls, decl);
}
case AstNode_BadDecl:
break;
case AstNode_ConstDecl:
case AstNode_TypeDecl:
default:
decl_count += 1;
array_add(&decls, decl);
break;
}
} else {
syntax_error_node(decl, "Illegal record field: %.*s", LIT(ast_node_strings[decl->kind]));
}
}
if (decl_count_) *decl_count_ = decl_count;
return decls;
} }
AstNode *parse_identifier_or_type(AstFile *f) { AstNode *parse_identifier_or_type(AstFile *f) {
@@ -2380,7 +2334,7 @@ void parse_proc_signature(AstFile *f,
AstNodeArray *params, AstNodeArray *params,
AstNodeArray *results) { AstNodeArray *results) {
expect_token(f, Token_OpenParen); expect_token(f, Token_OpenParen);
*params = parse_parameter_list(f, true, Token_CloseParen); *params = parse_parameter_list(f, NULL, true, Token_Comma, Token_CloseParen);
expect_token_after(f, Token_CloseParen, "parameter list"); expect_token_after(f, Token_CloseParen, "parameter list");
*results = parse_results(f); *results = parse_results(f);
} }
+5 -13
View File
@@ -2522,15 +2522,8 @@ void ssa_gen_global_type_name(ssaModule *m, Entity *e, String name) {
ssa_module_add_value(m, e, t); ssa_module_add_value(m, e, t);
map_ssa_value_set(&m->members, hash_string(name), t); map_ssa_value_set(&m->members, hash_string(name), t);
Type *bt = base_type(e->type); if (is_type_union(e->type)) {
if (bt->kind == Type_Record) { Type *bt = base_type(e->type);
TypeRecord *s = &bt->Record;
for (isize j = 0; j < s->other_field_count; j++) {
ssa_mangle_sub_type_name(m, s->other_fields[j], name);
}
}
if (is_type_union(bt)) {
TypeRecord *s = &bt->Record; TypeRecord *s = &bt->Record;
// NOTE(bill): Zeroth entry is null (for `match type` stmts) // NOTE(bill): Zeroth entry is null (for `match type` stmts)
for (isize j = 1; j < s->field_count; j++) { for (isize j = 1; j < s->field_count; j++) {
@@ -5418,13 +5411,12 @@ void ssa_gen_tree(ssaGen *s) {
ssaValue *base = ssa_emit_struct_ep(proc, tag, 0); ssaValue *base = ssa_emit_struct_ep(proc, tag, 0);
ssa_emit_store(proc, base, ssa_get_type_info_ptr(proc, type_info_data, enum_base)); ssa_emit_store(proc, base, ssa_get_type_info_ptr(proc, type_info_data, enum_base));
if (t->Record.other_field_count > 0) { if (t->Record.enum_value_count > 0) {
Entity **fields = t->Record.other_fields; Entity **fields = t->Record.enum_values;
isize count = t->Record.other_field_count; isize count = t->Record.enum_value_count;
ssaValue *value_array = NULL; ssaValue *value_array = NULL;
ssaValue *name_array = NULL; ssaValue *name_array = NULL;
{ {
Token token = {Token_Ident}; Token token = {Token_Ident};
i32 id = cast(i32)entry_index; i32 id = cast(i32)entry_index;