Entity_Type_Load_File,
Entity_Type_Binding,
Entity_Type_Use_Package,
+ Entity_Type_Static_If,
Entity_Type_String_Literal,
Entity_Type_File_Contents,
Entity_Type_Enum,
AstInclude *include;
AstUsePackage *use_package;
AstBinding *binding;
+ AstStaticIf *static_if;
AstFunction *function;
AstOverloadedFunction *overloaded_function;
AstGlobal *global;
Entity* entity_heap_top(EntityHeap* entities);
void entity_heap_change_top(EntityHeap* entities, Entity* new_top);
void entity_heap_remove_top(EntityHeap* entities);
-void add_entities_for_node(AstNode* node, Scope* scope, Package* package);
+
+// If target_arr is null, the entities will be placed directly in the heap.
+void add_entities_for_node(bh_arr(Entity *)* target_arr, AstNode* node, Scope* scope, Package* package);
void entity_bring_to_state(Entity* ent, EntityState state);
void symres_entity(Entity* ent);
PolymorphicContext polymorph_context;
bh_arr(Scope *) scope_stack;
+ bh_arr(AstStaticIf *) static_if_stack;
b32 hit_unexpected_token : 1;
} OnyxParser;
ONYX_COMPILER_PROGRESS_SUCCESS
} CompilerProgress;
+static OnyxToken implicit_load_token = { '#', 1, 0, { 0, 0, 0, 0, 0 } };
static AstInclude* create_load(bh_allocator alloc, char* filename) {
+
AstInclude* include_node = onyx_ast_node_new(alloc, sizeof(AstInclude), Ast_Kind_Load_File);
include_node->name = filename;
+ include_node->token = &implicit_load_token;
return include_node;
}
.include = create_load(context.ast_alloc, "core/builtin"),
}));
- add_entities_for_node((AstNode *) &builtin_stack_top, context.global_scope, NULL);
+ add_entities_for_node(NULL, (AstNode *) &builtin_stack_top, context.global_scope, NULL);
// NOTE: Add all files passed by command line to the queue
bh_arr_each(const char *, filename, opts->files) {
AstInclude* load_node = create_load(context.ast_alloc, (char *) *filename);
- add_entities_for_node((AstNode *) load_node, context.global_scope, NULL);
+ add_entities_for_node(NULL, (AstNode *) load_node, context.global_scope, NULL);
}
}
onyx_parser_free(&parser);
}
-static void process_source_file(char* filename) {
+static void process_source_file(char* filename, OnyxFilePos error_pos) {
bh_arr_each(bh_file_contents, fc, context.loaded_files) {
// CLEANUP: Add duplicate resolutions, such as
// ./foo and ./test/../foo
bh_file file;
bh_file_error err = bh_file_open(&file, filename);
if (err != BH_FILE_ERROR_NONE) {
- onyx_report_error((OnyxFilePos) { 0 }, "Failed to open file %s\n", filename);
+ onyx_report_error(error_pos, "Failed to open file %s", filename);
return;
}
char* filename = lookup_included_file(include->name);
char* formatted_name = bh_strdup(global_heap_allocator, filename);
- process_source_file(formatted_name);
+ process_source_file(formatted_name, include->token->pos);
} else if (include->kind == Ast_Kind_Load_Path) {
bh_arr_push(context.options->included_folders, include->name);
ent->state = Entity_State_Finalized;
break;
+ case Entity_State_Comptime_Resolve_Symbols:
case Entity_State_Resolve_Symbols: symres_entity(ent); break;
+
+ case Entity_State_Comptime_Check_Types:
case Entity_State_Check_Types: check_entity(ent); break;
+
case Entity_State_Code_Gen: emit_entity(ent); break;
default:
"Load File",
"Binding (Declaration)",
"Use Package",
+ "Static If",
"String Literal",
"File Contents",
"Enum",
#define CHECK(kind, ...) do { \
CheckStatus cs = check_ ## kind (__VA_ARGS__); \
- if (cs != Check_Success) return cs; \
+ if (cs > Check_Errors_Start) return cs; \
} while (0)
typedef enum CheckStatus {
- Check_Success,
- Check_Error,
+ Check_Success, // The node was successfully checked with out errors
+ Check_Complete, // The node is done processing
+
+ Check_Errors_Start,
+ Check_Error, // There was an error when checking the node
} CheckStatus;
CheckStatus check_block(AstBlock* block);
return Check_Success;
}
+CheckStatus check_static_if(AstStaticIf* static_if) {
+ CHECK(expression, &static_if->cond);
+
+ if (static_if->cond->flags & Ast_Flag_Comptime) {
+ AstNumLit* condition_value = (AstNumLit *) static_if->cond;
+ assert(condition_value->kind == Ast_Kind_NumLit); // This should be right, right?
+
+ if (condition_value->value.i) {
+ bh_arr_each(Entity *, ent, static_if->true_entities) {
+ entity_heap_insert_existing(&context.entities, *ent);
+ }
+ }
+
+ } else {
+ onyx_report_error(static_if->token->pos, "Expected this condition to be compile time known.");
+ return Check_Error;
+ }
+
+ return Check_Complete;
+}
+
CheckStatus check_node(AstNode* node) {
switch (node->kind) {
case Ast_Kind_Function: return check_function((AstFunction *) node);
if (ent->type_alias->kind == Ast_Kind_Struct_Type)
cs = check_struct((AstStructType *) ent->type_alias);
else
- check_type(ent->type_alias);
+ cs = check_type(ent->type_alias);
break;
case Entity_Type_Memory_Reservation_Type:
cs = check_memres(ent->mem_res);
break;
+ case Entity_Type_Static_If:
+ cs = check_static_if(ent->static_if);
+ break;
+
default: break;
}
- if (cs == Check_Success) {
- ent->state = Entity_State_Code_Gen;
- }
+ if (cs == Check_Success) ent->state = Entity_State_Code_Gen;
+ if (cs == Check_Complete) ent->state = Entity_State_Finalized;
// else if (cs == Check_Yield) {
// ent->attempts++;
// }
}
// NOTE(Brendan Hansen): Uses the entity heap in the context structure
-void add_entities_for_node(AstNode* node, Scope* scope, Package* package) {
+void add_entities_for_node(bh_arr(Entity *) *target_arr, AstNode* node, Scope* scope, Package* package) {
+#define ENTITY_INSERT(_ent) { \
+ Entity* entity = entity_heap_register(entities, _ent); \
+ if (target_arr) { \
+ bh_arr(Entity *) __tmp_arr = *target_arr; \
+ bh_arr_push(__tmp_arr, entity); \
+ *target_arr = __tmp_arr; \
+ } else { \
+ entity_heap_insert_existing(entities, entity); \
+ } \
+ }
+
EntityHeap* entities = &context.entities;
Entity ent;
ent.state = Entity_State_Parse;
ent.type = Entity_Type_Load_File;
ent.include = (AstInclude *) node;
- entity_heap_insert(entities, ent);
+ ENTITY_INSERT(ent);
break;
}
ent.state = Entity_State_Parse;
ent.type = Entity_Type_Load_Path;
ent.include = (AstInclude *) node;
- entity_heap_insert(entities, ent);
+ ENTITY_INSERT(ent);
break;
}
ent.state = Entity_State_Introduce_Symbols;
ent.type = Entity_Type_Binding;
ent.binding = (AstBinding *) node;
- entity_heap_insert(entities, ent);
+ ENTITY_INSERT(ent);
break;
}
if ((node->flags & Ast_Flag_Foreign) != 0) {
ent.type = Entity_Type_Foreign_Function_Header;
ent.function = (AstFunction *) node;
- entity_heap_insert(entities, ent);
+ ENTITY_INSERT(ent);
} else {
ent.type = Entity_Type_Function_Header;
ent.function = (AstFunction *) node;
- entity_heap_insert(entities, ent);
+ ENTITY_INSERT(ent);
ent.type = Entity_Type_Function;
ent.function = (AstFunction *) node;
- entity_heap_insert(entities, ent);
+ ENTITY_INSERT(ent);
}
break;
}
case Ast_Kind_Overloaded_Function: {
ent.type = Entity_Type_Overloaded_Function;
ent.overloaded_function = (AstOverloadedFunction *) node;
- entity_heap_insert(entities, ent);
+ ENTITY_INSERT(ent);
break;
}
if ((node->flags & Ast_Flag_Foreign) != 0) {
ent.type = Entity_Type_Foreign_Global_Header;
ent.global = (AstGlobal *) node;
- entity_heap_insert(entities, ent);
+ ENTITY_INSERT(ent);
} else {
ent.type = Entity_Type_Global_Header;
ent.global = (AstGlobal *) node;
- entity_heap_insert(entities, ent);
+ ENTITY_INSERT(ent);
ent.type = Entity_Type_Global;
ent.global = (AstGlobal *) node;
- entity_heap_insert(entities, ent);
+ ENTITY_INSERT(ent);
}
break;
}
case Ast_Kind_StrLit: {
ent.type = Entity_Type_String_Literal;
ent.strlit = (AstStrLit *) node;
- entity_heap_insert(entities, ent);
+ ENTITY_INSERT(ent);
break;
}
case Ast_Kind_File_Contents: {
ent.type = Entity_Type_File_Contents;
ent.file_contents = (AstFileContents *) node;
- entity_heap_insert(entities, ent);
+ ENTITY_INSERT(ent);
break;
}
case Ast_Kind_Struct_Type: {
ent.type = Entity_Type_Struct_Member_Default;
ent.type_alias = (AstType *) node;
- entity_heap_insert(entities, ent);
+ ENTITY_INSERT(ent);
// fallthrough
}
case Ast_Kind_Type_Alias: {
ent.type = Entity_Type_Type_Alias;
ent.type_alias = (AstType *) node;
- entity_heap_insert(entities, ent);
+ ENTITY_INSERT(ent);
break;
}
case Ast_Kind_Enum_Type: {
ent.type = Entity_Type_Enum;
ent.enum_type = (AstEnumType *) node;
- entity_heap_insert(entities, ent);
+ ENTITY_INSERT(ent);
break;
}
case Ast_Kind_Use_Package: {
+ ent.state = Entity_State_Comptime_Resolve_Symbols;
ent.type = Entity_Type_Use_Package;
ent.use_package = (AstUsePackage *) node;
- entity_heap_insert(entities, ent);
+ ENTITY_INSERT(ent);
break;
}
case Ast_Kind_Use: {
ent.type = Entity_Type_Use;
ent.use = (AstUse *) node;
- entity_heap_insert(entities, ent);
+ ENTITY_INSERT(ent);
break;
}
case Ast_Kind_Memres: {
ent.type = Entity_Type_Memory_Reservation_Type;
ent.mem_res = (AstMemRes *) node;
- entity_heap_insert(entities, ent);
+ ENTITY_INSERT(ent);
ent.type = Entity_Type_Memory_Reservation;
ent.mem_res = (AstMemRes *) node;
- entity_heap_insert(entities, ent);
+ ENTITY_INSERT(ent);
break;
}
case Ast_Kind_Polymorphic_Proc: {
ent.type = Entity_Type_Polymorphic_Proc;
ent.poly_proc = (AstPolyProc *) node;
- entity_heap_insert(entities, ent);
+ ENTITY_INSERT(ent);
+ break;
+ }
+
+ case Ast_Kind_Static_If: {
+ ent.state = Entity_State_Comptime_Resolve_Symbols;
+ ent.type = Entity_Type_Static_If;
+ ent.static_if = (AstStaticIf *) node;
+ ENTITY_INSERT(ent);
break;
}
default: {
ent.type = Entity_Type_Expression;
ent.expr = (AstTyped *) node;
- entity_heap_insert(entities, ent);
+ ENTITY_INSERT(ent);
break;
}
}
#include "onyxparser.h"
#include "onyxutils.h"
-// NOTE: The one weird define you need to know before read the code below
#define make_node(nclass, kind) onyx_ast_node_new(parser->allocator, sizeof(nclass), kind)
#define peek_token(ahead) (parser->curr + ahead)
-#define ENTITY_SUBMIT(node) (add_entities_for_node((AstNode *) (node), bh_arr_last(parser->scope_stack), parser->package))
-#define ENTITY_SUBMIT_IN_SCOPE(node, scope) (add_entities_for_node((AstNode *) (node), scope, parser->package))
static AstNode error_node = { Ast_Kind_Error, 0, NULL, NULL };
+#define ENTITY_SUBMIT(node) (submit_entity_in_scope(parser, (AstNode *) (node), bh_arr_last(parser->scope_stack), parser->package))
+#define ENTITY_SUBMIT_IN_SCOPE(node, scope) (submit_entity_in_scope(parser, (AstNode *) (node), scope, parser->package))
+
+void submit_entity_in_scope(OnyxParser* parser, AstNode* node, Scope* scope, Package* package) {
+ if (bh_arr_length(parser->static_if_stack) == 0) {
+ add_entities_for_node(NULL, node, scope, package);
+
+ } else {
+ AstStaticIf* static_if = bh_arr_last(parser->static_if_stack);
+
+ // nocheckin This should also be able to place them in the false entities
+ add_entities_for_node(&static_if->true_entities, node, scope, package);
+ }
+}
+
+// Parsing Utilities
static void consume_token(OnyxParser* parser);
static void unconsume_token(OnyxParser* parser);
static OnyxToken* expect_token(OnyxParser* parser, TokenType token_type);
static b32 consume_token_if_next(OnyxParser* parser, TokenType token_type);
+static b32 next_tokens_are(OnyxParser* parser, i32 n, ...);
+static OnyxToken* find_matching_paren(OnyxToken* paren);
static AstNumLit* parse_int_literal(OnyxParser* parser);
static AstNumLit* parse_float_literal(OnyxParser* parser);
static AstEnumType* parse_enum_declaration(OnyxParser* parser);
static AstTyped* parse_top_level_expression(OnyxParser* parser);
static AstBinding* parse_top_level_binding(OnyxParser* parser, OnyxToken* symbol);
-static AstNode* parse_top_level_statement(OnyxParser* parser);
+static void parse_top_level_statement(OnyxParser* parser);
static AstPackage* parse_package_name(OnyxParser* parser);
static void consume_token(OnyxParser* parser) {
}
static b32 parse_possible_directive(OnyxParser* parser, const char* dir) {
- if (parser->curr->type != '#') return 0;
+ if (peek_token(0)->type != '#' || peek_token(1)->type != Token_Type_Symbol) return 0;
expect_token(parser, '#');
OnyxToken* sym = expect_token(parser, Token_Type_Symbol);
return enum_node;
}
+static AstStaticIf* parse_static_if_stmt(OnyxParser* parser) {
+ AstStaticIf* static_if_node = make_node(AstStaticIf, Ast_Kind_Static_If);
+ static_if_node->token = expect_token(parser, '#');
+ expect_token(parser, Token_Type_Keyword_If);
+
+ static_if_node->cond = parse_expression(parser, 0);
+
+ // TODO: Add else statements to static ifs
+ bh_arr_new(global_heap_allocator, static_if_node->true_entities, 4);
+ bh_arr_push(parser->static_if_stack, static_if_node);
+
+ expect_token(parser, '{');
+ while (!consume_token_if_next(parser, '}')) {
+ if (parser->hit_unexpected_token) return static_if_node;
+
+ parse_top_level_statement(parser);
+ }
+
+ bh_arr_pop(parser->static_if_stack);
+
+ return static_if_node;
+}
+
static AstTyped* parse_top_level_expression(OnyxParser* parser) {
if (parser->curr->type == Token_Type_Keyword_Proc) {
OnyxToken* proc_token = expect_token(parser, Token_Type_Keyword_Proc);
return binding;
}
-static AstNode* parse_top_level_statement(OnyxParser* parser) {
+static void parse_top_level_statement(OnyxParser* parser) {
AstFlags private_kind = 0;
- if (parse_possible_directive(parser, "private")) {
- private_kind = Ast_Flag_Private_Package;
- }
+ if (parse_possible_directive(parser, "private")) private_kind = Ast_Flag_Private_Package;
+ else if (parse_possible_directive(parser, "private_file")) private_kind = Ast_Flag_Private_File;
- else if (parse_possible_directive(parser, "private_file")) {
- private_kind = Ast_Flag_Private_File;
- }
+ AstBinding* binding = NULL;
- // CLEANUP
switch ((u16) parser->curr->type) {
case Token_Type_Keyword_Use: {
AstNode* use_node = parse_use_stmt(parser);
ENTITY_SUBMIT(use_node);
- return NULL;
+ return;
}
case Token_Type_Keyword_Proc:
parse_top_level_expression(parser);
- return NULL;
+ return;
case Token_Type_Symbol: {
OnyxToken* symbol = expect_token(parser, Token_Type_Symbol);
expect_token(parser, ':');
if (parser->curr->type == ':') {
- AstBinding* binding = parse_top_level_binding(parser, symbol);
-
+ binding = parse_top_level_binding(parser, symbol);
if (binding != NULL) binding->node->flags |= private_kind;
- return (AstNode *) binding;
+ goto submit_binding_to_entities;
}
AstMemRes* memres = make_node(AstMemRes, Ast_Kind_Memres);
ENTITY_SUBMIT(memres);
- AstBinding* binding = make_node(AstBinding, Ast_Kind_Binding);
+ binding = make_node(AstBinding, Ast_Kind_Binding);
binding->token = symbol;
binding->node = (AstNode *) memres;
- return (AstNode *) binding;
+ goto submit_binding_to_entities;
}
case '#': {
- while (parser->curr->type == '#') {
- OnyxToken* dir_token = parser->curr;
-
- if (parse_possible_directive(parser, "load")) {
- AstInclude* include = make_node(AstInclude, Ast_Kind_Load_File);
- include->token = dir_token;
-
- OnyxToken* str_token = expect_token(parser, Token_Type_Literal_String);
- if (str_token != NULL) {
- token_toggle_end(str_token);
- include->name = bh_strdup(parser->allocator, str_token->text);
- token_toggle_end(str_token);
- }
-
- ENTITY_SUBMIT(include);
- return NULL;
+ if (next_tokens_are(parser, 2, '#', Token_Type_Keyword_If)) {
+ AstStaticIf* static_if = parse_static_if_stmt(parser);
+ ENTITY_SUBMIT(static_if);
+ return;
+ }
+
+ OnyxToken* dir_token = parser->curr;
+
+ if (parse_possible_directive(parser, "load")) {
+ AstInclude* include = make_node(AstInclude, Ast_Kind_Load_File);
+ include->token = dir_token;
+
+ OnyxToken* str_token = expect_token(parser, Token_Type_Literal_String);
+ if (str_token != NULL) {
+ token_toggle_end(str_token);
+ include->name = bh_strdup(parser->allocator, str_token->text);
+ token_toggle_end(str_token);
}
- else if (parse_possible_directive(parser, "load_path")) {
- AstInclude* include = make_node(AstInclude, Ast_Kind_Load_Path);
- include->token = dir_token;
-
- OnyxToken* str_token = expect_token(parser, Token_Type_Literal_String);
- if (str_token != NULL) {
- token_toggle_end(str_token);
- include->name = bh_strdup(parser->allocator, str_token->text);
- token_toggle_end(str_token);
- }
-
- ENTITY_SUBMIT(include);
- return NULL;
+
+ ENTITY_SUBMIT(include);
+ return;
+ }
+ else if (parse_possible_directive(parser, "load_path")) {
+ AstInclude* include = make_node(AstInclude, Ast_Kind_Load_Path);
+ include->token = dir_token;
+
+ OnyxToken* str_token = expect_token(parser, Token_Type_Literal_String);
+ if (str_token != NULL) {
+ token_toggle_end(str_token);
+ include->name = bh_strdup(parser->allocator, str_token->text);
+ token_toggle_end(str_token);
}
- else {
- OnyxToken* directive_token = expect_token(parser, '#');
- OnyxToken* symbol_token = expect_token(parser, Token_Type_Symbol);
+
+ ENTITY_SUBMIT(include);
+ return;
+ }
+ else {
+ OnyxToken* directive_token = expect_token(parser, '#');
+ OnyxToken* symbol_token = expect_token(parser, Token_Type_Symbol);
- onyx_report_error(directive_token->pos, "unknown directive '#%b'.", symbol_token->text, symbol_token->length);
- return NULL;
- }
+ onyx_report_error(directive_token->pos, "unknown directive '#%b'.", symbol_token->text, symbol_token->length);
+ return;
}
}
}
expect_token(parser, ';');
- return NULL;
+ return;
+
+submit_binding_to_entities:
+ {
+ if (!binding) return;
+
+ Scope* target_scope = parser->package->scope;
+
+ if (binding->node->flags & Ast_Flag_Private_Package)
+ target_scope = parser->package->private_scope;
+ if (binding->node->flags & Ast_Flag_Private_File)
+ target_scope = parser->file_scope;
+
+ ENTITY_SUBMIT_IN_SCOPE(binding, target_scope);
+ }
}
static AstPackage* parse_package_name(OnyxParser* parser) {
parser.prev = NULL;
parser.hit_unexpected_token = 0;
parser.scope_stack = NULL;
+ parser.static_if_stack = NULL;
parser.polymorph_context = (PolymorphicContext) {
.root_node = NULL,
};
bh_arr_new(global_heap_allocator, parser.scope_stack, 4);
+ bh_arr_new(global_heap_allocator, parser.static_if_stack, 4);
return parser;
}
ENTITY_SUBMIT(implicit_use_builtin);
while (parser->curr->type != Token_Type_End_Stream) {
- if (parser->hit_unexpected_token) return;
-
- AstNode* curr_stmt = parse_top_level_statement(parser);
-
- if (curr_stmt != NULL && curr_stmt != &error_node) {
- while (curr_stmt != NULL) {
- if (parser->hit_unexpected_token) return;
-
- switch (curr_stmt->kind) {
- case Ast_Kind_Binding: {
- Scope* target_scope = parser->package->scope;
-
- if (((AstBinding *) curr_stmt)->node->flags & Ast_Flag_Private_Package)
- target_scope = parser->package->private_scope;
- if (((AstBinding *) curr_stmt)->node->flags & Ast_Flag_Private_File)
- target_scope = parser->file_scope;
-
- ENTITY_SUBMIT_IN_SCOPE(curr_stmt, target_scope);
- break;
- }
-
- default: assert(("Invalid top level node", 0));
- }
-
- curr_stmt = curr_stmt->next;
- }
- }
+ if (parser->hit_unexpected_token) break;
+ if (onyx_has_errors()) break;
+ parse_top_level_statement(parser);
}
bh_arr_pop(parser->scope_stack);
static Package* curr_package = NULL;
static AstFunction* curr_function = NULL;
bh_arr(AstBlock *) block_stack = NULL;
+static b32 report_unresolved_symbols = 1;
AstType* symres_type(AstType* type);
static void symres_local(AstLocal** local, b32 add_to_block_locals);
static void symres_memres_type(AstMemRes** memres);
static void symres_memres(AstMemRes** memres);
static void symres_struct_defaults(AstType* st);
+static void symres_static_if(AstStaticIf* static_if);
static void scope_enter(Scope* new_scope) {
curr_scope = new_scope;
curr_scope = curr_scope->parent;
}
+static void symres_symbol(AstNode** symbol_node) {
+ OnyxToken* token = (*symbol_node)->token;
+ AstNode* res = symbol_resolve(curr_scope, token);
+
+ if (!res) { // :SymresStall
+ onyx_report_error(token->pos,
+ "Unable to resolve symbol '%b'",
+ token->text,
+ token->length);
+ } else {
+ *symbol_node = res;
+ }
+}
+
AstType* symres_type(AstType* type) {
if (type == NULL) return NULL;
}
if (type->kind == Ast_Kind_Symbol) {
- return (AstType *) symbol_resolve(curr_scope, ((AstNode *) type)->token);
+ symres_symbol((AstNode **) &type);
+ return type;
}
if (type->kind == Ast_Kind_Field_Access) {
}
switch ((*expr)->kind) {
- case Ast_Kind_Symbol:
- *expr = (AstTyped *) symbol_resolve(curr_scope, ((AstNode *) *expr)->token);
- break;
+ case Ast_Kind_Symbol: symres_symbol((AstNode **) expr); break;
case Ast_Kind_Binary_Op:
symres_expression(&((AstBinaryOp *)(*expr))->left);
bh_arr_each(AstAlias *, alias, package->only) {
AstNode* thing = symbol_resolve(p->scope, (*alias)->token);
- if (thing == NULL) {
- onyx_report_error((*alias)->token->pos, "not found in package");
+ if (thing == NULL) { // :SymresStall
+ onyx_report_error((*alias)->token->pos, "This symbol was not found in this package.");
return;
}
}
static void symres_enum(AstEnumType* enum_node) {
- if (enum_node->backing->kind == Ast_Kind_Symbol) {
- enum_node->backing = (AstType *) symbol_resolve(curr_scope, enum_node->backing->token);
- }
+ if (enum_node->backing->kind == Ast_Kind_Symbol) symres_symbol((AstNode **) &enum_node->backing);
if (enum_node->backing == NULL) return;
enum_node->backing_type = type_build_from_ast(context.ast_alloc, enum_node->backing);
}
}
+static void symres_static_if(AstStaticIf* static_if) {
+ symres_expression(&static_if->cond);
+}
+
void symres_entity(Entity* ent) {
if (block_stack == NULL)
bh_arr_new(global_heap_allocator, block_stack, 16);
next_state = Entity_State_Finalized;
break;
}
+
+ case Entity_Type_Static_If: {
+ symres_static_if(ent->static_if);
+ next_state = Entity_State_Comptime_Check_Types;
+ break;
+ }
case Entity_Type_Foreign_Function_Header:
case Entity_Type_Function_Header: symres_function_header(ent->function); break;
AstNode* symbol_resolve(Scope* start_scope, OnyxToken* tkn) {
token_toggle_end(tkn);
AstNode* res = symbol_raw_resolve(start_scope, tkn->text);
-
- if (res == NULL) {
- onyx_report_error(tkn->pos, "Unable to resolve symbol '%s'.", tkn->text);
- token_toggle_end(tkn);
- return &empty_node;
- }
-
token_toggle_end(tkn);
+
return res;
}