diff options
Diffstat (limited to 'src/checker/expr.cpp')
| -rw-r--r-- | src/checker/expr.cpp | 293 |
1 files changed, 160 insertions, 133 deletions
diff --git a/src/checker/expr.cpp b/src/checker/expr.cpp index b5fb1249f..13d367acd 100644 --- a/src/checker/expr.cpp +++ b/src/checker/expr.cpp @@ -250,7 +250,7 @@ void populate_using_entity_map(Checker *c, AstNode *node, Type *t, Map<Entity *> void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init_expr); -void check_fields(Checker *c, AstNode *node, AstNode *decl_list, +void check_fields(Checker *c, AstNode *node, AstNodeArray decls, Entity **fields, isize field_count, Entity **other_fields, isize other_field_count, CycleChecker *cycle_checker, String context) { @@ -268,19 +268,21 @@ void check_fields(Checker *c, AstNode *node, AstNode *decl_list, DeclInfo *d;d check_entity_decl(c, e, d, NULL); #endif - for (AstNode *decl = decl_list; decl != NULL; decl = decl->next) { + gb_for_array(decl_index, decls) { + AstNode *decl = decls[decl_index]; if (decl->kind == AstNode_VarDecl) { ast_node(vd, VarDecl, decl); if (vd->kind != Declaration_Immutable) continue; - isize entity_count = vd->name_count; + isize entity_count = gb_array_count(vd->names); isize entity_index = 0; Entity **entities = gb_alloc_array(c->allocator, Entity *, entity_count); - for (AstNode *name = vd->name_list, *value = vd->value_list; - name != NULL && value != NULL; - name = name->next, value = value->next) { + gb_for_array(i, vd->values) { + AstNode *name = vd->names[i]; + AstNode *value = vd->values[i]; + GB_ASSERT(name->kind == AstNode_Ident); ExactValue v = {ExactValue_Invalid}; Token name_token = name->Ident; @@ -289,8 +291,8 @@ void check_fields(Checker *c, AstNode *node, AstNode *decl_list, check_const_decl(c, e, vd->type, value); } - isize lhs_count = vd->name_count; - isize rhs_count = vd->value_count; + isize lhs_count = gb_array_count(vd->names); + isize rhs_count = gb_array_count(vd->values); // TODO(bill): Better error messages or is this good enough? if (rhs_count == 0 && vd->type == NULL) { @@ -299,8 +301,8 @@ void check_fields(Checker *c, AstNode *node, AstNode *decl_list, error(&c->error_collector, ast_node_token(node), "Extra initial expression"); } - AstNode *name = vd->name_list; - for (isize i = 0; i < entity_count; i++, name = name->next) { + gb_for_array(i, vd->names) { + AstNode *name = vd->names[i]; Entity *e = entities[i]; Token name_token = name->Ident; HashKey key = hash_string(name_token.string); @@ -337,15 +339,20 @@ void check_fields(Checker *c, AstNode *node, AstNode *decl_list, 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 (AstNode *decl = decl_list; decl != NULL; decl = decl->next) { - if (decl->kind != AstNode_VarDecl) + gb_for_array(decl_index, decls) { + AstNode *decl = decls[decl_index]; + if (decl->kind != AstNode_VarDecl) { continue; + } + ast_node(vd, VarDecl, decl); - if (vd->kind != Declaration_Mutable) + if (vd->kind != Declaration_Mutable) { continue; + } Type *base_type = check_type(c, vd->type, NULL, cycle_checker); - for (AstNode *name = vd->name_list; name != NULL; name = name->next) { + gb_for_array(name_index, vd->names) { + AstNode *name = vd->names[name_index]; Token name_token = name->Ident; Type *type = make_type_named(c->allocator, name_token.string, base_type, NULL); @@ -366,22 +373,26 @@ void check_fields(Checker *c, AstNode *node, AstNode *decl_list, } } else { isize field_index = 0; - for (AstNode *decl = decl_list; decl != NULL; decl = decl->next) { - if (decl->kind != AstNode_VarDecl) + gb_for_array(decl_index, decls) { + AstNode *decl = decls[decl_index]; + if (decl->kind != AstNode_VarDecl) { continue; + } ast_node(vd, VarDecl, decl); - if (vd->kind != Declaration_Mutable) + if (vd->kind != Declaration_Mutable) { continue; + } Type *type = check_type(c, vd->type, NULL, cycle_checker); if (vd->is_using) { - if (vd->name_count > 1) { - error(&c->error_collector, ast_node_token(vd->name_list), + if (gb_array_count(vd->names) > 1) { + error(&c->error_collector, ast_node_token(vd->names[0]), "Cannot apply `using` to more than one of the same type"); } } - for (AstNode *name = vd->name_list; name != NULL; name = name->next) { + gb_for_array(name_index, vd->names) { + AstNode *name = vd->names[name_index]; Token name_token = name->Ident; Entity *e = make_entity_field(c->allocator, c->context.scope, name_token, type, vd->is_using); @@ -401,7 +412,7 @@ void check_fields(Checker *c, AstNode *node, AstNode *decl_list, if (vd->is_using) { Type *t = get_base_type(type_deref(type)); if (!is_type_struct(t) && !is_type_raw_union(t)) { - Token name_token = vd->name_list->Ident; + Token name_token = vd->names[0]->Ident; error(&c->error_collector, name_token, "`using` on a field `%.*s` must be a type", LIT(name_token.string)); continue; } @@ -419,13 +430,14 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node, CycleChecke isize field_count = 0; isize other_field_count = 0; - for (AstNode *decl = st->decl_list; decl != NULL; decl = decl->next) { + gb_for_array(decl_index, st->decls) { + AstNode *decl = st->decls[decl_index]; switch (decl->kind) { case_ast_node(vd, VarDecl, decl); if (vd->kind == Declaration_Mutable) { - field_count += vd->name_count; + field_count += gb_array_count(vd->names); } else { - other_field_count += vd->name_count; + other_field_count += gb_array_count(vd->names); } case_end; @@ -438,7 +450,7 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node, CycleChecke 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->decl_list, fields, field_count, other_fields, other_field_count, cycle_checker, make_string("struct")); + check_fields(c, node, st->decls, fields, field_count, other_fields, other_field_count, cycle_checker, make_string("struct")); struct_type->Record.struct_is_packed = st->is_packed; struct_type->Record.fields = fields; @@ -453,13 +465,14 @@ void check_union_type(Checker *c, Type *union_type, AstNode *node, CycleChecker isize field_count = 1; isize other_field_count = 0; - for (AstNode *decl = ut->decl_list; decl != NULL; decl = decl->next) { + gb_for_array(decl_index, ut->decls) { + AstNode *decl = ut->decls[decl_index]; switch (decl->kind) { case_ast_node(vd, VarDecl, decl); if (vd->kind == Declaration_Mutable) { - field_count += vd->name_count; + field_count += gb_array_count(vd->names); } else { - other_field_count += vd->name_count; + other_field_count += gb_array_count(vd->names); } case_end; @@ -472,7 +485,7 @@ void check_union_type(Checker *c, Type *union_type, AstNode *node, CycleChecker 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->decl_list, fields, field_count, other_fields, other_field_count, cycle_checker, make_string("union")); + check_fields(c, node, ut->decls, fields, field_count, other_fields, other_field_count, cycle_checker, make_string("union")); union_type->Record.fields = fields; union_type->Record.field_count = field_count; @@ -487,13 +500,14 @@ void check_raw_union_type(Checker *c, Type *union_type, AstNode *node, CycleChec isize field_count = 0; isize other_field_count = 0; - for (AstNode *decl = ut->decl_list; decl != NULL; decl = decl->next) { + gb_for_array(decl_index, ut->decls) { + AstNode *decl = ut->decls[decl_index]; switch (decl->kind) { case_ast_node(vd, VarDecl, decl); if (vd->kind == Declaration_Mutable) { - field_count += vd->name_count; + field_count += gb_array_count(vd->names); } else { - other_field_count += vd->name_count; + other_field_count += gb_array_count(vd->names); } case_end; @@ -506,7 +520,7 @@ void check_raw_union_type(Checker *c, Type *union_type, AstNode *node, CycleChec 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->decl_list, fields, field_count, other_fields, other_field_count, cycle_checker, make_string("raw union")); + check_fields(c, node, ut->decls, fields, field_count, other_fields, other_field_count, cycle_checker, make_string("raw union")); union_type->Record.fields = fields; union_type->Record.field_count = field_count; @@ -538,10 +552,12 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod } enum_type->Record.enum_base = base_type; - Entity **fields = gb_alloc_array(c->allocator, Entity *, et->field_count); + Entity **fields = gb_alloc_array(c->allocator, Entity *, gb_array_count(et->fields)); isize field_index = 0; ExactValue iota = make_exact_value_integer(-1); - for (AstNode *field = et->field_list; field != NULL; field = field->next) { + gb_for_array(i, et->fields) { + AstNode *field = et->fields[i]; + ast_node(f, FieldValue, field); Token name_token = f->field->Ident; @@ -583,26 +599,34 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod add_entity_use(&c->info, f->field, e); } enum_type->Record.other_fields = fields; - enum_type->Record.other_field_count = et->field_count; + enum_type->Record.other_field_count = gb_array_count(et->fields); } -Type *check_get_params(Checker *c, Scope *scope, AstNode *field_list, isize field_count, b32 *is_variadic_) { - if (field_list == NULL || field_count == 0) +Type *check_get_params(Checker *c, Scope *scope, AstNodeArray fields, b32 *is_variadic_) { + if (fields == NULL || gb_array_count(fields) == 0) return NULL; b32 is_variadic = false; Type *tuple = make_type_tuple(c->allocator); - Entity **variables = gb_alloc_array(c->allocator, Entity *, field_count); + isize variable_count = 0; + gb_for_array(i, fields) { + AstNode *field = fields[i]; + ast_node(f, Field, field); + variable_count += gb_array_count(f->names); + } + + Entity **variables = gb_alloc_array(c->allocator, Entity *, variable_count); isize variable_index = 0; - for (AstNode *field = field_list; field != NULL; field = field->next) { + gb_for_array(i, fields) { + AstNode *field = fields[i]; ast_node(f, Field, field); AstNode *type_expr = f->type; if (type_expr) { if (type_expr->kind == AstNode_Ellipsis) { type_expr = type_expr->Ellipsis.expr; - if (field->next == NULL) { + if (i+1 == gb_array_count(fields)) { is_variadic = true; } else { error(&c->error_collector, ast_node_token(field), "Invalid AST: Invalid variadic parameter"); @@ -610,7 +634,8 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *field_list, isize fiel } Type *type = check_type(c, type_expr); - for (AstNode *name = f->name_list; name != NULL; name = name->next) { + gb_for_array(j, f->names) { + AstNode *name = f->names[j]; if (name->kind == AstNode_Ident) { Entity *param = make_entity_param(c->allocator, scope, name->Ident, type, f->is_using); add_entity(c, scope, name, param); @@ -622,29 +647,31 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *field_list, isize fiel } } - if (is_variadic && field_count > 0) { + if (is_variadic && gb_array_count(fields) > 0) { // NOTE(bill): Change last variadic parameter to be a slice // Custom Calling convention for variadic parameters - Entity *end = variables[field_count-1]; + Entity *end = variables[gb_array_count(fields)-1]; end->type = make_type_slice(c->allocator, end->type); } tuple->Tuple.variables = variables; - tuple->Tuple.variable_count = field_count; + tuple->Tuple.variable_count = variable_count; if (is_variadic_) *is_variadic_ = is_variadic; return tuple; } -Type *check_get_results(Checker *c, Scope *scope, AstNode *list, isize list_count) { - if (list == NULL) +Type *check_get_results(Checker *c, Scope *scope, AstNodeArray results) { + if (results == NULL || gb_array_count(results) == 0) { return NULL; + } Type *tuple = make_type_tuple(c->allocator); - Entity **variables = gb_alloc_array(c->allocator, Entity *, list_count); + Entity **variables = gb_alloc_array(c->allocator, Entity *, gb_array_count(results)); isize variable_index = 0; - for (AstNode *item = list; item != NULL; item = item->next) { + gb_for_array(i, results) { + AstNode *item = results[i]; Type *type = check_type(c, item); Token token = ast_node_token(item); token.string = make_string(""); // NOTE(bill): results are not named @@ -654,7 +681,7 @@ Type *check_get_results(Checker *c, Scope *scope, AstNode *list, isize list_coun variables[variable_index++] = param; } tuple->Tuple.variables = variables; - tuple->Tuple.variable_count = list_count; + tuple->Tuple.variable_count = gb_array_count(results); return tuple; } @@ -663,20 +690,23 @@ Type *check_get_results(Checker *c, Scope *scope, AstNode *list, isize list_coun void check_procedure_type(Checker *c, Type *type, AstNode *proc_type_node) { ast_node(pt, ProcType, proc_type_node); - isize param_count = pt->param_count; - isize result_count = pt->result_count; // gb_printf("%td -> %td\n", param_count, result_count); b32 variadic = false; - Type *params = check_get_params(c, c->context.scope, pt->param_list, param_count, &variadic); - Type *results = check_get_results(c, c->context.scope, pt->result_list, result_count); + Type *params = check_get_params(c, c->context.scope, pt->params, &variadic); + Type *results = check_get_results(c, c->context.scope, pt->results); + + isize param_count = 0; + isize result_count = 0; + if (params) param_count = params ->Tuple.variable_count; + if (results) result_count = results->Tuple.variable_count; type->Proc.scope = c->context.scope; type->Proc.params = params; - type->Proc.param_count = pt->param_count; + type->Proc.param_count = param_count; type->Proc.results = results; - type->Proc.result_count = pt->result_count; + type->Proc.result_count = result_count; type->Proc.variadic = variadic; } @@ -1953,15 +1983,15 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) BuiltinProc *bp = &builtin_procs[id]; { char *err = NULL; - if (ce->arg_list_count < bp->arg_count) + if (gb_array_count(ce->args) < bp->arg_count) err = "Too few"; - if (ce->arg_list_count > bp->arg_count && !bp->variadic) + if (gb_array_count(ce->args) > bp->arg_count && !bp->variadic) err = "Too many"; if (err) { ast_node(proc, Ident, ce->proc); error(&c->error_collector, ce->close, "`%s` arguments for `%.*s`, expected %td, got %td", err, LIT(proc->string), - bp->arg_count, ce->arg_list_count); + bp->arg_count, gb_array_count(ce->args)); return false; } } @@ -1975,17 +2005,17 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) // NOTE(bill): The first arg is a Type, this will be checked case by case break; default: - check_multi_expr(c, operand, ce->arg_list); + check_multi_expr(c, operand, ce->args[0]); } switch (id) { case BuiltinProc_new: { // new :: proc(Type) -> ^Type Operand op = {}; - check_expr_or_type(c, &op, ce->arg_list); + check_expr_or_type(c, &op, ce->args[0]); Type *type = op.type; if (op.mode != Addressing_Type && type == NULL || type == t_invalid) { - error(&c->error_collector, ast_node_token(ce->arg_list), "Expected a type for `new`"); + error(&c->error_collector, ast_node_token(ce->args[0]), "Expected a type for `new`"); return false; } operand->mode = Addressing_Value; @@ -1994,15 +2024,15 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) case BuiltinProc_new_slice: { // new_slice :: proc(Type, len: int[, cap: int]) -> []Type Operand op = {}; - check_expr_or_type(c, &op, ce->arg_list); + check_expr_or_type(c, &op, ce->args[0]); Type *type = op.type; if (op.mode != Addressing_Type && type == NULL || type == t_invalid) { - error(&c->error_collector, ast_node_token(ce->arg_list), "Expected a type for `new_slice`"); + error(&c->error_collector, ast_node_token(ce->args[0]), "Expected a type for `new_slice`"); return false; } - AstNode *len = ce->arg_list->next; - AstNode *cap = len->next; + AstNode *len = ce->args[1]; + AstNode *cap = ce->args[2]; check_expr(c, &op, len); if (op.mode == Addressing_Invalid) @@ -2028,7 +2058,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) type_str); return false; } - if (cap->next != NULL) { + if (ce->args[3] != NULL) { error(&c->error_collector, ast_node_token(call), "Too many arguments to `new_slice`, expected either 2 or 3"); return false; @@ -2057,10 +2087,10 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) case BuiltinProc_size_of: { // size_of :: proc(Type) -> int Operand op = {}; - check_expr_or_type(c, &op, ce->arg_list); + check_expr_or_type(c, &op, ce->args[0]); Type *type = op.type; if (!type) { - error(&c->error_collector, ast_node_token(ce->arg_list), "Expected a type for `size_of`"); + error(&c->error_collector, ast_node_token(ce->args[0]), "Expected a type for `size_of`"); return false; } @@ -2084,10 +2114,10 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) case BuiltinProc_align_of: { // align_of :: proc(Type) -> int Operand op = {}; - check_expr_or_type(c, &op, ce->arg_list); + check_expr_or_type(c, &op, ce->args[0]); Type *type = op.type; if (!type) { - error(&c->error_collector, ast_node_token(ce->arg_list), "Expected a type for `align_of`"); + error(&c->error_collector, ast_node_token(ce->args[0]), "Expected a type for `align_of`"); return false; } operand->mode = Addressing_Constant; @@ -2109,15 +2139,15 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) case BuiltinProc_offset_of: { // offset_val :: proc(Type, field) -> int Operand op = {}; - check_expr_or_type(c, &op, ce->arg_list); + check_expr_or_type(c, &op, ce->args[0]); Type *type = get_base_type(op.type); - AstNode *field_arg = unparen_expr(ce->arg_list->next); + AstNode *field_arg = unparen_expr(ce->args[1]); if (type != NULL) { - error(&c->error_collector, ast_node_token(ce->arg_list), "Expected a type for `offset_of`"); + error(&c->error_collector, ast_node_token(ce->args[0]), "Expected a type for `offset_of`"); return false; } if (!is_type_struct(type)) { - error(&c->error_collector, ast_node_token(ce->arg_list), "Expected a structure type for `offset_of`"); + error(&c->error_collector, ast_node_token(ce->args[0]), "Expected a structure type for `offset_of`"); return false; } if (field_arg == NULL || @@ -2131,7 +2161,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) Selection sel = lookup_field(type, arg->string, operand->mode == Addressing_Type); if (sel.entity == NULL) { gbString type_str = type_to_string(type); - error(&c->error_collector, ast_node_token(ce->arg_list), + error(&c->error_collector, ast_node_token(ce->args[0]), "`%s` has no field named `%.*s`", type_str, LIT(arg->string)); return false; } @@ -2144,7 +2174,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) case BuiltinProc_offset_of_val: { // offset_val :: proc(val: expression) -> int - AstNode *arg = unparen_expr(ce->arg_list); + AstNode *arg = unparen_expr(ce->args[0]); if (arg->kind != AstNode_SelectorExpr) { gbString str = expr_to_string(arg); error(&c->error_collector, ast_node_token(arg), "`%s` is not a selector expression", str); @@ -2192,7 +2222,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) // assert :: proc(cond: bool) if (!is_type_boolean(operand->type)) { - gbString str = expr_to_string(ce->arg_list); + gbString str = expr_to_string(ce->args[0]); defer (gb_string_free(str)); error(&c->error_collector, ast_node_token(call), "`%s` is not a boolean", str); @@ -2200,7 +2230,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) } if (operand->mode == Addressing_Constant && !operand->value.value_bool) { - gbString str = expr_to_string(ce->arg_list); + gbString str = expr_to_string(ce->args[0]); defer (gb_string_free(str)); error(&c->error_collector, ast_node_token(call), "Compile time assertion: `%s`", str); @@ -2272,7 +2302,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) dest_type = d->Slice.elem; Operand op = {}; - check_expr(c, &op, ce->arg_list->next); + check_expr(c, &op, ce->args[1]); if (op.mode == Addressing_Invalid) return false; Type *s = get_base_type(op.type); @@ -2285,8 +2315,8 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) } if (!are_types_identical(dest_type, src_type)) { - gbString d_arg = expr_to_string(ce->arg_list); - gbString s_arg = expr_to_string(ce->arg_list->next); + gbString d_arg = expr_to_string(ce->args[0]); + gbString s_arg = expr_to_string(ce->args[1]); gbString d_str = type_to_string(dest_type); gbString s_str = type_to_string(src_type); defer (gb_string_free(d_arg)); @@ -2309,7 +2339,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) x_type = get_base_type(operand->type); Operand op = {}; - check_expr(c, &op, ce->arg_list->next); + check_expr(c, &op, ce->args[1]); if (op.mode == Addressing_Invalid) return false; y_type = get_base_type(op.type); @@ -2321,8 +2351,8 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) Type *elem_type = x_type->Pointer.elem->Slice.elem; if (!check_is_assignable_to(c, &op, elem_type)) { - gbString d_arg = expr_to_string(ce->arg_list); - gbString s_arg = expr_to_string(ce->arg_list->next); + gbString d_arg = expr_to_string(ce->args[0]); + gbString s_arg = expr_to_string(ce->args[1]); gbString d_str = type_to_string(elem_type); gbString s_str = type_to_string(y_type); defer (gb_string_free(d_arg)); @@ -2353,7 +2383,9 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) isize max_count = vector_type->Vector.count; isize arg_count = 0; - for (AstNode *arg = ce->arg_list->next; arg != NULL; arg = arg->next) { + gb_for_array(i, ce->args) { + if (i == 0) continue; + AstNode *arg = ce->args[i]; Operand op = {}; check_expr(c, &op, arg); if (op.mode == Addressing_Invalid) @@ -2406,7 +2438,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) return false; } - AstNode *offset = ce->arg_list->next; + AstNode *offset = ce->args[1]; Operand op = {}; check_expr(c, &op, offset); if (op.mode == Addressing_Invalid) @@ -2447,7 +2479,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) "`rawptr` cannot have pointer arithmetic"); return false; } - AstNode *offset = ce->arg_list->next; + AstNode *offset = ce->args[1]; Operand op = {}; check_expr(c, &op, offset); if (op.mode == Addressing_Invalid) @@ -2509,8 +2541,8 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) return false; } - AstNode *len = ce->arg_list->next; - AstNode *cap = len->next; + AstNode *len = ce->args[1]; + AstNode *cap = ce->args[2]; Operand op = {}; check_expr(c, &op, len); @@ -2537,7 +2569,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) type_str); return false; } - if (cap->next != NULL) { + if (ce->args[2] != NULL) { error(&c->error_collector, ast_node_token(call), "Too many arguments to `slice_ptr`, expected either 2 or 3"); return false; @@ -2560,7 +2592,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) return false; } - AstNode *other_arg = ce->arg_list->next; + AstNode *other_arg = ce->args[1]; Operand a = *operand; Operand b = {}; check_expr(c, &b, other_arg); @@ -2620,7 +2652,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) return false; } - AstNode *other_arg = ce->arg_list->next; + AstNode *other_arg = ce->args[1]; Operand a = *operand; Operand b = {}; check_expr(c, &b, other_arg); @@ -2710,6 +2742,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) return true; } + void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode *call) { GB_ASSERT(call->kind == AstNode_CallExpr); GB_ASSERT(proc_type->kind == Type_Proc); @@ -2734,21 +2767,22 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode } } - if (ce->arg_list_count == 0) { + if (gb_array_count(ce->args) == 0) { if (variadic && param_count-1 == 0) return; if (param_count == 0) return; } + // TODO(bill): Completely redo this entire code. + // It's from when I used linked lists instead of arrays in the parser - - if (ce->arg_list_count > param_count && !variadic) { + if (gb_array_count(ce->args) > param_count && !variadic) { error_code = +1; } else { Entity **sig_params = proc_type->Proc.params->Tuple.variables; - AstNode *call_arg = ce->arg_list; - for (; call_arg != NULL; call_arg = call_arg->next) { + gb_for_array(arg_index, ce->args) { + AstNode *call_arg = ce->args[arg_index]; check_multi_expr(c, operand, call_arg); if (operand->mode == Addressing_Invalid) continue; @@ -2804,8 +2838,6 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode if ((!variadic && param_index < param_count) || (variadic && param_index < param_count-1)) { error_code = -1; - } else if (call_arg != NULL && call_arg->next != NULL) { - error_code = +1; } } @@ -2832,8 +2864,8 @@ ExprKind check_call_expr(Checker *c, Operand *operand, AstNode *call) { check_expr_or_type(c, operand, ce->proc); if (operand->mode == Addressing_Invalid) { - for (AstNode *arg = ce->arg_list; arg != NULL; arg = arg->next) { - check_expr_base(c, operand, arg); + gb_for_array(i, ce->args) { + check_expr_base(c, operand, ce->args[i]); } operand->mode = Addressing_Invalid; operand->expr = call; @@ -2977,17 +3009,16 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint case Type_Record: { if (!is_type_struct(t)) break; - if (cl->elem_count == 0) + if (gb_array_count(cl->elems) == 0) { break; // NOTE(bill): No need to init + } { // Checker values - AstNode *elem = cl->elem_list; isize field_count = t->Record.field_count; - if (elem->kind == AstNode_FieldValue) { + if (cl->elems[0]->kind == AstNode_FieldValue) { b32 *fields_visited = gb_alloc_array(c->allocator, b32, field_count); - for (; - elem != NULL; - elem = elem->next) { + gb_for_array(i, cl->elems) { + AstNode *elem = cl->elems[i]; if (elem->kind != AstNode_FieldValue) { error(&c->error_collector, ast_node_token(elem), "Mixture of `field = value` and value elements in a structure literal is not allowed"); @@ -3030,10 +3061,8 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint check_assignment(c, o, field->type, make_string("structure literal")); } } else { - isize index = 0; - for (; - elem != NULL; - elem = elem->next, index++) { + gb_for_array(index, cl->elems) { + AstNode *elem = cl->elems[index]; if (elem->kind == AstNode_FieldValue) { error(&c->error_collector, ast_node_token(elem), "Mixture of `field = value` and value elements in a structure literal is not allowed"); @@ -3048,8 +3077,8 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint } check_assignment(c, o, field->type, make_string("structure literal")); } - if (cl->elem_count < field_count) { - error(&c->error_collector, cl->close, "Too few values in structure literal, expected %td, got %td", field_count, cl->elem_count); + if (gb_array_count(cl->elems) < field_count) { + error(&c->error_collector, cl->close, "Too few values in structure literal, expected %td, got %td", field_count, gb_array_count(cl->elems)); } } } @@ -3074,10 +3103,10 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint } - i64 index = 0; i64 max = 0; - for (AstNode *elem = cl->elem_list; elem != NULL; elem = elem->next, index++) { - AstNode *e = elem; + isize index = 0; + for (; index < gb_array_count(cl->elems); index++) { + AstNode *e = cl->elems[index]; if (e->kind == AstNode_FieldValue) { error(&c->error_collector, ast_node_token(e), "`field = value` is only allowed in structure literals"); @@ -3088,12 +3117,12 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint if (t->kind == Type_Array && t->Array.count >= 0 && index >= t->Array.count) { - error(&c->error_collector, ast_node_token(elem), "Index %lld is out of bounds (>= %lld) for array literal", index, t->Array.count); + error(&c->error_collector, ast_node_token(e), "Index %lld is out of bounds (>= %lld) for array literal", index, t->Array.count); } if (t->kind == Type_Vector && t->Vector.count >= 0 && index >= t->Vector.count) { - error(&c->error_collector, ast_node_token(elem), "Index %lld is out of bounds (>= %lld) for vector literal", index, t->Vector.count); + error(&c->error_collector, ast_node_token(e), "Index %lld is out of bounds (>= %lld) for vector literal", index, t->Vector.count); } Operand o = {}; @@ -3105,7 +3134,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint if (t->kind == Type_Vector) { if (t->Vector.count > 1 && gb_is_between(index, 2, t->Vector.count-1)) { - error(&c->error_collector, ast_node_token(cl->elem_list), + error(&c->error_collector, ast_node_token(cl->elems[0]), "Expected either 1 (broadcast) or %td elements in vector literal, got %td", t->Vector.count, index); } } @@ -3454,15 +3483,14 @@ void check_expr_or_type(Checker *c, Operand *o, AstNode *e) { gbString write_expr_to_string(gbString str, AstNode *node); -gbString write_field_list_to_string(gbString str, AstNode *field_list, char *sep) { - isize i = 0; - for (AstNode *field = field_list; field != NULL; field = field->next) { +gbString write_fields_to_string(gbString str, AstNodeArray fields, char *sep) { + gb_for_array(i, fields) { + AstNode *field = fields[i]; ast_node(f, Field, field); if (i > 0) str = gb_string_appendc(str, sep); str = write_expr_to_string(str, field); - i++; } return str; } @@ -3594,12 +3622,11 @@ gbString write_expr_to_string(gbString str, AstNode *node) { if (f->is_using) { str = gb_string_appendc(str, "using "); } - isize i = 0; - for (AstNode *name = f->name_list; name != NULL; name = name->next) { + gb_for_array(i, f->names) { + AstNode *name = f->names[i]; if (i > 0) str = gb_string_appendc(str, ", "); str = write_expr_to_string(str, name); - i++; } str = gb_string_appendc(str, ": "); @@ -3609,32 +3636,32 @@ gbString write_expr_to_string(gbString str, AstNode *node) { case_ast_node(ce, CallExpr, node); str = write_expr_to_string(str, ce->proc); str = gb_string_appendc(str, "("); - isize i = 0; - for (AstNode *arg = ce->arg_list; arg != NULL; arg = arg->next) { + + gb_for_array(i, ce->args) { + AstNode *arg = ce->args[i]; if (i > 0) { str = gb_string_appendc(str, ", "); } str = write_expr_to_string(str, arg); - i++; } str = gb_string_appendc(str, ")"); case_end; case_ast_node(pt, ProcType, node); str = gb_string_appendc(str, "proc("); - str = write_field_list_to_string(str, pt->param_list, ", "); + str = write_fields_to_string(str, pt->params, ", "); str = gb_string_appendc(str, ")"); case_end; case_ast_node(st, StructType, node); str = gb_string_appendc(str, "struct{"); - // str = write_field_list_to_string(str, st->decl_list, ", "); + // str = write_fields_to_string(str, st->decl_list, ", "); str = gb_string_appendc(str, "}"); case_end; case_ast_node(st, RawUnionType, node); str = gb_string_appendc(str, "raw_union{"); - // str = write_field_list_to_string(str, st->decl_list, ", "); + // str = write_fields_to_string(str, st->decl_list, ", "); str = gb_string_appendc(str, "}"); case_end; |