diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/checker/expr.c | 112 | ||||
| -rw-r--r-- | src/checker/stmt.c | 17 | ||||
| -rw-r--r-- | src/checker/types.c | 26 | ||||
| -rw-r--r-- | src/parser.c | 86 | ||||
| -rw-r--r-- | src/ssa.c | 18 |
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(¶ms, 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(¶ms, 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); } @@ -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; |