diff --git a/src/array.cpp b/src/array.cpp index 6fe54b847..dc52eeb8d 100644 --- a/src/array.cpp +++ b/src/array.cpp @@ -43,11 +43,96 @@ template void array_set_capacity (Array *array, isize capac template Array array_slice (Array const &array, isize lo, isize hi); template Array array_clone (gbAllocator const &a, Array const &array); - - template void array_ordered_remove (Array *array, isize index); template void array_unordered_remove(Array *array, isize index); +template void array_copy(Array *array, Array const &data, isize offset); +template void array_copy(Array *array, Array const &data, isize offset, isize count); + +template T *array_end_ptr(Array *array); + + +template +struct Slice { + T *data; + isize count; + + T &operator[](isize index) { + #if !defined(NO_ARRAY_BOUNDS_CHECK) + GB_ASSERT_MSG(0 <= index && index < count, "Index %td is out of bounds ranges 0..<%td", index, count); + #endif + return data[index]; + } + + T const &operator[](isize index) const { + #if !defined(NO_ARRAY_BOUNDS_CHECK) + GB_ASSERT_MSG(0 <= index && index < count, "Index %td is out of bounds ranges 0..<%td", index, count); + #endif + return data[index]; + } +}; + +template Slice slice_from_array(Array const &a); + + + +template +Slice slice_make(gbAllocator const &allocator, isize count) { + Slice s = {}; + s.data = gb_alloc_array(allocator, T, count); + s.count = count; + return s; +} + + +template +Slice slice_from_array(Array const &a) { + return {a.data, a.count}; +} +template +Slice slice_clone(gbAllocator const &allocator, Slice const &a) { + T *data = cast(T *)gb_alloc_copy_align(allocator, a.data, a.count*gb_size_of(T), gb_align_of(T)); + return {data, a.count}; +} + +template +Slice slice_clone_from_array(gbAllocator const &allocator, Array const &a) { + auto c = array_clone(allocator, a); + return {c.data, c.count}; +} + + +template +void slice_copy(Slice *slice, Slice const &data, isize offset) { + gb_memmove(slice->data+offset, data.data, gb_size_of(T)*data.count); +} +template +void slice_copy(Slice *slice, Slice const &data, isize offset, isize count) { + gb_memmove(slice->data+offset, data.data, gb_size_of(T)*gb_min(data.count, count)); +} + + + +template +void slice_ordered_remove(Slice *array, isize index) { + GB_ASSERT(0 <= index && index < array->count); + + isize bytes = gb_size_of(T) * (array->count-(index+1)); + gb_memmove(array->data+index, array->data+index+1, bytes); + array->count -= 1; +} + +template +void slice_unordered_remove(Slice *array, isize index) { + GB_ASSERT(0 <= index && index < array->count); + + isize n = array->count-1; + if (index != n) { + gb_memmove(array->data+index, array->data+n, gb_size_of(T)); + } + array->count -= 1; +} + template void array_copy(Array *array, Array const &data, isize offset) { diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 248069b97..da07fe4bc 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -113,7 +113,7 @@ Type *check_init_variable(CheckerContext *ctx, Entity *e, Operand *operand, Stri return e->type; } -void check_init_variables(CheckerContext *ctx, Entity **lhs, isize lhs_count, Array const &inits, String context_name) { +void check_init_variables(CheckerContext *ctx, Entity **lhs, isize lhs_count, Slice const &inits, String context_name) { if ((lhs == nullptr || lhs_count == 0) && inits.count == 0) { return; } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 11ccf2dab..94a3467d2 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -73,7 +73,7 @@ void update_expr_type (CheckerContext *c, Ast *e, Type *type, bool check_is_terminating (Ast *node, String const &label); bool check_has_break (Ast *stmt, String const &label, bool implicit); void check_stmt (CheckerContext *c, Ast *node, u32 flags); -void check_stmt_list (CheckerContext *c, Array const &stmts, u32 flags); +void check_stmt_list (CheckerContext *c, Slice const &stmts, u32 flags); void check_init_constant (CheckerContext *c, Entity *e, Operand *operand); bool check_representable_as_constant(CheckerContext *c, ExactValue in_value, Type *type, ExactValue *out_value); bool check_procedure_type (CheckerContext *c, Type *type, Ast *proc_type_node, Array *operands = nullptr); @@ -133,7 +133,7 @@ void error_operand_no_value(Operand *o) { } -void check_scope_decls(CheckerContext *c, Array const &nodes, isize reserve_size) { +void check_scope_decls(CheckerContext *c, Slice const &nodes, isize reserve_size) { Scope *s = c->scope; check_collect_entities(c, nodes); @@ -6062,7 +6062,7 @@ isize add_dependencies_from_unpacking(CheckerContext *c, Entity **lhs, isize lhs } -bool check_assignment_arguments(CheckerContext *ctx, Array const &lhs, Array *operands, Array const &rhs) { +bool check_assignment_arguments(CheckerContext *ctx, Array const &lhs, Array *operands, Slice const &rhs) { bool optional_ok = false; isize tuple_index = 0; for_array(i, rhs) { @@ -6146,7 +6146,7 @@ bool check_assignment_arguments(CheckerContext *ctx, Array const &lhs, -bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize lhs_count, Array *operands, Array const &rhs, bool allow_ok, bool is_variadic) { +bool check_unpack_arguments(CheckerContext *ctx, Entity **lhs, isize lhs_count, Array *operands, Slice const &rhs, bool allow_ok, bool is_variadic) { bool optional_ok = false; isize tuple_index = 0; for_array(i, rhs) { @@ -6748,7 +6748,7 @@ Entity **populate_proc_parameter_list(CheckerContext *c, Type *proc_type, isize } -bool evaluate_where_clauses(CheckerContext *ctx, Ast *call_expr, Scope *scope, Array *clauses, bool print_err) { +bool evaluate_where_clauses(CheckerContext *ctx, Ast *call_expr, Scope *scope, Slice *clauses, bool print_err) { if (clauses != nullptr) { for_array(i, *clauses) { Ast *clause = (*clauses)[i]; @@ -6813,7 +6813,7 @@ bool evaluate_where_clauses(CheckerContext *ctx, Ast *call_expr, Scope *scope, A } -CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type *proc_type, Ast *call, Array const &args) { +CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type *proc_type, Ast *call, Slice const &args) { ast_node(ce, CallExpr, call); CallArgumentCheckerType *call_checker = check_call_arguments_internal; @@ -7598,7 +7598,7 @@ CallArgumentError check_polymorphic_record_type(CheckerContext *c, Operand *oper -ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call, Ast *proc, Array const &args, ProcInlining inlining, Type *type_hint) { +ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call, Ast *proc, Slice const &args, ProcInlining inlining, Type *type_hint) { if (proc != nullptr && proc->kind == Ast_BasicDirective) { ast_node(bd, BasicDirective, proc); @@ -8150,7 +8150,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type case_ast_node(bl, BasicLit, node); Type *t = t_invalid; - switch (bl->value.kind) { + switch (node->tav.value.kind) { case ExactValue_String: t = t_untyped_string; break; case ExactValue_Float: t = t_untyped_float; break; case ExactValue_Complex: t = t_untyped_complex; break; @@ -8168,7 +8168,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type o->mode = Addressing_Constant; o->type = t; - o->value = bl->value; + o->value = node->tav.value; case_end; case_ast_node(bd, BasicDirective, node); @@ -9600,9 +9600,9 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type - auto modified_args = array_make(heap_allocator(), ce->args.count+1); + auto modified_args = slice_make(heap_allocator(), ce->args.count+1); modified_args[0] = first_arg; - array_copy(&modified_args, ce->args, 1); + slice_copy(&modified_args, ce->args, 1); ce->args = modified_args; se->modified_call = true; @@ -10210,7 +10210,7 @@ void check_expr_or_type(CheckerContext *c, Operand *o, Ast *e, Type *type_hint) gbString write_expr_to_string(gbString str, Ast *node); -gbString write_struct_fields_to_string(gbString str, Array const ¶ms) { +gbString write_struct_fields_to_string(gbString str, Slice const ¶ms) { for_array(i, params) { if (i > 0) { str = gb_string_appendc(str, ", "); diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 4cafa8df5..ad72256c3 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -15,7 +15,7 @@ bool is_divigering_stmt(Ast *stmt) { return t->kind == Type_Proc && t->Proc.diverging; } -void check_stmt_list(CheckerContext *ctx, Array const &stmts, u32 flags) { +void check_stmt_list(CheckerContext *ctx, Slice const &stmts, u32 flags) { if (stmts.count == 0) { return; } @@ -78,7 +78,7 @@ void check_stmt_list(CheckerContext *ctx, Array const &stmts, u32 flags) } } -bool check_is_terminating_list(Array const &stmts, String const &label) { +bool check_is_terminating_list(Slice const &stmts, String const &label) { // Iterate backwards for (isize n = stmts.count-1; n >= 0; n--) { Ast *stmt = stmts[n]; @@ -96,7 +96,7 @@ bool check_is_terminating_list(Array const &stmts, String const &label) { return false; } -bool check_has_break_list(Array const &stmts, String const &label, bool implicit) { +bool check_has_break_list(Slice const &stmts, String const &label, bool implicit) { for_array(i, stmts) { Ast *stmt = stmts[i]; if (check_has_break(stmt, label, implicit)) { diff --git a/src/check_type.cpp b/src/check_type.cpp index af0c70119..6ea17eca6 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -117,7 +117,7 @@ bool does_field_type_allow_using(Type *t) { return false; } -void check_struct_fields(CheckerContext *ctx, Ast *node, Array *fields, Array *tags, Array const ¶ms, +void check_struct_fields(CheckerContext *ctx, Ast *node, Array *fields, Array *tags, Slice const ¶ms, isize init_field_capacity, Type *struct_type, String context) { *fields = array_make(heap_allocator(), 0, init_field_capacity); *tags = array_make(heap_allocator(), 0, init_field_capacity); @@ -389,7 +389,7 @@ void check_struct_type(CheckerContext *ctx, Type *struct_type, Ast *node, Array< if (st->polymorphic_params != nullptr) { ast_node(field_list, FieldList, st->polymorphic_params); - Array params = field_list->list; + Slice params = field_list->list; if (params.count != 0) { isize variable_count = 0; for_array(i, params) { @@ -607,7 +607,7 @@ void check_union_type(CheckerContext *ctx, Type *union_type, Ast *node, Arraypolymorphic_params != nullptr) { ast_node(field_list, FieldList, ut->polymorphic_params); - Array params = field_list->list; + Slice params = field_list->list; if (params.count != 0) { isize variable_count = 0; for_array(i, params) { @@ -1516,7 +1516,7 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is bool success = true; ast_node(field_list, FieldList, _params); - Array params = field_list->list; + Slice params = field_list->list; if (params.count == 0) { if (success_) *success_ = success; @@ -1875,7 +1875,7 @@ Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) { return nullptr; } ast_node(field_list, FieldList, _results); - Array results = field_list->list; + Slice results = field_list->list; if (results.count == 0) { return nullptr; diff --git a/src/checker.cpp b/src/checker.cpp index 380872f24..f02b927c3 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -2854,7 +2854,7 @@ void check_decl_attributes(CheckerContext *c, Array const &attributes, De } -isize get_total_value_count(Array const &values) { +isize get_total_value_count(Slice const &values) { isize count = 0; for_array(i, values) { Type *t = type_of_expr(values[i]); @@ -3068,7 +3068,7 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) { } else { entity_visibility_kind = kind; } - array_unordered_remove(elems, j); + slice_unordered_remove(elems, j); j -= 1; } } @@ -3252,7 +3252,7 @@ void check_add_foreign_block_decl(CheckerContext *ctx, Ast *decl) { } // NOTE(bill): If file_scopes == nullptr, this will act like a local scope -void check_collect_entities(CheckerContext *c, Array const &nodes) { +void check_collect_entities(CheckerContext *c, Slice const &nodes) { for_array(decl_index, nodes) { Ast *decl = nodes[decl_index]; if (!is_ast_decl(decl) && !is_ast_when_stmt(decl)) { @@ -3783,7 +3783,7 @@ void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) { } } -bool collect_checked_packages_from_decl_list(Checker *c, Array const &decls) { +bool collect_checked_packages_from_decl_list(Checker *c, Slice const &decls) { bool new_files = false; for_array(i, decls) { Ast *decl = decls[i]; @@ -3805,7 +3805,7 @@ bool collect_checked_packages_from_decl_list(Checker *c, Array const &dec } // Returns true if a new package is present -bool collect_file_decls(CheckerContext *ctx, Array const &decls); +bool collect_file_decls(CheckerContext *ctx, Slice const &decls); bool collect_file_decls_from_when_stmt(CheckerContext *ctx, AstWhenStmt *ws); bool collect_when_stmt_from_file(CheckerContext *ctx, AstWhenStmt *ws) { @@ -3880,7 +3880,7 @@ bool collect_file_decls_from_when_stmt(CheckerContext *ctx, AstWhenStmt *ws) { return false; } -bool collect_file_decls(CheckerContext *ctx, Array const &decls) { +bool collect_file_decls(CheckerContext *ctx, Slice const &decls) { GB_ASSERT(ctx->scope->flags&ScopeFlag_File); if (collect_checked_packages_from_decl_list(ctx->checker, decls)) { diff --git a/src/checker.hpp b/src/checker.hpp index e6111d2af..9c9b77ac3 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -384,7 +384,7 @@ void check_add_foreign_import_decl(CheckerContext *c, Ast *decl); bool check_arity_match(CheckerContext *c, AstValueDecl *vd, bool is_global = false); -void check_collect_entities(CheckerContext *c, Array const &nodes); +void check_collect_entities(CheckerContext *c, Slice const &nodes); void check_collect_entities_from_when_stmt(CheckerContext *c, AstWhenStmt *ws); void check_delayed_file_import_entity(CheckerContext *c, Ast *decl); diff --git a/src/entity.cpp b/src/entity.cpp index 708b0862c..0aece39c3 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -165,7 +165,7 @@ struct Entity { Scope *scope; } ImportName; struct { - Array paths; + Slice paths; String name; } LibraryName; i32 Nil; @@ -333,7 +333,7 @@ Entity *alloc_entity_import_name(Scope *scope, Token token, Type *type, } Entity *alloc_entity_library_name(Scope *scope, Token token, Type *type, - Array paths, String name) { + Slice paths, String name) { Entity *entity = alloc_entity(Entity_LibraryName, scope, token, type); entity->LibraryName.paths = paths; entity->LibraryName.name = name; diff --git a/src/ir.cpp b/src/ir.cpp index 7b6301e30..1f2819ccf 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -6884,7 +6884,7 @@ irValue *ir_find_global_variable(irProcedure *proc, String name) { return *value; } -void ir_build_stmt_list(irProcedure *proc, Array stmts); +void ir_build_stmt_list(irProcedure *proc, Slice stmts); void ir_build_assign_op(irProcedure *proc, irAddr const &lhs, irValue *value, TokenKind op); bool is_double_pointer(Type *t) { @@ -9689,7 +9689,7 @@ void ir_build_constant_value_decl(irProcedure *proc, AstValueDecl *vd) { } } -void ir_build_stmt_list(irProcedure *proc, Array stmts) { +void ir_build_stmt_list(irProcedure *proc, Slice stmts) { // NOTE(bill): Precollect constant entities for_array(i, stmts) { Ast *stmt = stmts[i]; @@ -10899,7 +10899,7 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) { ast_node(body, BlockStmt, ss->body); - Array default_stmts = {}; + Slice default_stmts = {}; irBlock *default_fall = nullptr; irBlock *default_block = nullptr; diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 6542da69b..50d200551 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -3134,7 +3134,7 @@ void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd) { } -void lb_build_stmt_list(lbProcedure *p, Array const &stmts) { +void lb_build_stmt_list(lbProcedure *p, Slice const &stmts) { for_array(i, stmts) { Ast *stmt = stmts[i]; switch (stmt->kind) { @@ -3865,7 +3865,7 @@ void lb_build_switch_stmt(lbProcedure *p, AstSwitchStmt *ss) { ast_node(body, BlockStmt, ss->body); - Array default_stmts = {}; + Slice default_stmts = {}; lbBlock *default_fall = nullptr; lbBlock *default_block = nullptr; diff --git a/src/parser.cpp b/src/parser.cpp index 476504d52..cf464f149 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -126,7 +126,7 @@ Ast *alloc_ast_node(AstFile *f, AstKind kind) { } Ast *clone_ast(Ast *node); -Array clone_ast_array(Array array) { +Array clone_ast_array(Array const &array) { Array result = {}; if (array.count > 0) { result = array_make(ast_allocator(nullptr), array.count); @@ -136,6 +136,16 @@ Array clone_ast_array(Array array) { } return result; } +Slice clone_ast_array(Slice const &array) { + Slice result = {}; + if (array.count > 0) { + result = slice_clone(permanent_allocator(), array); + for_array(i, array) { + result[i] = clone_ast(array[i]); + } + } + return result; +} Ast *clone_ast(Ast *node) { if (node == nullptr) { @@ -537,10 +547,10 @@ Ast *ast_paren_expr(AstFile *f, Ast *expr, Token open, Token close) { return result; } -Ast *ast_call_expr(AstFile *f, Ast *proc, Array args, Token open, Token close, Token ellipsis) { +Ast *ast_call_expr(AstFile *f, Ast *proc, Array const &args, Token open, Token close, Token ellipsis) { Ast *result = alloc_ast_node(f, Ast_CallExpr); result->CallExpr.proc = proc; - result->CallExpr.args = args; + result->CallExpr.args = slice_from_array(args); result->CallExpr.open = open; result->CallExpr.close = close; result->CallExpr.ellipsis = ellipsis; @@ -624,7 +634,8 @@ Ast *ast_undef(AstFile *f, Token token) { Ast *ast_basic_lit(AstFile *f, Token basic_lit) { Ast *result = alloc_ast_node(f, Ast_BasicLit); result->BasicLit.token = basic_lit; - result->BasicLit.value = exact_value_from_basic_literal(basic_lit); + result->tav.mode = Addressing_Constant; + result->tav.value = exact_value_from_basic_literal(basic_lit); return result; } @@ -643,12 +654,12 @@ Ast *ast_ellipsis(AstFile *f, Token token, Ast *expr) { } -Ast *ast_proc_group(AstFile *f, Token token, Token open, Token close, Array args) { +Ast *ast_proc_group(AstFile *f, Token token, Token open, Token close, Array const &args) { Ast *result = alloc_ast_node(f, Ast_ProcGroup); result->ProcGroup.token = token; result->ProcGroup.open = open; result->ProcGroup.close = close; - result->ProcGroup.args = args; + result->ProcGroup.args = slice_from_array(args); return result; } @@ -658,7 +669,7 @@ Ast *ast_proc_lit(AstFile *f, Ast *type, Ast *body, u64 tags, Token where_token, result->ProcLit.body = body; result->ProcLit.tags = tags; result->ProcLit.where_token = where_token; - result->ProcLit.where_clauses = where_clauses; + result->ProcLit.where_clauses = slice_from_array(where_clauses); return result; } @@ -670,10 +681,10 @@ Ast *ast_field_value(AstFile *f, Ast *field, Ast *value, Token eq) { return result; } -Ast *ast_compound_lit(AstFile *f, Ast *type, Array elems, Token open, Token close) { +Ast *ast_compound_lit(AstFile *f, Ast *type, Array const &elems, Token open, Token close) { Ast *result = alloc_ast_node(f, Ast_CompoundLit); result->CompoundLit.type = type; - result->CompoundLit.elems = elems; + result->CompoundLit.elems = slice_from_array(elems); result->CompoundLit.open = open; result->CompoundLit.close = close; return result; @@ -736,7 +747,7 @@ Ast *ast_inline_asm_expr(AstFile *f, Token token, Token open, Token close, result->InlineAsmExpr.token = token; result->InlineAsmExpr.open = open; result->InlineAsmExpr.close = close; - result->InlineAsmExpr.param_types = param_types; + result->InlineAsmExpr.param_types = slice_from_array(param_types); result->InlineAsmExpr.return_type = return_type; result->InlineAsmExpr.asm_string = asm_string; result->InlineAsmExpr.constraints_string = constraints_string; @@ -768,18 +779,18 @@ Ast *ast_expr_stmt(AstFile *f, Ast *expr) { return result; } -Ast *ast_assign_stmt(AstFile *f, Token op, Array lhs, Array rhs) { +Ast *ast_assign_stmt(AstFile *f, Token op, Array const &lhs, Array const &rhs) { Ast *result = alloc_ast_node(f, Ast_AssignStmt); result->AssignStmt.op = op; - result->AssignStmt.lhs = lhs; - result->AssignStmt.rhs = rhs; + result->AssignStmt.lhs = slice_from_array(lhs); + result->AssignStmt.rhs = slice_from_array(rhs); return result; } -Ast *ast_block_stmt(AstFile *f, Array stmts, Token open, Token close) { +Ast *ast_block_stmt(AstFile *f, Array const &stmts, Token open, Token close) { Ast *result = alloc_ast_node(f, Ast_BlockStmt); - result->BlockStmt.stmts = stmts; + result->BlockStmt.stmts = slice_from_array(stmts); result->BlockStmt.open = open; result->BlockStmt.close = close; return result; @@ -805,10 +816,10 @@ Ast *ast_when_stmt(AstFile *f, Token token, Ast *cond, Ast *body, Ast *else_stmt } -Ast *ast_return_stmt(AstFile *f, Token token, Array results) { +Ast *ast_return_stmt(AstFile *f, Token token, Array const &results) { Ast *result = alloc_ast_node(f, Ast_ReturnStmt); result->ReturnStmt.token = token; - result->ReturnStmt.results = results; + result->ReturnStmt.results = slice_from_array(results); return result; } @@ -866,11 +877,11 @@ Ast *ast_type_switch_stmt(AstFile *f, Token token, Ast *tag, Ast *body) { return result; } -Ast *ast_case_clause(AstFile *f, Token token, Array list, Array stmts) { +Ast *ast_case_clause(AstFile *f, Token token, Array const &list, Array const &stmts) { Ast *result = alloc_ast_node(f, Ast_CaseClause); result->CaseClause.token = token; - result->CaseClause.list = list; - result->CaseClause.stmts = stmts; + result->CaseClause.list = slice_from_array(list); + result->CaseClause.stmts = slice_from_array(stmts); return result; } @@ -889,10 +900,10 @@ Ast *ast_branch_stmt(AstFile *f, Token token, Ast *label) { return result; } -Ast *ast_using_stmt(AstFile *f, Token token, Array list) { +Ast *ast_using_stmt(AstFile *f, Token token, Array const &list) { Ast *result = alloc_ast_node(f, Ast_UsingStmt); result->UsingStmt.token = token; - result->UsingStmt.list = list; + result->UsingStmt.list = slice_from_array(list); return result; } @@ -905,10 +916,10 @@ Ast *ast_bad_decl(AstFile *f, Token begin, Token end) { return result; } -Ast *ast_field(AstFile *f, Array names, Ast *type, Ast *default_value, u32 flags, Token tag, +Ast *ast_field(AstFile *f, Array const &names, Ast *type, Ast *default_value, u32 flags, Token tag, CommentGroup *docs, CommentGroup *comment) { Ast *result = alloc_ast_node(f, Ast_Field); - result->Field.names = names; + result->Field.names = slice_from_array(names); result->Field.type = type; result->Field.default_value = default_value; result->Field.flags = flags; @@ -918,10 +929,10 @@ Ast *ast_field(AstFile *f, Array names, Ast *type, Ast *default_value, u3 return result; } -Ast *ast_field_list(AstFile *f, Token token, Array list) { +Ast *ast_field_list(AstFile *f, Token token, Array const &list) { Ast *result = alloc_ast_node(f, Ast_FieldList); result->FieldList.token = token; - result->FieldList.list = list; + result->FieldList.list = slice_from_array(list); return result; } @@ -1002,7 +1013,7 @@ Ast *ast_dynamic_array_type(AstFile *f, Token token, Ast *elem) { return result; } -Ast *ast_struct_type(AstFile *f, Token token, Array fields, isize field_count, +Ast *ast_struct_type(AstFile *f, Token token, Slice fields, isize field_count, Ast *polymorphic_params, bool is_packed, bool is_raw_union, Ast *align, Token where_token, Array const &where_clauses) { @@ -1015,38 +1026,38 @@ Ast *ast_struct_type(AstFile *f, Token token, Array fields, isize field_c result->StructType.is_raw_union = is_raw_union; result->StructType.align = align; result->StructType.where_token = where_token; - result->StructType.where_clauses = where_clauses; + result->StructType.where_clauses = slice_from_array(where_clauses); return result; } -Ast *ast_union_type(AstFile *f, Token token, Array variants, Ast *polymorphic_params, Ast *align, bool no_nil, bool maybe, +Ast *ast_union_type(AstFile *f, Token token, Array const &variants, Ast *polymorphic_params, Ast *align, bool no_nil, bool maybe, Token where_token, Array const &where_clauses) { Ast *result = alloc_ast_node(f, Ast_UnionType); result->UnionType.token = token; - result->UnionType.variants = variants; + result->UnionType.variants = slice_from_array(variants); result->UnionType.polymorphic_params = polymorphic_params; result->UnionType.align = align; result->UnionType.no_nil = no_nil; - result->UnionType.maybe = maybe; + result->UnionType.maybe = maybe; result->UnionType.where_token = where_token; - result->UnionType.where_clauses = where_clauses; + result->UnionType.where_clauses = slice_from_array(where_clauses); return result; } -Ast *ast_enum_type(AstFile *f, Token token, Ast *base_type, Array fields) { +Ast *ast_enum_type(AstFile *f, Token token, Ast *base_type, Array const &fields) { Ast *result = alloc_ast_node(f, Ast_EnumType); result->EnumType.token = token; result->EnumType.base_type = base_type; - result->EnumType.fields = fields; + result->EnumType.fields = slice_from_array(fields); return result; } -Ast *ast_bit_field_type(AstFile *f, Token token, Array fields, Ast *align) { +Ast *ast_bit_field_type(AstFile *f, Token token, Array const &fields, Ast *align) { Ast *result = alloc_ast_node(f, Ast_BitFieldType); result->BitFieldType.token = token; - result->BitFieldType.fields = fields; + result->BitFieldType.fields = slice_from_array(fields); result->BitFieldType.align = align; return result; } @@ -1069,7 +1080,7 @@ Ast *ast_map_type(AstFile *f, Token token, Ast *key, Ast *value) { Ast *ast_foreign_block_decl(AstFile *f, Token token, Ast *foreign_library, Ast *body, - CommentGroup *docs) { + CommentGroup *docs) { Ast *result = alloc_ast_node(f, Ast_ForeignBlockDecl); result->ForeignBlockDecl.token = token; result->ForeignBlockDecl.foreign_library = foreign_library; @@ -1087,12 +1098,12 @@ Ast *ast_label_decl(AstFile *f, Token token, Ast *name) { return result; } -Ast *ast_value_decl(AstFile *f, Array names, Ast *type, Array values, bool is_mutable, +Ast *ast_value_decl(AstFile *f, Array const &names, Ast *type, Array const &values, bool is_mutable, CommentGroup *docs, CommentGroup *comment) { Ast *result = alloc_ast_node(f, Ast_ValueDecl); - result->ValueDecl.names = names; + result->ValueDecl.names = slice_from_array(names); result->ValueDecl.type = type; - result->ValueDecl.values = values; + result->ValueDecl.values = slice_from_array(values); result->ValueDecl.is_mutable = is_mutable; result->ValueDecl.docs = docs; result->ValueDecl.comment = comment; @@ -1126,7 +1137,7 @@ Ast *ast_foreign_import_decl(AstFile *f, Token token, Array filepaths, To CommentGroup *docs, CommentGroup *comment) { Ast *result = alloc_ast_node(f, Ast_ForeignImportDecl); result->ForeignImportDecl.token = token; - result->ForeignImportDecl.filepaths = filepaths; + result->ForeignImportDecl.filepaths = slice_from_array(filepaths); result->ForeignImportDecl.library_name = library_name; result->ForeignImportDecl.docs = docs; result->ForeignImportDecl.comment = comment; @@ -1136,11 +1147,11 @@ Ast *ast_foreign_import_decl(AstFile *f, Token token, Array filepaths, To } -Ast *ast_attribute(AstFile *f, Token token, Token open, Token close, Array elems) { +Ast *ast_attribute(AstFile *f, Token token, Token open, Token close, Array const &elems) { Ast *result = alloc_ast_node(f, Ast_Attribute); result->Attribute.token = token; result->Attribute.open = open; - result->Attribute.elems = elems; + result->Attribute.elems = slice_from_array(elems); result->Attribute.close = close; return result; } @@ -1192,7 +1203,7 @@ CommentGroup *consume_comment_group(AstFile *f, isize n, isize *end_line_) { CommentGroup *comments = nullptr; if (list.count > 0) { comments = gb_alloc_item(heap_allocator(), CommentGroup); - comments->list = list; + comments->list = slice_from_array(list); array_add(&f->comments, comments); } return comments; @@ -2181,7 +2192,7 @@ Ast *parse_operand(AstFile *f, bool lhs) { Ast *fields = parse_struct_field_list(f, &name_count); Token close = expect_token(f, Token_CloseBrace); - Array decls = {}; + Slice decls = {}; if (fields != nullptr) { GB_ASSERT(fields->kind == Ast_FieldList); decls = fields->FieldList.list; @@ -4887,7 +4898,7 @@ bool determine_path_from_string(gbMutex *file_mutex, Ast *node, String base_dir, -void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, Array &decls); +void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, Slice &decls); void parse_setup_file_when_stmt(Parser *p, AstFile *f, String base_dir, AstWhenStmt *ws) { if (ws->body != nullptr) { @@ -4908,7 +4919,7 @@ void parse_setup_file_when_stmt(Parser *p, AstFile *f, String base_dir, AstWhenS } } -void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, Array &decls) { +void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, Slice &decls) { for_array(i, decls) { Ast *node = decls[i]; if (!is_ast_decl(node) && @@ -4947,8 +4958,7 @@ void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, Array } else if (node->kind == Ast_ForeignImportDecl) { ast_node(fl, ForeignImportDecl, node); - fl->fullpaths.allocator = heap_allocator(); - array_reserve(&fl->fullpaths, fl->filepaths.count); + auto fullpaths = array_make(permanent_allocator(), 0, fl->filepaths.count); for_array(fp_idx, fl->filepaths) { String file_str = fl->filepaths[fp_idx].string; @@ -4962,14 +4972,17 @@ void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, Array } fullpath = foreign_path; } - array_add(&fl->fullpaths, fullpath); + array_add(&fullpaths, fullpath); } - if (fl->fullpaths.count == 0) { + if (fullpaths.count == 0) { syntax_error(decls[i], "No foreign paths found"); decls[i] = ast_bad_decl(f, fl->filepaths[0], fl->filepaths[fl->filepaths.count-1]); goto end; } + fl->fullpaths = slice_from_array(fullpaths); + + } else if (node->kind == Ast_WhenStmt) { ast_node(ws, WhenStmt, node); parse_setup_file_when_stmt(p, f, base_dir, ws); @@ -5131,12 +5144,12 @@ bool parse_file(Parser *p, AstFile *f) { f->pkg_decl = pd; if (f->error_count == 0) { - f->decls = array_make(heap_allocator()); + auto decls = array_make(heap_allocator()); while (f->curr_token.kind != Token_EOF) { Ast *stmt = parse_stmt(f); if (stmt && stmt->kind != Ast_EmptyStmt) { - array_add(&f->decls, stmt); + array_add(&decls, stmt); if (stmt->kind == Ast_ExprStmt && stmt->ExprStmt.expr != nullptr && stmt->ExprStmt.expr->kind == Ast_ProcLit) { @@ -5145,6 +5158,8 @@ bool parse_file(Parser *p, AstFile *f) { } } + f->decls = slice_from_array(decls); + parse_setup_file_decls(p, f, base_dir, f->decls); } diff --git a/src/parser.hpp b/src/parser.hpp index 9a7ddd4b9..3be7939fa 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -46,7 +46,7 @@ enum ParseFileError { }; struct CommentGroup { - Array list; // Token_Comment + Slice list; // Token_Comment }; @@ -98,8 +98,8 @@ struct AstFile { bool in_foreign_block; bool allow_type; - Array decls; - Array imports; // 'import' 'using import' + Slice decls; + Array imports; // 'import' isize directive_count; Ast * curr_proc; @@ -277,7 +277,6 @@ char const *inline_asm_dialect_strings[InlineAsmDialect_COUNT] = { AST_KIND(Undef, "undef", Token) \ AST_KIND(BasicLit, "basic literal", struct { \ Token token; \ - ExactValue value; \ }) \ AST_KIND(BasicDirective, "basic directive", struct { \ Token token; \ @@ -291,7 +290,7 @@ char const *inline_asm_dialect_strings[InlineAsmDialect_COUNT] = { Token token; \ Token open; \ Token close; \ - Array args; \ + Slice args; \ }) \ AST_KIND(ProcLit, "procedure literal", struct { \ Ast *type; \ @@ -299,12 +298,12 @@ char const *inline_asm_dialect_strings[InlineAsmDialect_COUNT] = { u64 tags; \ ProcInlining inlining; \ Token where_token; \ - Array where_clauses; \ + Slice where_clauses; \ DeclInfo *decl; \ }) \ AST_KIND(CompoundLit, "compound literal", struct { \ Ast *type; \ - Array elems; \ + Slice elems; \ Token open, close; \ i64 max_count; \ }) \ @@ -327,7 +326,7 @@ AST_KIND(_ExprBegin, "", bool) \ }) \ AST_KIND(CallExpr, "call expression", struct { \ Ast * proc; \ - Array args; \ + Slice args; \ Token open; \ Token close; \ Token ellipsis; \ @@ -344,7 +343,7 @@ AST_KIND(_ExprBegin, "", bool) \ AST_KIND(InlineAsmExpr, "inline asm expression", struct { \ Token token; \ Token open, close; \ - Array param_types; \ + Slice param_types; \ Ast *return_type; \ Ast *asm_string; \ Ast *constraints_string; \ @@ -364,11 +363,11 @@ AST_KIND(_StmtBegin, "", bool) \ }) \ AST_KIND(AssignStmt, "assign statement", struct { \ Token op; \ - Array lhs, rhs; \ + Slice lhs, rhs; \ }) \ AST_KIND(_ComplexStmtBegin, "", bool) \ AST_KIND(BlockStmt, "block statement", struct { \ - Array stmts; \ + Slice stmts; \ Ast *label; \ Token open, close; \ }) \ @@ -390,7 +389,7 @@ AST_KIND(_ComplexStmtBegin, "", bool) \ }) \ AST_KIND(ReturnStmt, "return statement", struct { \ Token token; \ - Array results; \ + Slice results; \ }) \ AST_KIND(ForStmt, "for statement", struct { \ Token token; \ @@ -420,8 +419,8 @@ AST_KIND(_ComplexStmtBegin, "", bool) \ }) \ AST_KIND(CaseClause, "case clause", struct { \ Token token; \ - Array list; \ - Array stmts; \ + Slice list; \ + Slice stmts; \ Entity *implicit_entity; \ }) \ AST_KIND(SwitchStmt, "switch statement", struct { \ @@ -438,12 +437,12 @@ AST_KIND(_ComplexStmtBegin, "", bool) \ Ast *tag; \ Ast *body; \ bool partial; \ -}) \ + }) \ AST_KIND(DeferStmt, "defer statement", struct { Token token; Ast *stmt; }) \ AST_KIND(BranchStmt, "branch statement", struct { Token token; Ast *label; }) \ AST_KIND(UsingStmt, "using statement", struct { \ Token token; \ - Array list; \ + Slice list; \ }) \ AST_KIND(_ComplexStmtEnd, "", bool) \ AST_KIND(_StmtEnd, "", bool) \ @@ -461,9 +460,9 @@ AST_KIND(_DeclBegin, "", bool) \ Ast *name; \ }) \ AST_KIND(ValueDecl, "value declaration", struct { \ - Array names; \ + Slice names; \ Ast * type; \ - Array values; \ + Slice values; \ Array attributes; \ CommentGroup *docs; \ CommentGroup *comment; \ @@ -488,10 +487,10 @@ AST_KIND(_DeclBegin, "", bool) \ }) \ AST_KIND(ForeignImportDecl, "foreign import declaration", struct { \ Token token; \ - Array filepaths; \ + Slice filepaths; \ Token library_name; \ String collection_name; \ - Array fullpaths; \ + Slice fullpaths; \ Array attributes; \ CommentGroup *docs; \ CommentGroup *comment; \ @@ -499,11 +498,11 @@ AST_KIND(_DeclBegin, "", bool) \ AST_KIND(_DeclEnd, "", bool) \ AST_KIND(Attribute, "attribute", struct { \ Token token; \ - Array elems; \ + Slice elems; \ Token open, close; \ }) \ AST_KIND(Field, "field", struct { \ - Array names; \ + Slice names; \ Ast * type; \ Ast * default_value; \ Token tag; \ @@ -513,7 +512,7 @@ AST_KIND(_DeclEnd, "", bool) \ }) \ AST_KIND(FieldList, "field list", struct { \ Token token; \ - Array list; \ + Slice list; \ }) \ AST_KIND(_TypeBegin, "", bool) \ AST_KIND(TypeidType, "typeid", struct { \ @@ -567,34 +566,34 @@ AST_KIND(_TypeBegin, "", bool) \ }) \ AST_KIND(StructType, "struct type", struct { \ Token token; \ - Array fields; \ + Slice fields; \ isize field_count; \ Ast *polymorphic_params; \ Ast *align; \ Token where_token; \ - Array where_clauses; \ + Slice where_clauses; \ bool is_packed; \ bool is_raw_union; \ }) \ AST_KIND(UnionType, "union type", struct { \ Token token; \ - Array variants; \ + Slice variants; \ Ast *polymorphic_params; \ Ast * align; \ bool maybe; \ bool no_nil; \ Token where_token; \ - Array where_clauses; \ + Slice where_clauses; \ }) \ AST_KIND(EnumType, "enum type", struct { \ Token token; \ Ast * base_type; \ - Array fields; /* FieldValue */ \ + Slice fields; /* FieldValue */ \ bool is_using; \ }) \ AST_KIND(BitFieldType, "bit field type", struct { \ Token token; \ - Array fields; /* FieldValue with : */ \ + Slice fields; /* FieldValue with : */ \ Ast * align; \ }) \ AST_KIND(BitSetType, "bit set type", struct { \