mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-08 16:48:18 +00:00
Fix preload initialization ordering
This commit is contained in:
@@ -16,7 +16,7 @@ if %release_mode% EQU 0 ( rem Debug
|
|||||||
)
|
)
|
||||||
|
|
||||||
set compiler_warnings= ^
|
set compiler_warnings= ^
|
||||||
-we4013 -we4706 -we4002 -we4133 -we4047 -we4024 ^
|
-we4002 -we4013 -we4024 -we4047 -we4133 -we4706 ^
|
||||||
-wd4100 -wd4101 -wd4127 -wd4189 ^
|
-wd4100 -wd4101 -wd4127 -wd4189 ^
|
||||||
-wd4201 -wd4204 -wd4244 ^
|
-wd4201 -wd4204 -wd4244 ^
|
||||||
-wd4306 ^
|
-wd4306 ^
|
||||||
|
|||||||
+5
-2
@@ -1,6 +1,9 @@
|
|||||||
#import "game.odin";
|
// #import "game.odin";
|
||||||
|
#import "fmt.odin";
|
||||||
|
|
||||||
|
x := type_info(int);
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
game.run();
|
fmt.println(123);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-1
@@ -4,10 +4,16 @@
|
|||||||
#import "fmt.odin";
|
#import "fmt.odin";
|
||||||
#import "mem.odin";
|
#import "mem.odin";
|
||||||
|
|
||||||
|
// IMPORTANT NOTE(bill): `type_info` & `type_info_val` cannot be used within a
|
||||||
|
// #shared_global_scope due to the internals of the compiler.
|
||||||
|
// This could change at a later date if the all these data structures are
|
||||||
|
// implemented within the compiler rather than in this "preload" file
|
||||||
|
|
||||||
|
|
||||||
// IMPORTANT NOTE(bill): Do not change the order of any of this data
|
// IMPORTANT NOTE(bill): Do not change the order of any of this data
|
||||||
// The compiler relies upon this _exact_ order
|
// The compiler relies upon this _exact_ order
|
||||||
Type_Info :: union {
|
Type_Info :: union {
|
||||||
Member :: struct #ordered {
|
Member :: type struct #ordered {
|
||||||
name: string; // can be empty if tuple
|
name: string; // can be empty if tuple
|
||||||
type_info: ^Type_Info;
|
type_info: ^Type_Info;
|
||||||
offset: int; // offsets are not used in tuples
|
offset: int; // offsets are not used in tuples
|
||||||
|
|||||||
+91
-2
@@ -11,6 +11,16 @@ typedef struct BuildContext {
|
|||||||
String link_flags;
|
String link_flags;
|
||||||
} BuildContext;
|
} BuildContext;
|
||||||
|
|
||||||
|
// TODO(bill): OS dependent versions for the BuildContext
|
||||||
|
// join_path
|
||||||
|
// is_dir
|
||||||
|
// is_file
|
||||||
|
// is_abs_path
|
||||||
|
// has_subdir
|
||||||
|
|
||||||
|
String const WIN32_SEPARATOR_STRING = {cast(u8 *)"\\", 1};
|
||||||
|
String const NIX_SEPARATOR_STRING = {cast(u8 *)"/", 1};
|
||||||
|
|
||||||
String odin_root_dir(void) {
|
String odin_root_dir(void) {
|
||||||
String path = global_module_path;
|
String path = global_module_path;
|
||||||
Array(wchar_t) path_buf;
|
Array(wchar_t) path_buf;
|
||||||
@@ -60,14 +70,93 @@ String odin_root_dir(void) {
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String path_to_fullpath(gbAllocator a, String s) {
|
||||||
|
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&string_buffer_arena);
|
||||||
|
String16 string16 = string_to_string16(string_buffer_allocator, s);
|
||||||
|
String result = {0};
|
||||||
|
|
||||||
|
DWORD len = GetFullPathNameW(string16.text, 0, NULL, NULL);
|
||||||
|
if (len != 0) {
|
||||||
|
wchar_t *text = gb_alloc_array(string_buffer_allocator, wchar_t, len+1);
|
||||||
|
GetFullPathNameW(string16.text, len, text, NULL);
|
||||||
|
text[len] = 0;
|
||||||
|
result = string16_to_string(a, make_string16(text, len));
|
||||||
|
}
|
||||||
|
gb_temp_arena_memory_end(tmp);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String get_fullpath_relative(gbAllocator a, String base_dir, String path) {
|
||||||
|
String res = {0};
|
||||||
|
isize str_len = base_dir.len+path.len;
|
||||||
|
|
||||||
|
u8 *str = gb_alloc_array(heap_allocator(), u8, str_len+1);
|
||||||
|
|
||||||
|
isize i = 0;
|
||||||
|
gb_memmove(str+i, base_dir.text, base_dir.len); i += base_dir.len;
|
||||||
|
gb_memmove(str+i, path.text, path.len);
|
||||||
|
str[str_len] = '\0';
|
||||||
|
res = path_to_fullpath(a, make_string(str, str_len));
|
||||||
|
gb_free(heap_allocator(), str);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
String get_fullpath_core(gbAllocator a, String path) {
|
||||||
|
String module_dir = odin_root_dir();
|
||||||
|
String res = {0};
|
||||||
|
|
||||||
|
char core[] = "core/";
|
||||||
|
isize core_len = gb_size_of(core)-1;
|
||||||
|
|
||||||
|
isize str_len = module_dir.len + core_len + path.len;
|
||||||
|
u8 *str = gb_alloc_array(heap_allocator(), u8, str_len+1);
|
||||||
|
|
||||||
|
gb_memmove(str, module_dir.text, module_dir.len);
|
||||||
|
gb_memmove(str+module_dir.len, core, core_len);
|
||||||
|
gb_memmove(str+module_dir.len+core_len, path.text, path.len);
|
||||||
|
str[str_len] = '\0';
|
||||||
|
|
||||||
|
res = path_to_fullpath(a, make_string(str, str_len));
|
||||||
|
gb_free(heap_allocator(), str);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String get_filepath_extension(String path) {
|
||||||
|
isize dot = 0;
|
||||||
|
bool seen_slash = false;
|
||||||
|
for (isize i = path.len-1; i >= 0; i--) {
|
||||||
|
u8 c = path.text[i];
|
||||||
|
if (c == '/' || c == '\\') {
|
||||||
|
seen_slash = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == '.') {
|
||||||
|
if (seen_slash) {
|
||||||
|
return str_lit("");
|
||||||
|
}
|
||||||
|
|
||||||
|
dot = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return make_string(path.text, dot);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void init_build_context(BuildContext *bc) {
|
void init_build_context(BuildContext *bc) {
|
||||||
bc->ODIN_OS = str_lit("windows");
|
|
||||||
bc->ODIN_ARCH = str_lit("amd64");
|
|
||||||
bc->ODIN_VENDOR = str_lit("odin");
|
bc->ODIN_VENDOR = str_lit("odin");
|
||||||
bc->ODIN_VERSION = str_lit("0.0.3d");
|
bc->ODIN_VERSION = str_lit("0.0.3d");
|
||||||
bc->ODIN_ROOT = odin_root_dir();
|
bc->ODIN_ROOT = odin_root_dir();
|
||||||
|
|
||||||
|
#if defined(GB_SYSTEM_WINDOWS)
|
||||||
|
bc->ODIN_OS = str_lit("windows");
|
||||||
|
bc->ODIN_ARCH = str_lit("amd64");
|
||||||
|
#else
|
||||||
|
#error Implement system
|
||||||
|
#endif
|
||||||
|
|
||||||
if (str_eq(bc->ODIN_ARCH, str_lit("amd64"))) {
|
if (str_eq(bc->ODIN_ARCH, str_lit("amd64"))) {
|
||||||
bc->word_size = 8;
|
bc->word_size = 8;
|
||||||
|
|||||||
+50
-64
@@ -266,6 +266,7 @@ typedef struct Checker {
|
|||||||
|
|
||||||
Array(Type *) proc_stack;
|
Array(Type *) proc_stack;
|
||||||
bool in_defer; // TODO(bill): Actually handle correctly
|
bool in_defer; // TODO(bill): Actually handle correctly
|
||||||
|
bool done_preload;
|
||||||
} Checker;
|
} Checker;
|
||||||
|
|
||||||
typedef struct CycleChecker {
|
typedef struct CycleChecker {
|
||||||
@@ -570,6 +571,7 @@ void init_universal_scope(BuildContext *bc) {
|
|||||||
add_global_entity(entity);
|
add_global_entity(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
t_u8_ptr = make_type_pointer(a, t_u8);
|
t_u8_ptr = make_type_pointer(a, t_u8);
|
||||||
t_int_ptr = make_type_pointer(a, t_int);
|
t_int_ptr = make_type_pointer(a, t_int);
|
||||||
}
|
}
|
||||||
@@ -986,11 +988,21 @@ MapEntity generate_minimum_dependency_map(CheckerInfo *info, Entity *start) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#include "expr.c"
|
void add_implicit_value(Checker *c, ImplicitValueId id, String name, String backing_name, Type *type) {
|
||||||
#include "decl.c"
|
ImplicitValueInfo info = {name, backing_name, type};
|
||||||
#include "stmt.c"
|
Entity *value = make_entity_implicit_value(c->allocator, info.name, info.type, id);
|
||||||
|
Entity *prev = scope_insert_entity(c->global_scope, value);
|
||||||
|
GB_ASSERT(prev == NULL);
|
||||||
|
implicit_value_infos[id] = info;
|
||||||
|
c->info.implicit_values[id] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void init_preload(Checker *c) {
|
||||||
|
if (c->done_preload) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void init_preload_types(Checker *c) {
|
|
||||||
if (t_type_info == NULL) {
|
if (t_type_info == NULL) {
|
||||||
Entity *e = current_scope_lookup_entity(c->global_scope, str_lit("Type_Info"));
|
Entity *e = current_scope_lookup_entity(c->global_scope, str_lit("Type_Info"));
|
||||||
if (e == NULL) {
|
if (e == NULL) {
|
||||||
@@ -1045,54 +1057,22 @@ void init_preload_types(Checker *c) {
|
|||||||
}
|
}
|
||||||
t_context = e->type;
|
t_context = e->type;
|
||||||
t_context_ptr = make_type_pointer(c->allocator, t_context);
|
t_context_ptr = make_type_pointer(c->allocator, t_context);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
c->done_preload = true;
|
||||||
|
|
||||||
void add_implicit_value(Checker *c, ImplicitValueId id, String name, String backing_name, Type *type) {
|
|
||||||
ImplicitValueInfo info = {name, backing_name, type};
|
|
||||||
Entity *value = make_entity_implicit_value(c->allocator, info.name, info.type, id);
|
|
||||||
Entity *prev = scope_insert_entity(c->global_scope, value);
|
|
||||||
GB_ASSERT(prev == NULL);
|
|
||||||
implicit_value_infos[id] = info;
|
|
||||||
c->info.implicit_values[id] = value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void check_global_entities_by_kind(Checker *c, EntityKind kind) {
|
|
||||||
for_array(i, c->info.entities.entries) {
|
|
||||||
MapDeclInfoEntry *entry = &c->info.entities.entries.e[i];
|
|
||||||
Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
|
|
||||||
DeclInfo *d = entry->value;
|
|
||||||
|
|
||||||
if (e->kind != kind) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (d->scope != e->scope) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
add_curr_ast_file(c, d->scope->file);
|
|
||||||
if (e->kind != Entity_Procedure && str_eq(e->token.string, str_lit("main"))) {
|
|
||||||
if (e->scope->is_init) {
|
|
||||||
error(e->token, "`main` is reserved as the entry point procedure in the initial scope");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else if (e->scope->is_global && str_eq(e->token.string, str_lit("main"))) {
|
|
||||||
error(e->token, "`main` is reserved as the entry point procedure in the initial scope");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Scope *prev_scope = c->context.scope;
|
|
||||||
c->context.scope = d->scope;
|
|
||||||
check_entity_decl(c, e, d, NULL, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "expr.c"
|
||||||
|
#include "decl.c"
|
||||||
|
#include "stmt.c"
|
||||||
|
|
||||||
void check_all_global_entities(Checker *c) {
|
void check_all_global_entities(Checker *c) {
|
||||||
|
Scope *prev_file = {0};
|
||||||
|
|
||||||
for_array(i, c->info.entities.entries) {
|
for_array(i, c->info.entities.entries) {
|
||||||
MapDeclInfoEntry *entry = &c->info.entities.entries.e[i];
|
MapDeclInfoEntry *entry = &c->info.entities.entries.e[i];
|
||||||
Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
|
Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
|
||||||
@@ -1101,8 +1081,8 @@ void check_all_global_entities(Checker *c) {
|
|||||||
if (d->scope != e->scope) {
|
if (d->scope != e->scope) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_curr_ast_file(c, d->scope->file);
|
add_curr_ast_file(c, d->scope->file);
|
||||||
|
|
||||||
if (e->kind != Entity_Procedure && str_eq(e->token.string, str_lit("main"))) {
|
if (e->kind != Entity_Procedure && str_eq(e->token.string, str_lit("main"))) {
|
||||||
if (e->scope->is_init) {
|
if (e->scope->is_init) {
|
||||||
error(e->token, "`main` is reserved as the entry point procedure in the initial scope");
|
error(e->token, "`main` is reserved as the entry point procedure in the initial scope");
|
||||||
@@ -1116,10 +1096,15 @@ void check_all_global_entities(Checker *c) {
|
|||||||
Scope *prev_scope = c->context.scope;
|
Scope *prev_scope = c->context.scope;
|
||||||
c->context.scope = d->scope;
|
c->context.scope = d->scope;
|
||||||
check_entity_decl(c, e, d, NULL, NULL);
|
check_entity_decl(c, e, d, NULL, NULL);
|
||||||
|
|
||||||
|
|
||||||
|
if (d->scope->is_init && !c->done_preload) {
|
||||||
|
init_preload(c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_global_collect_entities(Checker *c, Scope *parent_scope, AstNodeArray nodes, MapScope *file_scopes) {
|
void check_global_collect_entities_from_file(Checker *c, Scope *parent_scope, AstNodeArray nodes, MapScope *file_scopes) {
|
||||||
for_array(decl_index, nodes) {
|
for_array(decl_index, nodes) {
|
||||||
AstNode *decl = nodes.e[decl_index];
|
AstNode *decl = nodes.e[decl_index];
|
||||||
if (!is_ast_node_decl(decl) && !is_ast_node_when_stmt(decl)) {
|
if (!is_ast_node_decl(decl) && !is_ast_node_when_stmt(decl)) {
|
||||||
@@ -1179,6 +1164,7 @@ void check_global_collect_entities(Checker *c, Scope *parent_scope, AstNodeArray
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE(bill): You need to store the entity information here unline a constant declaration
|
||||||
isize entity_count = vd->names.count;
|
isize entity_count = vd->names.count;
|
||||||
isize entity_index = 0;
|
isize entity_index = 0;
|
||||||
Entity **entities = gb_alloc_array(c->allocator, Entity *, entity_count);
|
Entity **entities = gb_alloc_array(c->allocator, Entity *, entity_count);
|
||||||
@@ -1351,6 +1337,7 @@ void check_import_entities(Checker *c, MapScope *file_scopes) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (import_name.len > 0) {
|
if (import_name.len > 0) {
|
||||||
|
GB_ASSERT(id->import_name.pos.line != 0);
|
||||||
id->import_name.string = import_name;
|
id->import_name.string = import_name;
|
||||||
Entity *e = make_entity_import_name(c->allocator, parent_scope, id->import_name, t_invalid,
|
Entity *e = make_entity_import_name(c->allocator, parent_scope, id->import_name, t_invalid,
|
||||||
id->fullpath, id->import_name.string,
|
id->fullpath, id->import_name.string,
|
||||||
@@ -1399,9 +1386,7 @@ void check_parsed_files(Checker *c) {
|
|||||||
scope->is_global = f->is_global_scope;
|
scope->is_global = f->is_global_scope;
|
||||||
scope->is_file = true;
|
scope->is_file = true;
|
||||||
scope->file = f;
|
scope->file = f;
|
||||||
if (i == 0) {
|
if (str_eq(f->tokenizer.fullpath, c->parser->init_fullpath)) {
|
||||||
// NOTE(bill): First file is always the initial file
|
|
||||||
// thus it must contain main
|
|
||||||
scope->is_init = true;
|
scope->is_init = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1420,26 +1405,23 @@ void check_parsed_files(Checker *c) {
|
|||||||
for_array(i, c->parser->files) {
|
for_array(i, c->parser->files) {
|
||||||
AstFile *f = &c->parser->files.e[i];
|
AstFile *f = &c->parser->files.e[i];
|
||||||
add_curr_ast_file(c, f);
|
add_curr_ast_file(c, f);
|
||||||
check_global_collect_entities(c, f->scope, f->decls, &file_scopes);
|
check_global_collect_entities_from_file(c, f->scope, f->decls, &file_scopes);
|
||||||
}
|
}
|
||||||
|
|
||||||
check_import_entities(c, &file_scopes);
|
check_import_entities(c, &file_scopes);
|
||||||
|
|
||||||
#if 0
|
map_scope_destroy(&file_scopes);
|
||||||
check_global_entities_by_kind(c, Entity_TypeName);
|
|
||||||
check_global_entities_by_kind(c, Entity_Constant);
|
|
||||||
init_preload_types(c);
|
|
||||||
add_implicit_value(c, ImplicitValue_context, str_lit("context"), str_lit("__context"), t_context);
|
|
||||||
check_global_entities_by_kind(c, Entity_Procedure);
|
|
||||||
check_global_entities_by_kind(c, Entity_Variable);
|
|
||||||
#else
|
|
||||||
check_all_global_entities(c);
|
|
||||||
init_preload_types(c);
|
|
||||||
add_implicit_value(c, ImplicitValue_context, str_lit("context"), str_lit("__context"), t_context);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
check_all_global_entities(c);
|
||||||
|
init_preload(c); // NOTE(bill): This could be setup previously through the use of `type_info(_of_val)`
|
||||||
|
// NOTE(bill): Nothing is the global scope _should_ depend on this implicit value as implicit
|
||||||
|
// values are only useful within procedures
|
||||||
|
add_implicit_value(c, ImplicitValue_context, str_lit("context"), str_lit("__context"), t_context);
|
||||||
|
|
||||||
|
// Initialize implicit values with backing variables
|
||||||
|
// TODO(bill): Are implicit values "too implicit"?
|
||||||
for (isize i = 1; i < ImplicitValue_Count; i++) {
|
for (isize i = 1; i < ImplicitValue_Count; i++) {
|
||||||
// NOTE(bill): First is invalid
|
// NOTE(bill): 0th is invalid
|
||||||
Entity *e = c->info.implicit_values[i];
|
Entity *e = c->info.implicit_values[i];
|
||||||
GB_ASSERT(e->kind == Entity_ImplicitValue);
|
GB_ASSERT(e->kind == Entity_ImplicitValue);
|
||||||
|
|
||||||
@@ -1451,6 +1433,7 @@ void check_parsed_files(Checker *c) {
|
|||||||
|
|
||||||
|
|
||||||
// Check procedure bodies
|
// Check procedure bodies
|
||||||
|
// NOTE(bill): Nested procedures bodies will be added to this "queue"
|
||||||
for_array(i, c->procs) {
|
for_array(i, c->procs) {
|
||||||
ProcedureInfo *pi = &c->procs.e[i];
|
ProcedureInfo *pi = &c->procs.e[i];
|
||||||
add_curr_ast_file(c, pi->file);
|
add_curr_ast_file(c, pi->file);
|
||||||
@@ -1487,6 +1470,11 @@ void check_parsed_files(Checker *c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(bill): Check for unused imports (and remove) or even warn/err
|
||||||
|
// TODO(bill): Any other checks?
|
||||||
|
|
||||||
|
|
||||||
|
// Add "Basic" type information
|
||||||
for (isize i = 0; i < gb_count_of(basic_types)-1; i++) {
|
for (isize i = 0; i < gb_count_of(basic_types)-1; i++) {
|
||||||
Type *t = &basic_types[i];
|
Type *t = &basic_types[i];
|
||||||
if (t->Basic.size > 0) {
|
if (t->Basic.size > 0) {
|
||||||
@@ -1500,8 +1488,6 @@ void check_parsed_files(Checker *c) {
|
|||||||
add_type_info_type(c, t);
|
add_type_info_type(c, t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
map_scope_destroy(&file_scopes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+12
-1
@@ -2939,6 +2939,12 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
|||||||
|
|
||||||
case BuiltinProc_type_info: {
|
case BuiltinProc_type_info: {
|
||||||
// type_info :: proc(Type) -> ^Type_Info
|
// type_info :: proc(Type) -> ^Type_Info
|
||||||
|
if (c->context.scope->is_global) {
|
||||||
|
compiler_error("`type_info` Cannot be declared within a #shared_global_scope due to how the internals of the compiler works");
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE(bill): The type information may not be setup yet
|
||||||
|
init_preload(c);
|
||||||
AstNode *expr = ce->args.e[0];
|
AstNode *expr = ce->args.e[0];
|
||||||
Type *type = check_type(c, expr);
|
Type *type = check_type(c, expr);
|
||||||
if (type == NULL || type == t_invalid) {
|
if (type == NULL || type == t_invalid) {
|
||||||
@@ -2954,8 +2960,13 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
|||||||
|
|
||||||
case BuiltinProc_type_info_of_val: {
|
case BuiltinProc_type_info_of_val: {
|
||||||
// type_info_of_val :: proc(val: Type) -> ^Type_Info
|
// type_info_of_val :: proc(val: Type) -> ^Type_Info
|
||||||
AstNode *expr = ce->args.e[0];
|
if (c->context.scope->is_global) {
|
||||||
|
compiler_error("`type_info` Cannot be declared within a #shared_global_scope due to how the internals of the compiler works");
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE(bill): The type information may not be setup yet
|
||||||
|
init_preload(c);
|
||||||
|
AstNode *expr = ce->args.e[0];
|
||||||
check_assignment(c, operand, NULL, str_lit("argument of `type_info_of_val`"));
|
check_assignment(c, operand, NULL, str_lit("argument of `type_info_of_val`"));
|
||||||
if (operand->mode == Addressing_Invalid || operand->mode == Addressing_Builtin)
|
if (operand->mode == Addressing_Invalid || operand->mode == Addressing_Builtin)
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -13,22 +13,6 @@ gb_global String global_module_path = {0};
|
|||||||
gb_global bool global_module_path_set = false;
|
gb_global bool global_module_path_set = false;
|
||||||
|
|
||||||
|
|
||||||
String path_to_fullpath(gbAllocator a, String s) {
|
|
||||||
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&string_buffer_arena);
|
|
||||||
String16 string16 = string_to_string16(string_buffer_allocator, s);
|
|
||||||
String result = {0};
|
|
||||||
|
|
||||||
DWORD len = GetFullPathNameW(string16.text, 0, NULL, NULL);
|
|
||||||
if (len != 0) {
|
|
||||||
wchar_t *text = gb_alloc_array(string_buffer_allocator, wchar_t, len+1);
|
|
||||||
GetFullPathNameW(string16.text, len, text, NULL);
|
|
||||||
text[len] = 0;
|
|
||||||
result = string16_to_string(a, make_string16(text, len));
|
|
||||||
}
|
|
||||||
gb_temp_arena_memory_end(tmp);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
i64 next_pow2(i64 n) {
|
i64 next_pow2(i64 n) {
|
||||||
if (n <= 0) {
|
if (n <= 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
+7
-57
@@ -2869,6 +2869,9 @@ AstNode *parse_stmt(AstFile *f) {
|
|||||||
import_name = f->curr_token;
|
import_name = f->curr_token;
|
||||||
next_token(f);
|
next_token(f);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
import_name.pos = hash_token.pos;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (str_eq(import_name.string, str_lit("_"))) {
|
if (str_eq(import_name.string, str_lit("_"))) {
|
||||||
@@ -3068,40 +3071,6 @@ bool try_add_import_path(Parser *p, String path, String rel_path, TokenPos pos)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
String get_fullpath_relative(gbAllocator a, String base_dir, String path) {
|
|
||||||
String res = {0};
|
|
||||||
isize str_len = base_dir.len+path.len;
|
|
||||||
|
|
||||||
u8 *str = gb_alloc_array(heap_allocator(), u8, str_len+1);
|
|
||||||
|
|
||||||
isize i = 0;
|
|
||||||
gb_memmove(str+i, base_dir.text, base_dir.len); i += base_dir.len;
|
|
||||||
gb_memmove(str+i, path.text, path.len);
|
|
||||||
str[str_len] = '\0';
|
|
||||||
res = path_to_fullpath(a, make_string(str, str_len));
|
|
||||||
gb_free(heap_allocator(), str);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
String get_fullpath_core(gbAllocator a, String path) {
|
|
||||||
String module_dir = odin_root_dir();
|
|
||||||
String res = {0};
|
|
||||||
|
|
||||||
char core[] = "core/";
|
|
||||||
isize core_len = gb_size_of(core)-1;
|
|
||||||
|
|
||||||
isize str_len = module_dir.len + core_len + path.len;
|
|
||||||
u8 *str = gb_alloc_array(heap_allocator(), u8, str_len+1);
|
|
||||||
|
|
||||||
gb_memmove(str, module_dir.text, module_dir.len);
|
|
||||||
gb_memmove(str+module_dir.len, core, core_len);
|
|
||||||
gb_memmove(str+module_dir.len+core_len, path.text, path.len);
|
|
||||||
str[str_len] = '\0';
|
|
||||||
|
|
||||||
res = path_to_fullpath(a, make_string(str, str_len));
|
|
||||||
gb_free(heap_allocator(), str);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
// // NOTE(bill): Returns true if it's added
|
// // NOTE(bill): Returns true if it's added
|
||||||
// bool try_add_foreign_library_path(Parser *p, String import_file) {
|
// bool try_add_foreign_library_path(Parser *p, String import_file) {
|
||||||
@@ -3157,27 +3126,6 @@ bool is_import_path_valid(String path) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
String get_filepath_extension(String path) {
|
|
||||||
isize dot = 0;
|
|
||||||
bool seen_slash = false;
|
|
||||||
for (isize i = path.len-1; i >= 0; i--) {
|
|
||||||
u8 c = path.text[i];
|
|
||||||
if (c == '/' || c == '\\') {
|
|
||||||
seen_slash = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == '.') {
|
|
||||||
if (seen_slash) {
|
|
||||||
return str_lit("");
|
|
||||||
}
|
|
||||||
|
|
||||||
dot = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return make_string(path.text, dot);
|
|
||||||
}
|
|
||||||
|
|
||||||
void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, AstNodeArray decls) {
|
void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, AstNodeArray decls) {
|
||||||
for_array(i, decls) {
|
for_array(i, decls) {
|
||||||
AstNode *node = decls.e[i];
|
AstNode *node = decls.e[i];
|
||||||
@@ -3261,8 +3209,7 @@ ParseFileError parse_files(Parser *p, char *init_filename) {
|
|||||||
String init_fullpath = make_string_c(fullpath_str);
|
String init_fullpath = make_string_c(fullpath_str);
|
||||||
TokenPos init_pos = {0};
|
TokenPos init_pos = {0};
|
||||||
ImportedFile init_imported_file = {init_fullpath, init_fullpath, init_pos};
|
ImportedFile init_imported_file = {init_fullpath, init_fullpath, init_pos};
|
||||||
array_add(&p->imports, init_imported_file);
|
|
||||||
p->init_fullpath = init_fullpath;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
String s = get_fullpath_core(heap_allocator(), str_lit("_preload.odin"));
|
String s = get_fullpath_core(heap_allocator(), str_lit("_preload.odin"));
|
||||||
@@ -3275,6 +3222,9 @@ ParseFileError parse_files(Parser *p, char *init_filename) {
|
|||||||
array_add(&p->imports, runtime_file);
|
array_add(&p->imports, runtime_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
array_add(&p->imports, init_imported_file);
|
||||||
|
p->init_fullpath = init_fullpath;
|
||||||
|
|
||||||
for_array(i, p->imports) {
|
for_array(i, p->imports) {
|
||||||
ImportedFile imported_file = p->imports.e[i];
|
ImportedFile imported_file = p->imports.e[i];
|
||||||
String import_path = imported_file.path;
|
String import_path = imported_file.path;
|
||||||
|
|||||||
@@ -108,19 +108,6 @@ GB_COMPARE_PROC(string_cmp_proc) {
|
|||||||
return string_compare(x, y);
|
return string_compare(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// gb_inline bool operator ==(String a, String b) { return are_strings_equal(a, b) != 0; }
|
|
||||||
// gb_inline bool operator !=(String a, String b) { return !operator==(a, b); }
|
|
||||||
// gb_inline bool operator < (String a, String b) { return string_compare(a, b) < 0; }
|
|
||||||
// gb_inline bool operator > (String a, String b) { return string_compare(a, b) > 0; }
|
|
||||||
// gb_inline bool operator <=(String a, String b) { return string_compare(a, b) <= 0; }
|
|
||||||
// gb_inline bool operator >=(String a, String b) { return string_compare(a, b) >= 0; }
|
|
||||||
|
|
||||||
// template <size_t N> gb_inline bool operator ==(String a, char const (&b)[N]) { return a == make_string(cast(u8 *)b, N-1); }
|
|
||||||
// template <size_t N> gb_inline bool operator !=(String a, char const (&b)[N]) { return a != make_string(cast(u8 *)b, N-1); }
|
|
||||||
// template <size_t N> gb_inline bool operator ==(char const (&a)[N], String b) { return make_string(cast(u8 *)a, N-1) == b; }
|
|
||||||
// template <size_t N> gb_inline bool operator !=(char const (&a)[N], String b) { return make_string(cast(u8 *)a, N-1) != b; }
|
|
||||||
|
|
||||||
gb_inline bool str_eq(String a, String b) { return a.len == b.len ? gb_memcompare(a.text, b.text, a.len) == 0 : false; }
|
gb_inline bool str_eq(String a, String b) { return a.len == b.len ? gb_memcompare(a.text, b.text, a.len) == 0 : false; }
|
||||||
gb_inline bool str_ne(String a, String b) { return !str_eq(a, b); }
|
gb_inline bool str_ne(String a, String b) { return !str_eq(a, b); }
|
||||||
gb_inline bool str_lt(String a, String b) { return string_compare(a, b) < 0; }
|
gb_inline bool str_lt(String a, String b) { return string_compare(a, b) < 0; }
|
||||||
|
|||||||
Reference in New Issue
Block a user