diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index 584bebc4d..406838f28 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -151,6 +151,38 @@ static void analyze_to_stage(AnalysisStage stage) halt_on_error(); } +static void add_global_define(const char *name, Expr *value) +{ + Decl *dec = decl_calloc(); + TokenType type = TOKEN_CONST_IDENT; + const char *unique_name = symtab_add(name, strlen(name), fnv1a(name, strlen(name)), &type); + dec->name = unique_name; + dec->module = &global_context.std_module; + dec->visibility = VISIBLE_PUBLIC; + dec->decl_kind = DECL_VAR; + dec->var.kind = VARDECL_CONST; + dec->var.constant = true; + dec->var.type_info = NULL; + dec->var.init_expr = value; + dec->type = value->type; + dec->resolve_status = RESOLVE_DONE; + decl_set_external_name(dec); + compiler_register_public_symbol(dec); + stable_set(&dec->module->public_symbols, dec->name, dec); + stable_set(&dec->module->symbols, dec->name, dec); +} + +static void add_global_define_int(const char *name, uint64_t int_value) +{ + Expr *value = expr_new(EXPR_CONST, INVALID_RANGE); + value->const_expr.kind = TYPE_IXX; + value->original_type = type_compint; + expr_const_set_int(&value->const_expr, int_value, TYPE_IXX); + value->type = type_compint; + value->resolve_status = RESOLVE_DONE; + add_global_define(name, value); +} + void compiler_compile(void) { Context **contexts = NULL; @@ -175,6 +207,12 @@ void compiler_compile(void) vec_add(contexts, context); if (!parse_file(context)) continue; } + + global_context.std_module_path = (Path) { .module = kw_std, .span = INVALID_RANGE, .len = strlen(kw_std) }; + global_context.std_module = (Module){ .name = &global_context.std_module_path }; + global_context.std_module.stage = ANALYSIS_LAST; + stable_init(&global_context.std_module.symbols, 0x10000); + unsigned source_count = vec_size(contexts); if (!source_count) { diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 6cbeb4f55..45e3a5f2f 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -1307,6 +1307,8 @@ typedef struct Decl* locals[MAX_LOCALS]; DynamicScope scopes[MAX_SCOPE_DEPTH]; STable scratch_table; + Module std_module; + Path std_module_path; } GlobalContext; @@ -1413,6 +1415,7 @@ extern Type *type_virtual, *type_virtual_generic; extern const char *attribute_list[NUMBER_OF_ATTRIBUTES]; +extern const char *kw_std; extern const char *kw_align; extern const char *kw_alignof; extern const char *kw_distinct; diff --git a/src/compiler/sema_name_resolution.c b/src/compiler/sema_name_resolution.c index fcceac3a1..43eb5ca5f 100644 --- a/src/compiler/sema_name_resolution.c +++ b/src/compiler/sema_name_resolution.c @@ -34,12 +34,19 @@ static Decl *sema_resolve_path_symbol(Context *context, const char *symbol, Path Decl *decl = NULL; bool path_found = false; + // 0. std module special handling. + if (path->module == global_context.std_module_path.module) + { + return module_find_symbol(&global_context.std_module, symbol); + } + // 1. Do we match our own path? if (matches_subpath(context->module->name, path)) { // 2. If so just get the symbol. return module_find_symbol(context->module, symbol); } + // 3. Loop over imports. VECEACH(context->imports, i) { diff --git a/src/compiler/sema_passes.c b/src/compiler/sema_passes.c index 1c68045af..e9f0d9228 100644 --- a/src/compiler/sema_passes.c +++ b/src/compiler/sema_passes.c @@ -29,6 +29,7 @@ void sema_analysis_pass_process_imports(Module *module) // 2. Loop through imports unsigned imports = vec_size(context->imports); + for (unsigned i = 0; i < imports; i++) { // 3. Begin analysis diff --git a/src/compiler/symtab.c b/src/compiler/symtab.c index be4430cb5..367b20007 100644 --- a/src/compiler/symtab.c +++ b/src/compiler/symtab.c @@ -36,6 +36,7 @@ static SymTab symtab; const char *attribute_list[NUMBER_OF_ATTRIBUTES]; +const char *kw_std; const char *kw_align; const char *kw_alignof; const char *kw_distinct; @@ -113,6 +114,7 @@ void symtab_init(uint32_t capacity) kw___round = KW_DEF("__round"); kw___sqrt = KW_DEF("__sqrt"); kw___trunc = KW_DEF("__trunc"); + kw_std = KW_DEF("std"); attribute_list[ATTRIBUTE_INLINE] = kw_inline; attribute_list[ATTRIBUTE_NOINLINE] = KW_DEF("noinline");