diff --git a/lib/std/collections/range.c3 b/lib/std/collections/range.c3 new file mode 100644 index 000000000..e1b1216a4 --- /dev/null +++ b/lib/std/collections/range.c3 @@ -0,0 +1,26 @@ +/** + * @checked Type{} < Type{} : "The type must be comparable" + * @checked Type{} + (Type)1 : "The type must be possible to add to" + **/ +module std::collections::range; + +struct Range +{ + Type start; + Type end; +} + +fn usz Range.len(Range* range) @operator(len) +{ + if (range.end < range.start) return 0; + return (usz)(range.end - range.start); +} + +/** + * @require index < range.len() : "Can't index into an empty range" + **/ +fn Type Range.get(Range* range, usz index) @operator([]) +{ + return range.start + (Type)index; +} + diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index a7350d440..0f992ebb7 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -917,7 +917,7 @@ Module *compiler_find_or_create_module(Path *module_name, const char **parameter module->stage = ANALYSIS_NOT_BEGUN; module->parameters = parameters; module->is_generic = vec_size(parameters) > 0; - htable_init(&module->symbols, 0x10000); + htable_init(&module->symbols, 0x1000); htable_set(&global_context.modules, (void *)module_name->module, module); if (parameters) { diff --git a/src/compiler/context.c b/src/compiler/context.c index ccc843512..878f498f2 100644 --- a/src/compiler/context.c +++ b/src/compiler/context.c @@ -10,7 +10,7 @@ CompilationUnit *unit_create(File *file) CompilationUnit *unit = CALLOCS(CompilationUnit); unit->file = file; unit->is_interface_file = str_has_suffix(file->name, ".c3i"); - htable_init(&unit->local_symbols, 64 * 1024); + htable_init(&unit->local_symbols, 1024); return unit; } diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 837b80e70..882af00c1 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -1936,7 +1936,7 @@ bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *s AstId assert_first = 0; AstId* next = &assert_first; - if (!sema_analyse_contracts(¯o_context, docs, &next, call_expr->span)) return false; + if (!sema_analyse_contracts(¯o_context, docs, &next, call_expr->span)) goto EXIT_FAIL; sema_append_contract_asserts(assert_first, body); if (!sema_analyse_statement(¯o_context, body)) goto EXIT_FAIL; @@ -1951,13 +1951,13 @@ bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *s SEMA_ERROR(decl, "Missing return in macro that should evaluate to %s.", type_quoted_error_string(rtype)); - return SCOPE_POP_ERROR(); + goto EXIT_FAIL; } } else if (is_no_return) { SEMA_ERROR(context->returns[0], "Return used despite macro being marked '@noreturn'."); - return SCOPE_POP_ERROR(); + goto EXIT_FAIL; } if (rtype) @@ -1976,7 +1976,7 @@ bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *s { if (rtype == type_void) continue; SEMA_ERROR(return_stmt, "Expected returning a value of type %s.", type_quoted_error_string(rtype)); - return SCOPE_POP_ERROR(); + goto EXIT_FAIL; } Type *type = ret_expr->type; if (inferred_len) @@ -1998,7 +1998,7 @@ bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *s { SEMA_ERROR(ret_expr, "Expected %s, not %s.", type_quoted_error_string(rtype), type_quoted_error_string(type)); - return SCOPE_POP_ERROR(); + goto EXIT_FAIL; } if (may_be_optional) ret_expr->type = type_add_optional(ret_expr->type, may_be_optional); } @@ -2007,7 +2007,7 @@ bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *s else { Type *sum_returns = context_unify_returns(¯o_context); - if (!sum_returns) return SCOPE_POP_ERROR(); + if (!sum_returns) goto EXIT_FAIL; call_expr->type = type_add_optional(sum_returns, optional); } @@ -2020,12 +2020,12 @@ bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *s if (decl->func_decl.signature.attrs.nodiscard) { SEMA_ERROR(call_expr, "The result of the macro must be used."); - return SCOPE_POP_ERROR(); + goto EXIT_FAIL; } if (type_is_optional(type) && !decl->func_decl.signature.attrs.maydiscard) { SEMA_ERROR(call_expr, "The optional result of the macro must be used."); - return SCOPE_POP_ERROR(); + goto EXIT_FAIL; } } } @@ -2057,8 +2057,10 @@ EXIT: assert(context->active_scope.defer_last == context->active_scope.defer_start); context->active_scope = old_scope; if (is_no_return) context->active_scope.jump_end = true; + sema_context_destroy(¯o_context); return true; EXIT_FAIL: + sema_context_destroy(¯o_context); return SCOPE_POP_ERROR(); } diff --git a/src/compiler/semantic_analyser.c b/src/compiler/semantic_analyser.c index b24e90f2e..d11ac5488 100644 --- a/src/compiler/semantic_analyser.c +++ b/src/compiler/semantic_analyser.c @@ -332,7 +332,7 @@ void sema_analysis_run(void) global_context.locals_list = NULL; // Set a maximum of symbols in the std_module and test module - htable_init(&global_context.std_module.symbols, 0x10000); + htable_init(&global_context.std_module.symbols, 0x1000); // Setup the func prototype hash map type_func_prototype_init(0x10000); diff --git a/src/utils/malloc.c b/src/utils/malloc.c index 11ccbd459..04e30d2f0 100644 --- a/src/utils/malloc.c +++ b/src/utils/malloc.c @@ -16,7 +16,7 @@ static Vmem char_arena; void memory_init(void) { - vmem_init(&arena, 512); + vmem_init(&arena, 2048); vmem_init(&char_arena, 512); allocations_done = 0; arena_zero = (uintptr_t)arena.ptr; diff --git a/src/version.h b/src/version.h index ca688fa15..ae0286f76 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "0.4.540" \ No newline at end of file +#define COMPILER_VERSION "0.4.541" \ No newline at end of file diff --git a/test/unit/stdlib/collections/range.c3 b/test/unit/stdlib/collections/range.c3 new file mode 100644 index 000000000..4d6487ca4 --- /dev/null +++ b/test/unit/stdlib/collections/range.c3 @@ -0,0 +1,15 @@ +module range_test @test; +import std::collections::range; + +def IntRange = Range; +fn void! test_range() +{ + IntRange range = { -4, 2 }; + int sum = 0; + foreach (int z : range) + { + assert(z >= -4 && z < 2); + sum += z * z; + } + assert(sum == 31); +} \ No newline at end of file