mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-03 14:18:47 +00:00
Allow importation of core:builtin to get built-in entities
This commit is contained in:
+8
-12
@@ -640,7 +640,7 @@ void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_var_decl(CheckerContext *ctx, Entity *e, Entity **entities, isize entity_count, Ast *type_expr, Array<Ast *> const &init_expr_list) {
|
void check_var_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init_expr) {
|
||||||
GB_ASSERT(e->type == nullptr);
|
GB_ASSERT(e->type == nullptr);
|
||||||
GB_ASSERT(e->kind == Entity_Variable);
|
GB_ASSERT(e->kind == Entity_Variable);
|
||||||
|
|
||||||
@@ -651,7 +651,7 @@ void check_var_decl(CheckerContext *ctx, Entity *e, Entity **entities, isize ent
|
|||||||
e->flags |= EntityFlag_Visited;
|
e->flags |= EntityFlag_Visited;
|
||||||
|
|
||||||
AttributeContext ac = make_attribute_context(e->Variable.link_prefix);
|
AttributeContext ac = make_attribute_context(e->Variable.link_prefix);
|
||||||
ac.init_expr_list_count = init_expr_list.count;
|
ac.init_expr_list_count = init_expr != nullptr ? 1 : 0;
|
||||||
|
|
||||||
DeclInfo *decl = decl_info_of_entity(e);
|
DeclInfo *decl = decl_info_of_entity(e);
|
||||||
if (decl != nullptr) {
|
if (decl != nullptr) {
|
||||||
@@ -682,7 +682,7 @@ void check_var_decl(CheckerContext *ctx, Entity *e, Entity **entities, isize ent
|
|||||||
|
|
||||||
|
|
||||||
if (e->Variable.is_foreign) {
|
if (e->Variable.is_foreign) {
|
||||||
if (init_expr_list.count > 0) {
|
if (init_expr != nullptr) {
|
||||||
error(e->token, "A foreign variable declaration cannot have a default value");
|
error(e->token, "A foreign variable declaration cannot have a default value");
|
||||||
}
|
}
|
||||||
init_entity_foreign_library(ctx, e);
|
init_entity_foreign_library(ctx, e);
|
||||||
@@ -716,20 +716,16 @@ void check_var_decl(CheckerContext *ctx, Entity *e, Entity **entities, isize ent
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (init_expr_list.count == 0) {
|
if (init_expr == nullptr) {
|
||||||
if (type_expr == nullptr) {
|
if (type_expr == nullptr) {
|
||||||
e->type = t_invalid;
|
e->type = t_invalid;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type_expr != nullptr) {
|
Operand o = {};
|
||||||
for (isize i = 0; i < entity_count; i++) {
|
check_expr(ctx, &o, init_expr);
|
||||||
entities[i]->type = e->type;
|
check_init_variable(ctx, e, &o, str_lit("variable declaration"));
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
check_init_variables(ctx, entities, entity_count, init_expr_list, context_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_proc_group_decl(CheckerContext *ctx, Entity *pg_entity, DeclInfo *d) {
|
void check_proc_group_decl(CheckerContext *ctx, Entity *pg_entity, DeclInfo *d) {
|
||||||
@@ -895,7 +891,7 @@ void check_entity_decl(CheckerContext *ctx, Entity *e, DeclInfo *d, Type *named_
|
|||||||
|
|
||||||
switch (e->kind) {
|
switch (e->kind) {
|
||||||
case Entity_Variable:
|
case Entity_Variable:
|
||||||
check_var_decl(&c, e, d->entities, d->entity_count, d->type_expr, d->init_expr_list);
|
check_var_decl(&c, e, d->type_expr, d->init_expr);
|
||||||
break;
|
break;
|
||||||
case Entity_Constant:
|
case Entity_Constant:
|
||||||
check_const_decl(&c, e, d->type_expr, d->init_expr, named_type);
|
check_const_decl(&c, e, d->type_expr, d->init_expr, named_type);
|
||||||
|
|||||||
+5
-3
@@ -44,7 +44,6 @@ int valid_index_and_score_cmp(void const *a, void const *b) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define CALL_ARGUMENT_CHECKER(name) CallArgumentError name(CheckerContext *c, Ast *call, Type *proc_type, Entity *entity, Array<Operand> operands, CallArgumentErrorMode show_error_mode, CallArgumentData *data)
|
#define CALL_ARGUMENT_CHECKER(name) CallArgumentError name(CheckerContext *c, Ast *call, Type *proc_type, Entity *entity, Array<Operand> operands, CallArgumentErrorMode show_error_mode, CallArgumentData *data)
|
||||||
typedef CALL_ARGUMENT_CHECKER(CallArgumentCheckerType);
|
typedef CALL_ARGUMENT_CHECKER(CallArgumentCheckerType);
|
||||||
|
|
||||||
@@ -5206,6 +5205,10 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
|
|||||||
|
|
||||||
|
|
||||||
case_ast_node(bl, BasicLit, node);
|
case_ast_node(bl, BasicLit, node);
|
||||||
|
// NOTE(bill, 2018-06-17): Placing this in the parser is slower than
|
||||||
|
// placing it here for some reason. So don't move it to the parsing
|
||||||
|
// stage if you _think_ it will be faster, only do it if you _know_ it
|
||||||
|
// will be faster.
|
||||||
Type *t = t_invalid;
|
Type *t = t_invalid;
|
||||||
switch (bl->token.kind) {
|
switch (bl->token.kind) {
|
||||||
case Token_Integer: t = t_untyped_integer; break;
|
case Token_Integer: t = t_untyped_integer; break;
|
||||||
@@ -5231,6 +5234,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
|
|||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
case_ast_node(bd, BasicDirective, node);
|
case_ast_node(bd, BasicDirective, node);
|
||||||
|
o->mode = Addressing_Constant;
|
||||||
if (bd->name == "file") {
|
if (bd->name == "file") {
|
||||||
o->type = t_untyped_string;
|
o->type = t_untyped_string;
|
||||||
o->value = exact_value_string(bd->token.pos.file);
|
o->value = exact_value_string(bd->token.pos.file);
|
||||||
@@ -5254,7 +5258,6 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
|
|||||||
} else {
|
} else {
|
||||||
GB_PANIC("Unknown basic directive");
|
GB_PANIC("Unknown basic directive");
|
||||||
}
|
}
|
||||||
o->mode = Addressing_Constant;
|
|
||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
case_ast_node(pg, ProcGroup, node);
|
case_ast_node(pg, ProcGroup, node);
|
||||||
@@ -5296,7 +5299,6 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
|
|||||||
}
|
}
|
||||||
check_close_scope(&ctx);
|
check_close_scope(&ctx);
|
||||||
|
|
||||||
|
|
||||||
o->mode = Addressing_Value;
|
o->mode = Addressing_Value;
|
||||||
o->type = type;
|
o->type = type;
|
||||||
case_end;
|
case_end;
|
||||||
|
|||||||
+44
-60
@@ -25,6 +25,7 @@ bool is_operand_undef(Operand o) {
|
|||||||
|
|
||||||
|
|
||||||
gb_global Scope *universal_scope = nullptr;
|
gb_global Scope *universal_scope = nullptr;
|
||||||
|
gb_global AstPackage *builtin_package = nullptr;
|
||||||
|
|
||||||
void scope_reset(Scope *scope) {
|
void scope_reset(Scope *scope) {
|
||||||
if (scope == nullptr) return;
|
if (scope == nullptr) return;
|
||||||
@@ -531,13 +532,22 @@ void add_global_type_entity(String name, Type *type) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void init_universal_scope(void) {
|
void init_universal(void) {
|
||||||
BuildContext *bc = &build_context;
|
BuildContext *bc = &build_context;
|
||||||
// NOTE(bill): No need to free these
|
// NOTE(bill): No need to free these
|
||||||
gbAllocator a = heap_allocator();
|
gbAllocator a = heap_allocator();
|
||||||
universal_scope = create_scope(nullptr, a);
|
universal_scope = create_scope(nullptr, a);
|
||||||
universal_scope->is_package = true;
|
universal_scope->is_package = true;
|
||||||
|
|
||||||
|
|
||||||
|
builtin_package = gb_alloc_item(a, AstPackage);
|
||||||
|
builtin_package->name = str_lit("builtin");
|
||||||
|
builtin_package->kind = Package_Normal;
|
||||||
|
builtin_package->scope = universal_scope;
|
||||||
|
universal_scope->package = builtin_package;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
for (isize i = 0; i < gb_count_of(basic_types); i++) {
|
for (isize i = 0; i < gb_count_of(basic_types); i++) {
|
||||||
add_global_type_entity(basic_types[i].Basic.name, &basic_types[i]);
|
add_global_type_entity(basic_types[i].Basic.name, &basic_types[i]);
|
||||||
@@ -2009,19 +2019,6 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE(bill): You need to store the entity information here unline a constant declaration
|
|
||||||
isize entity_cap = vd->names.count;
|
|
||||||
isize entity_count = 0;
|
|
||||||
Entity **entities = gb_alloc_array(c->allocator, Entity *, entity_cap);
|
|
||||||
DeclInfo *di = nullptr;
|
|
||||||
if (vd->values.count > 0) {
|
|
||||||
di = make_decl_info(heap_allocator(), c->scope, c->decl);
|
|
||||||
di->entities = entities;
|
|
||||||
di->type_expr = vd->type;
|
|
||||||
di->init_expr = vd->values[0];
|
|
||||||
di->init_expr_list = vd->values;
|
|
||||||
}
|
|
||||||
|
|
||||||
for_array(i, vd->names) {
|
for_array(i, vd->names) {
|
||||||
Ast *name = vd->names[i];
|
Ast *name = vd->names[i];
|
||||||
Ast *value = nullptr;
|
Ast *value = nullptr;
|
||||||
@@ -2052,24 +2049,15 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) {
|
|||||||
e->Variable.is_export = true;
|
e->Variable.is_export = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
entities[entity_count++] = e;
|
Ast *init_expr = value;
|
||||||
|
DeclInfo *d = make_decl_info(heap_allocator(), c->scope, c->decl);
|
||||||
DeclInfo *d = di;
|
d->type_expr = vd->type;
|
||||||
if (d == nullptr || i > 0) {
|
d->init_expr = init_expr;
|
||||||
Ast *init_expr = value;
|
|
||||||
d = make_decl_info(heap_allocator(), e->scope, c->decl);
|
|
||||||
d->type_expr = vd->type;
|
|
||||||
d->init_expr = init_expr;
|
|
||||||
}
|
|
||||||
d->attributes = vd->attributes;
|
d->attributes = vd->attributes;
|
||||||
|
|
||||||
add_entity_and_decl_info(c, name, e, d);
|
add_entity_and_decl_info(c, name, e, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (di != nullptr) {
|
|
||||||
di->entity_count = entity_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
check_arity_match(c, vd, true);
|
check_arity_match(c, vd, true);
|
||||||
} else {
|
} else {
|
||||||
for_array(i, vd->names) {
|
for_array(i, vd->names) {
|
||||||
@@ -2380,6 +2368,9 @@ void add_import_dependency_node(Checker *c, Ast *decl, Map<ImportGraphNode *> *M
|
|||||||
switch (decl->kind) {
|
switch (decl->kind) {
|
||||||
case_ast_node(id, ImportDecl, decl);
|
case_ast_node(id, ImportDecl, decl);
|
||||||
String path = id->fullpath;
|
String path = id->fullpath;
|
||||||
|
if (path == "builtin") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
HashKey key = hash_string(path);
|
HashKey key = hash_string(path);
|
||||||
AstPackage **found = map_get(&c->info.packages, key);
|
AstPackage **found = map_get(&c->info.packages, key);
|
||||||
if (found == nullptr) {
|
if (found == nullptr) {
|
||||||
@@ -2538,32 +2529,35 @@ void check_add_import_decl(CheckerContext *ctx, Ast *decl) {
|
|||||||
decl->been_handled = true;
|
decl->been_handled = true;
|
||||||
|
|
||||||
ast_node(id, ImportDecl, decl);
|
ast_node(id, ImportDecl, decl);
|
||||||
|
Token token = id->relpath;
|
||||||
|
|
||||||
Scope *parent_scope = ctx->scope;
|
Scope *parent_scope = ctx->scope;
|
||||||
GB_ASSERT(parent_scope->is_file);
|
GB_ASSERT(parent_scope->is_file);
|
||||||
|
|
||||||
auto *pkgs = &ctx->checker->info.packages;
|
auto *pkgs = &ctx->checker->info.packages;
|
||||||
|
|
||||||
Token token = id->relpath;
|
Scope *scope = nullptr;
|
||||||
HashKey key = hash_string(id->fullpath);
|
|
||||||
AstPackage **found = map_get(pkgs, key);
|
if (id->fullpath == "builtin") {
|
||||||
if (found == nullptr) {
|
scope = universal_scope;
|
||||||
for_array(pkg_index, pkgs->entries) {
|
} else {
|
||||||
AstPackage *pkg = pkgs->entries[pkg_index].value;
|
HashKey key = hash_string(id->fullpath);
|
||||||
gb_printf_err("%.*s\n", LIT(pkg->fullpath));
|
AstPackage **found = map_get(pkgs, key);
|
||||||
|
if (found == nullptr) {
|
||||||
|
for_array(pkg_index, pkgs->entries) {
|
||||||
|
AstPackage *pkg = pkgs->entries[pkg_index].value;
|
||||||
|
gb_printf_err("%.*s\n", LIT(pkg->fullpath));
|
||||||
|
}
|
||||||
|
gb_printf_err("%.*s(%td:%td)\n", LIT(token.pos.file), token.pos.line, token.pos.column);
|
||||||
|
GB_PANIC("Unable to find scope for package: %.*s", LIT(id->fullpath));
|
||||||
|
} else {
|
||||||
|
AstPackage *pkg = *found;
|
||||||
|
ptr_set_add(&ctx->checker->checked_packages, pkg);
|
||||||
|
scope = pkg->scope;
|
||||||
}
|
}
|
||||||
gb_printf_err("%.*s(%td:%td)\n", LIT(token.pos.file), token.pos.line, token.pos.column);
|
|
||||||
GB_PANIC("Unable to find scope for package: %.*s", LIT(id->fullpath));
|
|
||||||
}
|
}
|
||||||
AstPackage *pkg = *found;
|
|
||||||
Scope *scope = pkg->scope;
|
|
||||||
GB_ASSERT(scope->is_package);
|
GB_ASSERT(scope->is_package);
|
||||||
|
|
||||||
// TODO(bill): Should this be allowed or not?
|
|
||||||
// if (scope->is_global) {
|
|
||||||
// error(token, "Importing a runtime package is disallowed and unnecessary");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (ptr_set_exists(&parent_scope->imported, scope)) {
|
if (ptr_set_exists(&parent_scope->imported, scope)) {
|
||||||
// error(token, "Multiple import of the same file within this scope");
|
// error(token, "Multiple import of the same file within this scope");
|
||||||
@@ -2615,7 +2609,6 @@ void check_add_import_decl(CheckerContext *ctx, Ast *decl) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr_set_add(&ctx->checker->checked_packages, pkg);
|
|
||||||
scope->has_been_imported = true;
|
scope->has_been_imported = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3093,11 +3086,7 @@ void calculate_global_init_order(Checker *c) {
|
|||||||
}
|
}
|
||||||
ptr_set_add(&emitted, d);
|
ptr_set_add(&emitted, d);
|
||||||
|
|
||||||
if (d->entities == nullptr) {
|
d->entity = e;
|
||||||
d->entities = gb_alloc_array(c->allocator, Entity *, 1);
|
|
||||||
d->entities[0] = e;
|
|
||||||
d->entity_count = 1;
|
|
||||||
}
|
|
||||||
array_add(&info->variable_init_order, d);
|
array_add(&info->variable_init_order, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3105,13 +3094,8 @@ void calculate_global_init_order(Checker *c) {
|
|||||||
gb_printf("Variable Initialization Order:\n");
|
gb_printf("Variable Initialization Order:\n");
|
||||||
for_array(i, info->variable_init_order) {
|
for_array(i, info->variable_init_order) {
|
||||||
DeclInfo *d = info->variable_init_order[i];
|
DeclInfo *d = info->variable_init_order[i];
|
||||||
for (isize j = 0; j < d->entity_count; j++) {
|
Entity *e = d->entity;
|
||||||
Entity *e = d->entities[j];
|
gb_printf("\t'%.*s' %td\n", LIT(e->token.string), e->order_in_src);
|
||||||
if (j == 0) gb_printf("\t");
|
|
||||||
if (j > 0) gb_printf(", ");
|
|
||||||
gb_printf("'%.*s' %td", LIT(e->token.string), e->order_in_src);
|
|
||||||
}
|
|
||||||
gb_printf("\n");
|
|
||||||
}
|
}
|
||||||
gb_printf("\n");
|
gb_printf("\n");
|
||||||
}
|
}
|
||||||
@@ -3200,15 +3184,15 @@ void check_parsed_files(Checker *c) {
|
|||||||
TIME_SECTION("collect entities");
|
TIME_SECTION("collect entities");
|
||||||
// Collect Entities
|
// Collect Entities
|
||||||
for_array(i, c->parser->packages) {
|
for_array(i, c->parser->packages) {
|
||||||
AstPackage *p = c->parser->packages[i];
|
AstPackage *pkg = c->parser->packages[i];
|
||||||
|
|
||||||
CheckerContext ctx = make_checker_context(c);
|
CheckerContext ctx = make_checker_context(c);
|
||||||
defer (destroy_checker_context(&ctx));
|
defer (destroy_checker_context(&ctx));
|
||||||
ctx.pkg = p;
|
ctx.pkg = pkg;
|
||||||
ctx.collect_delayed_decls = false;
|
ctx.collect_delayed_decls = false;
|
||||||
|
|
||||||
for_array(j, p->files) {
|
for_array(j, pkg->files) {
|
||||||
AstFile *f = p->files[j];
|
AstFile *f = pkg->files[j];
|
||||||
create_scope_from_file(&ctx, f);
|
create_scope_from_file(&ctx, f);
|
||||||
HashKey key = hash_string(f->fullpath);
|
HashKey key = hash_string(f->fullpath);
|
||||||
map_set(&c->info.files, key, f);
|
map_set(&c->info.files, key, f);
|
||||||
|
|||||||
+9
-9
@@ -180,18 +180,17 @@ void check_decl_attributes(CheckerContext *c, Array<Ast *> const &attributes, De
|
|||||||
|
|
||||||
// DeclInfo is used to store information of certain declarations to allow for "any order" usage
|
// DeclInfo is used to store information of certain declarations to allow for "any order" usage
|
||||||
struct DeclInfo {
|
struct DeclInfo {
|
||||||
DeclInfo * parent; // NOTE(bill): only used for procedure literals at the moment
|
DeclInfo * parent; // NOTE(bill): only used for procedure literals at the moment
|
||||||
Scope * scope;
|
Scope * scope;
|
||||||
|
|
||||||
Entity ** entities;
|
Entity *entity;
|
||||||
isize entity_count;
|
|
||||||
|
|
||||||
Ast * type_expr;
|
Ast * type_expr;
|
||||||
Ast * init_expr;
|
Ast * init_expr;
|
||||||
Array<Ast *> init_expr_list;
|
// Array<Ast *> init_expr_list;
|
||||||
Array<Ast *> attributes;
|
Array<Ast *> attributes;
|
||||||
Ast * proc_lit; // Ast_ProcLit
|
Ast * proc_lit; // Ast_ProcLit
|
||||||
Type * gen_proc_type; // Precalculated
|
Type * gen_proc_type; // Precalculated
|
||||||
|
|
||||||
PtrSet<Entity *> deps;
|
PtrSet<Entity *> deps;
|
||||||
PtrSet<Type *> type_info_deps;
|
PtrSet<Type *> type_info_deps;
|
||||||
@@ -204,16 +203,16 @@ struct ProcInfo {
|
|||||||
Token token;
|
Token token;
|
||||||
DeclInfo *decl;
|
DeclInfo *decl;
|
||||||
Type * type; // Type_Procedure
|
Type * type; // Type_Procedure
|
||||||
Ast * body; // Ast_BlockStmt
|
Ast * body; // Ast_BlockStmt
|
||||||
u64 tags;
|
u64 tags;
|
||||||
bool generated_from_polymorphic;
|
bool generated_from_polymorphic;
|
||||||
Ast * poly_def_node;
|
Ast * poly_def_node;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct Scope {
|
struct Scope {
|
||||||
Ast * node;
|
Ast * node;
|
||||||
Scope * parent;
|
Scope * parent;
|
||||||
Scope * prev, *next;
|
Scope * prev, *next;
|
||||||
Scope * first_child;
|
Scope * first_child;
|
||||||
@@ -298,6 +297,7 @@ struct CheckerInfo {
|
|||||||
Map<isize> type_info_map; // Key: Type *
|
Map<isize> type_info_map; // Key: Type *
|
||||||
|
|
||||||
|
|
||||||
|
AstPackage * builtin_package;
|
||||||
AstPackage * runtime_package;
|
AstPackage * runtime_package;
|
||||||
Scope * init_scope;
|
Scope * init_scope;
|
||||||
Entity * entry_point;
|
Entity * entry_point;
|
||||||
|
|||||||
+41
-43
@@ -4188,8 +4188,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, Ast *expr, TypeAndValue tv, Bu
|
|||||||
Entity *e = entity_of_ident(ident);
|
Entity *e = entity_of_ident(ident);
|
||||||
GB_ASSERT(e != nullptr);
|
GB_ASSERT(e != nullptr);
|
||||||
|
|
||||||
if (e->parent_proc_decl != nullptr && e->parent_proc_decl->entity_count > 0) {
|
if (e->parent_proc_decl != nullptr && e->parent_proc_decl->entity != nullptr) {
|
||||||
procedure = e->parent_proc_decl->entities[0]->token.string;
|
procedure = e->parent_proc_decl->entity->token.string;
|
||||||
} else {
|
} else {
|
||||||
procedure = str_lit("");
|
procedure = str_lit("");
|
||||||
}
|
}
|
||||||
@@ -8343,57 +8343,55 @@ void ir_gen_tree(irGen *s) {
|
|||||||
for_array(i, info->variable_init_order) {
|
for_array(i, info->variable_init_order) {
|
||||||
DeclInfo *d = info->variable_init_order[i];
|
DeclInfo *d = info->variable_init_order[i];
|
||||||
|
|
||||||
for (isize j = 0; j < d->entity_count; j++) {
|
Entity *e = d->entity;
|
||||||
Entity *e = d->entities[j];
|
|
||||||
|
|
||||||
if (!e->scope->is_file) {
|
if (!e->scope->is_file) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ir_min_dep_entity(m, e)) {
|
if (!ir_min_dep_entity(m, e)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
DeclInfo *decl = decl_info_of_entity(e);
|
DeclInfo *decl = decl_info_of_entity(e);
|
||||||
if (decl == nullptr) {
|
if (decl == nullptr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
GB_ASSERT(e->kind == Entity_Variable);
|
GB_ASSERT(e->kind == Entity_Variable);
|
||||||
|
|
||||||
bool is_foreign = e->Variable.is_foreign;
|
bool is_foreign = e->Variable.is_foreign;
|
||||||
bool is_export = e->Variable.is_export;
|
bool is_export = e->Variable.is_export;
|
||||||
bool no_name_mangle = e->Variable.link_name.len > 0 || is_foreign || is_export;
|
bool no_name_mangle = e->Variable.link_name.len > 0 || is_foreign || is_export;
|
||||||
|
|
||||||
String name = e->token.string;
|
String name = e->token.string;
|
||||||
if (!no_name_mangle) {
|
if (!no_name_mangle) {
|
||||||
name = ir_mangle_name(s, e);
|
name = ir_mangle_name(s, e);
|
||||||
}
|
}
|
||||||
ir_add_entity_name(m, e, name);
|
ir_add_entity_name(m, e, name);
|
||||||
|
|
||||||
irValue *g = ir_value_global(a, e, nullptr);
|
irValue *g = ir_value_global(a, e, nullptr);
|
||||||
g->Global.name = name;
|
g->Global.name = name;
|
||||||
g->Global.thread_local_model = e->Variable.thread_local_model;
|
g->Global.thread_local_model = e->Variable.thread_local_model;
|
||||||
g->Global.is_foreign = is_foreign;
|
g->Global.is_foreign = is_foreign;
|
||||||
g->Global.is_export = is_export;
|
g->Global.is_export = is_export;
|
||||||
|
|
||||||
irGlobalVariable var = {};
|
irGlobalVariable var = {};
|
||||||
var.var = g;
|
var.var = g;
|
||||||
var.decl = decl;
|
var.decl = decl;
|
||||||
|
|
||||||
if (decl->init_expr != nullptr && !is_type_any(e->type)) {
|
if (decl->init_expr != nullptr && !is_type_any(e->type)) {
|
||||||
TypeAndValue tav = type_and_value_of_expr(decl->init_expr);
|
TypeAndValue tav = type_and_value_of_expr(decl->init_expr);
|
||||||
if (tav.mode != Addressing_Invalid) {
|
if (tav.mode != Addressing_Invalid) {
|
||||||
if (tav.value.kind != ExactValue_Invalid) {
|
if (tav.value.kind != ExactValue_Invalid) {
|
||||||
ExactValue v = tav.value;
|
ExactValue v = tav.value;
|
||||||
g->Global.value = ir_add_module_constant(m, tav.type, v);
|
g->Global.value = ir_add_module_constant(m, tav.type, v);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
array_add(&global_variables, var);
|
|
||||||
|
|
||||||
ir_module_add_value(m, e, g);
|
|
||||||
map_set(&m->members, hash_string(name), g);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
array_add(&global_variables, var);
|
||||||
|
|
||||||
|
ir_module_add_value(m, e, g);
|
||||||
|
map_set(&m->members, hash_string(name), g);
|
||||||
}
|
}
|
||||||
|
|
||||||
for_array(i, info->entities) {
|
for_array(i, info->entities) {
|
||||||
|
|||||||
+1
-1
@@ -791,7 +791,7 @@ int main(int arg_count, char **arg_ptr) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
init_universal_scope();
|
init_universal();
|
||||||
// TODO(bill): prevent compiling without a linker
|
// TODO(bill): prevent compiling without a linker
|
||||||
|
|
||||||
timings_start_section(&timings, str_lit("parse files"));
|
timings_start_section(&timings, str_lit("parse files"));
|
||||||
|
|||||||
+20
-4
@@ -2446,7 +2446,7 @@ Ast *parse_value_decl(AstFile *f, Array<Ast *> names, CommentGroup *docs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (values.data == nullptr) {
|
if (values.data == nullptr) {
|
||||||
values = array_make<Ast *>(heap_allocator());
|
values.allocator = heap_allocator();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f->expr_level >= 0) {
|
if (f->expr_level >= 0) {
|
||||||
@@ -2462,6 +2462,12 @@ Ast *parse_value_decl(AstFile *f, Array<Ast *> names, CommentGroup *docs) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (f->curr_proc == nullptr) {
|
||||||
|
if (values.count > 0 && names.count != values.count) {
|
||||||
|
syntax_error(values[0], "Expected %td expressions on the right hand side, got %td", names.count, values.count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ast_value_decl(f, names, type, values, is_mutable, docs, f->line_comment);
|
return ast_value_decl(f, names, type, values, is_mutable, docs, f->line_comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4094,8 +4100,13 @@ bool determine_path_from_string(Parser *p, Ast *node, String base_dir, String or
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
String fullpath = string_trim_whitespace(get_fullpath_relative(a, base_dir, file_str));
|
|
||||||
*path = fullpath;
|
if (file_str == "builtin") {
|
||||||
|
*path = str_lit("builtin");
|
||||||
|
} else {
|
||||||
|
String fullpath = string_trim_whitespace(get_fullpath_relative(a, base_dir, file_str));
|
||||||
|
*path = fullpath;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -4155,6 +4166,9 @@ void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, Array<Ast *>
|
|||||||
import_path = string_trim_whitespace(import_path);
|
import_path = string_trim_whitespace(import_path);
|
||||||
|
|
||||||
id->fullpath = import_path;
|
id->fullpath = import_path;
|
||||||
|
if (import_path == "builtin") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
try_add_import_path(p, import_path, original_string, ast_token(node).pos);
|
try_add_import_path(p, import_path, original_string, ast_token(node).pos);
|
||||||
} else if (node->kind == Ast_ForeignImportDecl) {
|
} else if (node->kind == Ast_ForeignImportDecl) {
|
||||||
ast_node(fl, ForeignImportDecl, node);
|
ast_node(fl, ForeignImportDecl, node);
|
||||||
@@ -4284,6 +4298,8 @@ bool parse_file(Parser *p, AstFile *f) {
|
|||||||
error(package_name, "Invalid package name '_'");
|
error(package_name, "Invalid package name '_'");
|
||||||
} else if (f->pkg->kind != Package_Runtime && package_name.string == "runtime") {
|
} else if (f->pkg->kind != Package_Runtime && package_name.string == "runtime") {
|
||||||
error(package_name, "Use of reserved package name '%.*s'", LIT(package_name.string));
|
error(package_name, "Use of reserved package name '%.*s'", LIT(package_name.string));
|
||||||
|
} else if (package_name.string == "builtin") {
|
||||||
|
error(package_name, "Use of reserved package name '%.*s'", LIT(package_name.string));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f->package_name = package_name.string;
|
f->package_name = package_name.string;
|
||||||
@@ -4418,8 +4434,8 @@ ParseFileError parse_packages(Parser *p, String init_filename) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TokenPos init_pos = {};
|
|
||||||
|
|
||||||
|
TokenPos init_pos = {};
|
||||||
if (!build_context.generate_docs) {
|
if (!build_context.generate_docs) {
|
||||||
String s = get_fullpath_core(heap_allocator(), str_lit("runtime"));
|
String s = get_fullpath_core(heap_allocator(), str_lit("runtime"));
|
||||||
try_add_import_path(p, s, s, init_pos, Package_Runtime);
|
try_add_import_path(p, s, s, init_pos, Package_Runtime);
|
||||||
|
|||||||
@@ -573,3 +573,4 @@ gbAllocator ast_allocator(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ast *alloc_ast_node(AstFile *f, AstKind kind);
|
Ast *alloc_ast_node(AstFile *f, AstKind kind);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user