aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/checker/expr.c112
-rw-r--r--src/checker/stmt.c17
-rw-r--r--src/checker/types.c26
-rw-r--r--src/parser.c86
-rw-r--r--src/ssa.c18
5 files changed, 74 insertions, 185 deletions
diff --git a/src/checker/expr.c b/src/checker/expr.c
index 47964ec5a..8900cb4a7 100644
--- a/src/checker/expr.c
+++ b/src/checker/expr.c
@@ -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,
Entity **fields, isize field_count,
- Entity **other_fields, isize other_field_count,
String context) {
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
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;
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) {
isize field_index = 0;
fields[field_index++] = make_entity_type_name(c->allocator, c->context.scope, empty_token, NULL);
for_array(decl_index, decls) {
AstNode *decl = decls.e[decl_index];
- if (decl->kind != AstNode_VarDecl) {
+ if (decl->kind != AstNode_Parameter) {
continue;
}
- ast_node(vd, VarDecl, decl);
- Type *base_type = check_type_extra(c, vd->type, NULL);
+ ast_node(p, Parameter, decl);
+ Type *base_type = check_type_extra(c, p->type, NULL);
- for_array(name_index, vd->names) {
- AstNode *name = vd->names.e[name_index];
+ for_array(name_index, p->names) {
+ AstNode *name = p->names.e[name_index];
if (!ast_node_expect(name, AstNode_Ident)) {
continue;
}
@@ -526,28 +518,28 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
isize field_index = 0;
for_array(decl_index, decls) {
AstNode *decl = decls.e[decl_index];
- if (decl->kind != AstNode_VarDecl) {
+ if (decl->kind != AstNode_Parameter) {
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 (vd->names.count > 1) {
- error_node(vd->names.e[0], "Cannot apply `using` to more than one of the same type");
+ if (param->is_using) {
+ if (param->names.count > 1) {
+ error_node(param->names.e[0], "Cannot apply `using` to more than one of the same type");
}
}
- for_array(name_index, vd->names) {
- AstNode *name = vd->names.e[name_index];
+ for_array(name_index, param->names) {
+ AstNode *name = param->names.e[name_index];
if (!ast_node_expect(name, AstNode_Ident)) {
continue;
}
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;
if (str_eq(name_token.string, str_lit("_"))) {
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));
if (!is_type_struct(t) && !is_type_raw_union(t) &&
- vd->names.count >= 1 &&
- vd->names.e[0]->kind == AstNode_Ident) {
- Token name_token = vd->names.e[0]->Ident;
+ param->names.count >= 1 &&
+ param->names.e[0]->kind == AstNode_Ident) {
+ Token name_token = param->names.e[0]->Ident;
if (is_type_indexable(t)) {
bool ok = true;
for_array(emi, entity_map.entries) {
Entity *e = entity_map.entries.e[emi].value;
if (e->kind == Entity_Variable && e->flags & EntityFlag_Anonymous) {
if (is_type_indexable(e->type)) {
- if (e->identifier != vd->names.e[0]) {
+ if (e->identifier != param->names.e[0]) {
ok = false;
using_index_expr = e;
break;
@@ -643,36 +635,24 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node) {
ast_node(st, StructType, node);
isize field_count = 0;
- isize other_field_count = 0;
for_array(field_index, st->fields) {
AstNode *field = st->fields.e[field_index];
switch (field->kind) {
- case_ast_node(vd, VarDecl, field);
- field_count += vd->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_ast_node(p, Parameter, field);
+ field_count += p->names.count;
case_end;
}
}
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_ordered = st->is_ordered;
struct_type->Record.fields = fields;
struct_type->Record.fields_in_src_order = fields;
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) {
// 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);
isize field_count = 1;
- isize other_field_count = 0;
for_array(field_index, ut->fields) {
AstNode *field = ut->fields.e[field_index];
switch (field->kind) {
- case_ast_node(vd, VarDecl, field);
- field_count += vd->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_ast_node(p, Parameter, field);
+ field_count += p->names.count;
case_end;
}
}
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.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) {
@@ -739,33 +707,21 @@ void check_raw_union_type(Checker *c, Type *union_type, AstNode *node) {
ast_node(ut, RawUnionType, node);
isize field_count = 0;
- isize other_field_count = 0;
for_array(field_index, ut->fields) {
AstNode *field = ut->fields.e[field_index];
switch (field->kind) {
- case_ast_node(vd, VarDecl, field);
- field_count += vd->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_ast_node(p, Parameter, field);
+ field_count += p->names.count;
case_end;
}
}
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.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) {
@@ -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);
- enum_type->Record.other_fields = fields;
- enum_type->Record.other_field_count = field_index;
+ enum_type->Record.enum_values = fields;
+ enum_type->Record.enum_value_count = field_index;
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,
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,
@@ -3599,8 +3555,8 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
ExactValue value = make_exact_value_string(str_lit(""));
if (operand->value.kind == ExactValue_Integer) {
i64 index = operand->value.value_integer;
- for (isize i = 0; i < type->Record.other_field_count; i++) {
- Entity *f = type->Record.other_fields[i];
+ for (isize i = 0; i < type->Record.enum_value_count; i++) {
+ Entity *f = type->Record.enum_values[i];
if (f->kind == Entity_Constant && f->Constant.value.kind == ExactValue_Integer) {
i64 fv = f->Constant.value.value_integer;
if (index == fv) {
diff --git a/src/checker/stmt.c b/src/checker/stmt.c
index 9e3efc204..f1074e2e6 100644
--- a/src/checker/stmt.c
+++ b/src/checker/stmt.c
@@ -907,9 +907,9 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
switch (e->kind) {
case Entity_TypeName: {
Type *t = base_type(e->type);
- if (is_type_struct(t) || is_type_enum(t)) {
- for (isize i = 0; i < t->Record.other_field_count; i++) {
- Entity *f = t->Record.other_fields[i];
+ if (is_type_enum(t)) {
+ for (isize i = 0; i < t->Record.enum_value_count; i++) {
+ Entity *f = t->Record.enum_values[i];
Entity *found = scope_insert_entity(c->context.scope, f);
if (found != NULL) {
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;
}
- 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;
diff --git a/src/checker/types.c b/src/checker/types.c
index 45b40b8e0..a09254061 100644
--- a/src/checker/types.c
+++ b/src/checker/types.c
@@ -84,6 +84,8 @@ typedef struct TypeRecord {
Entity * enum_count;
Entity * min_value;
Entity * max_value;
+ Entity **enum_values;
+ i32 enum_value_count;
};
struct { // struct only
i64 * struct_offsets;
@@ -93,10 +95,6 @@ typedef struct TypeRecord {
Entity **fields_in_src_order; // Entity_Variable
};
};
-
- // Entity_Constant or Entity_TypeName
- Entity **other_fields;
- i32 other_field_count;
} TypeRecord;
#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 (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)) {
+ sel.entity = f;
+ selection_add_index(&sel, i);
+ return sel;
+ }
}
- }
- if (is_type_enum(type)) {
if (str_eq(field_name, str_lit("count"))) {
sel.entity = type->Record.enum_count;
return sel;
diff --git a/src/parser.c b/src/parser.c
index cd8a8bd27..e5c64ae88 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -1646,8 +1646,9 @@ AstNode *parse_atom_expr(AstFile *f, bool lhs) {
f->expr_level++;
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);
+ }
isize colon_count = 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);
+ isize name_count = 0;
while (f->curr_token.kind != follow &&
f->curr_token.kind != Token_EOF) {
@@ -2088,6 +2090,8 @@ AstNodeArray parse_parameter_list(AstFile *f, bool allow_using, TokenKind follow
is_using = false;
}
+ name_count += names.count;
+
// expect_token_after(f, Token_Colon, "parameter list");
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");
}
- array_add(&params, make_parameter(f, names, type, is_using));
- if (!allow_token(f, Token_Comma)) {
- break;
- }
- }
-
- return params;
-}
-
-
-AstNodeArray parse_record_params(AstFile *f, isize *decl_count_, bool allow_using, String context) {
- AstNodeArray decls = make_ast_node_array(f);
- 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;
+ AstNode *param = make_parameter(f, names, type, is_using);
+ array_add(&params, param);
- 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);
+ if (separator == Token_Semicolon) {
+ expect_semicolon(f, param);
+ } else {
+ if (!allow_token(f, separator)) {
break;
}
- } else {
- syntax_error_node(decl, "Illegal record field: %.*s", LIT(ast_node_strings[decl->kind]));
}
}
- if (decl_count_) *decl_count_ = decl_count;
+ if (name_count_) *name_count_ = name_count;
+
+ return params;
+}
+
- return decls;
+AstNodeArray parse_record_params(AstFile *f, isize *field_count_, bool allow_using, String context) {
+ return parse_parameter_list(f, field_count_, allow_using, Token_Semicolon, Token_CloseBrace);
}
AstNode *parse_identifier_or_type(AstFile *f) {
@@ -2380,7 +2334,7 @@ void parse_proc_signature(AstFile *f,
AstNodeArray *params,
AstNodeArray *results) {
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");
*results = parse_results(f);
}
diff --git a/src/ssa.c b/src/ssa.c
index c86df0969..f4100e9cf 100644
--- a/src/ssa.c
+++ b/src/ssa.c
@@ -2522,15 +2522,8 @@ void ssa_gen_global_type_name(ssaModule *m, Entity *e, String name) {
ssa_module_add_value(m, e, t);
map_ssa_value_set(&m->members, hash_string(name), t);
- Type *bt = base_type(e->type);
- if (bt->kind == Type_Record) {
- 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)) {
+ if (is_type_union(e->type)) {
+ Type *bt = base_type(e->type);
TypeRecord *s = &bt->Record;
// NOTE(bill): Zeroth entry is null (for `match type` stmts)
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);
ssa_emit_store(proc, base, ssa_get_type_info_ptr(proc, type_info_data, enum_base));
- if (t->Record.other_field_count > 0) {
- Entity **fields = t->Record.other_fields;
- isize count = t->Record.other_field_count;
+ if (t->Record.enum_value_count > 0) {
+ Entity **fields = t->Record.enum_values;
+ isize count = t->Record.enum_value_count;
ssaValue *value_array = NULL;
ssaValue *name_array = NULL;
-
{
Token token = {Token_Ident};
i32 id = cast(i32)entry_index;