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);
void entity_bring_to_state(Entity* ent, EntityState state);
void symres_entity(Entity* ent);
#include "onyxerrors.h"
#include "onyxastnodes.h"
-typedef struct NodeToProcess {
- Scope *scope;
- Package *package;
- AstNode *node;
-} NodeToProcess;
-
-typedef struct ParseResults {
- // NOTE: The allocator used to make the arrays below
- bh_allocator allocator;
-
- // NOTE: Contains all the nodes that will need some processing (symbol resolution, type checking)
- bh_arr(NodeToProcess) nodes_to_process;
-} ParseResults;
-
typedef struct PolymorphicContext {
AstType* root_node;
bh_arr(AstPolyParam)* poly_params;
OnyxToken *prev;
OnyxToken *curr;
- ParseResults results;
-
PolymorphicContext polymorph_context;
bh_arr(Scope *) scope_stack;
void* onyx_ast_node_new(bh_allocator alloc, i32 size, AstKind kind);
OnyxParser onyx_parser_create(bh_allocator alloc, OnyxTokenizer *tokenizer);
void onyx_parser_free(OnyxParser* parser);
-ParseResults onyx_parse(OnyxParser *parser);
+void onyx_parse(OnyxParser *parser);
#endif // #ifndef ONYXPARSER_H
#undef DIR_SEPARATOR
}
-static ParseResults parse_source_file(bh_file_contents* file_contents) {
+static void parse_source_file(bh_file_contents* file_contents) {
// :Remove passing the allocators as parameters
OnyxTokenizer tokenizer = onyx_tokenizer_create(context.token_alloc, file_contents);
onyx_lex_tokens(&tokenizer);
OnyxParser parser = onyx_parser_create(context.ast_alloc, &tokenizer);
- return onyx_parse(&parser);
-}
-
-static void merge_parse_results(ParseResults* results) {
- Entity ent;
- bh_arr_each(NodeToProcess, n, results->nodes_to_process) {
- AstNode* node = n->node;
- AstKind nkind = node->kind;
-
- ent.state = Entity_State_Resolve_Symbols;
- ent.package = n->package;
- ent.scope = n->scope;
-
- switch (nkind) {
- case Ast_Kind_Load_File: {
- ent.state = Entity_State_Parse;
- ent.type = Entity_Type_Load_File;
- ent.include = (AstInclude *) node;
- entity_heap_insert(&context.entities, ent);
- break;
- }
-
- case Ast_Kind_Load_Path: {
- ent.state = Entity_State_Parse;
- ent.type = Entity_Type_Load_Path;
- ent.include = (AstInclude *) node;
- entity_heap_insert(&context.entities, ent);
- break;
- }
-
- case Ast_Kind_Function: {
- if ((node->flags & Ast_Flag_Foreign) != 0) {
- ent.type = Entity_Type_Foreign_Function_Header;
- ent.function = (AstFunction *) node;
- entity_heap_insert(&context.entities, ent);
-
- } else {
- ent.type = Entity_Type_Function_Header;
- ent.function = (AstFunction *) node;
- entity_heap_insert(&context.entities, ent);
-
- ent.type = Entity_Type_Function;
- ent.function = (AstFunction *) node;
- entity_heap_insert(&context.entities, ent);
- }
- break;
- }
-
- case Ast_Kind_Overloaded_Function: {
- ent.type = Entity_Type_Overloaded_Function;
- ent.overloaded_function = (AstOverloadedFunction *) node;
- entity_heap_insert(&context.entities, ent);
- break;
- }
-
- case Ast_Kind_Global: {
- if ((node->flags & Ast_Flag_Foreign) != 0) {
- ent.type = Entity_Type_Foreign_Global_Header;
- ent.global = (AstGlobal *) node;
- entity_heap_insert(&context.entities, ent);
-
- } else {
- ent.type = Entity_Type_Global_Header;
- ent.global = (AstGlobal *) node;
- entity_heap_insert(&context.entities, ent);
-
- ent.type = Entity_Type_Global;
- ent.global = (AstGlobal *) node;
- entity_heap_insert(&context.entities, ent);
- }
- break;
- }
-
- case Ast_Kind_StrLit: {
- ent.type = Entity_Type_String_Literal;
- ent.strlit = (AstStrLit *) node;
- entity_heap_insert(&context.entities, ent);
- break;
- }
-
- case Ast_Kind_File_Contents: {
- ent.type = Entity_Type_File_Contents;
- ent.file_contents = (AstFileContents *) node;
- entity_heap_insert(&context.entities, ent);
- break;
- }
-
- case Ast_Kind_Struct_Type: {
- ent.type = Entity_Type_Struct_Member_Default;
- ent.type_alias = (AstType *) node;
- entity_heap_insert(&context.entities, ent);
- // fallthrough
- }
-
- case Ast_Kind_Poly_Struct_Type:
- case Ast_Kind_Type_Alias: {
- ent.type = Entity_Type_Type_Alias;
- ent.type_alias = (AstType *) node;
- entity_heap_insert(&context.entities, ent);
- break;
- }
-
- case Ast_Kind_Enum_Type: {
- ent.type = Entity_Type_Enum;
- ent.enum_type = (AstEnumType *) node;
- entity_heap_insert(&context.entities, ent);
- break;
- }
-
- case Ast_Kind_Use_Package: {
- ent.type = Entity_Type_Use_Package;
- ent.use_package = (AstUsePackage *) node;
- entity_heap_insert(&context.entities, ent);
- break;
- }
-
- case Ast_Kind_Use: {
- ent.type = Entity_Type_Use;
- ent.use = (AstUse *) node;
- entity_heap_insert(&context.entities, ent);
- break;
- }
-
- case Ast_Kind_Memres: {
- ent.type = Entity_Type_Memory_Reservation_Type;
- ent.mem_res = (AstMemRes *) node;
- entity_heap_insert(&context.entities, ent);
-
- ent.type = Entity_Type_Memory_Reservation;
- ent.mem_res = (AstMemRes *) node;
- entity_heap_insert(&context.entities, ent);
- break;
- }
-
- case Ast_Kind_Polymorphic_Proc: {
- ent.type = Entity_Type_Polymorphic_Proc;
- ent.poly_proc = (AstPolyProc *) node;
- entity_heap_insert(&context.entities, ent);
- break;
- }
-
- default: {
- ent.type = Entity_Type_Expression;
- ent.expr = (AstTyped *) node;
- entity_heap_insert(&context.entities, ent);
- break;
- }
- }
- }
+ onyx_parse(&parser);
+ onyx_parser_free(&parser);
}
static CompilerProgress process_source_file(char* filename) {
bh_printf("Processing source file: %s (%d bytes)\n", file.filename, fc.length);
}
- ParseResults results = parse_source_file(&fc);
- merge_parse_results(&results);
-
+ parse_source_file(&fc);
+
if (onyx_has_errors()) {
return ONYX_COMPILER_PROGRESS_FAILED_PARSE;
} else {
bh_arr_pop(entities->entities);
eh_shift_down(entities, 0);
}
+
+// NOTE(Brendan Hansen): Uses the entity heap in the context structure
+void add_entities_for_node(AstNode* node, Scope* scope, Package* package) {
+ EntityHeap* entities = &context.entities;
+
+ Entity ent;
+ ent.state = Entity_State_Resolve_Symbols;
+ ent.package = package;
+ ent.scope = scope;
+
+ switch (node->kind) {
+ case Ast_Kind_Load_File: {
+ ent.state = Entity_State_Parse;
+ ent.type = Entity_Type_Load_File;
+ ent.include = (AstInclude *) node;
+ entity_heap_insert(entities, ent);
+ break;
+ }
+
+ case Ast_Kind_Load_Path: {
+ ent.state = Entity_State_Parse;
+ ent.type = Entity_Type_Load_Path;
+ ent.include = (AstInclude *) node;
+ entity_heap_insert(entities, ent);
+ break;
+ }
+
+ case Ast_Kind_Function: {
+ if ((node->flags & Ast_Flag_Foreign) != 0) {
+ ent.type = Entity_Type_Foreign_Function_Header;
+ ent.function = (AstFunction *) node;
+ entity_heap_insert(entities, ent);
+
+ } else {
+ ent.type = Entity_Type_Function_Header;
+ ent.function = (AstFunction *) node;
+ entity_heap_insert(entities, ent);
+
+ ent.type = Entity_Type_Function;
+ ent.function = (AstFunction *) node;
+ entity_heap_insert(entities, ent);
+ }
+ break;
+ }
+
+ case Ast_Kind_Overloaded_Function: {
+ ent.type = Entity_Type_Overloaded_Function;
+ ent.overloaded_function = (AstOverloadedFunction *) node;
+ entity_heap_insert(entities, ent);
+ break;
+ }
+
+ case Ast_Kind_Global: {
+ if ((node->flags & Ast_Flag_Foreign) != 0) {
+ ent.type = Entity_Type_Foreign_Global_Header;
+ ent.global = (AstGlobal *) node;
+ entity_heap_insert(entities, ent);
+
+ } else {
+ ent.type = Entity_Type_Global_Header;
+ ent.global = (AstGlobal *) node;
+ entity_heap_insert(entities, ent);
+
+ ent.type = Entity_Type_Global;
+ ent.global = (AstGlobal *) node;
+ entity_heap_insert(entities, ent);
+ }
+ break;
+ }
+
+ case Ast_Kind_StrLit: {
+ ent.type = Entity_Type_String_Literal;
+ ent.strlit = (AstStrLit *) node;
+ entity_heap_insert(entities, ent);
+ break;
+ }
+
+ case Ast_Kind_File_Contents: {
+ ent.type = Entity_Type_File_Contents;
+ ent.file_contents = (AstFileContents *) node;
+ entity_heap_insert(entities, ent);
+ break;
+ }
+
+ case Ast_Kind_Struct_Type: {
+ ent.type = Entity_Type_Struct_Member_Default;
+ ent.type_alias = (AstType *) node;
+ entity_heap_insert(entities, ent);
+ // fallthrough
+ }
+
+ case Ast_Kind_Poly_Struct_Type:
+ case Ast_Kind_Type_Alias: {
+ ent.type = Entity_Type_Type_Alias;
+ ent.type_alias = (AstType *) node;
+ entity_heap_insert(entities, ent);
+ break;
+ }
+
+ case Ast_Kind_Enum_Type: {
+ ent.type = Entity_Type_Enum;
+ ent.enum_type = (AstEnumType *) node;
+ entity_heap_insert(entities, ent);
+ break;
+ }
+
+ case Ast_Kind_Use_Package: {
+ ent.type = Entity_Type_Use_Package;
+ ent.use_package = (AstUsePackage *) node;
+ entity_heap_insert(entities, ent);
+ break;
+ }
+
+ case Ast_Kind_Use: {
+ ent.type = Entity_Type_Use;
+ ent.use = (AstUse *) node;
+ entity_heap_insert(entities, ent);
+ break;
+ }
+
+ case Ast_Kind_Memres: {
+ ent.type = Entity_Type_Memory_Reservation_Type;
+ ent.mem_res = (AstMemRes *) node;
+ entity_heap_insert(entities, ent);
+
+ ent.type = Entity_Type_Memory_Reservation;
+ ent.mem_res = (AstMemRes *) node;
+ entity_heap_insert(entities, ent);
+ break;
+ }
+
+ case Ast_Kind_Polymorphic_Proc: {
+ ent.type = Entity_Type_Polymorphic_Proc;
+ ent.poly_proc = (AstPolyProc *) node;
+ entity_heap_insert(entities, ent);
+ break;
+ }
+
+ default: {
+ ent.type = Entity_Type_Expression;
+ ent.expr = (AstTyped *) node;
+ entity_heap_insert(entities, ent);
+ break;
+ }
+ }
+}
\ No newline at end of file
// having to allocate the temporary array for the parse results.
// Things that need to be cleaned up in the parser:
-// - add_node_to_process
// - control block local variables should be more extensible and reuse more code
#include "onyxlex.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 peek_token(ahead) (parser->curr + ahead)
+#define ENTITY_SUBMIT(node) (add_entities_for_node((AstNode *) (node), bh_arr_last(parser->scope_stack), parser->package))
static AstNode error_node = { Ast_Kind_Error, 0, NULL, NULL };
}
}
-// CLEANUP: Currently, this procedure uses 'parser->file_scope' as the scope for the Entity.
-// Except when there is a block stack; in that case, it uses the top of the block stack. I
-// think there should just be a scope stack that is automatically handled.
-static void add_node_to_process(OnyxParser* parser, AstNode* node) {
- Scope* scope = bh_arr_last(parser->scope_stack);
- assert(scope);
-
- bh_arr_push(parser->results.nodes_to_process, ((NodeToProcess) {
- .package = parser->package,
- .scope = scope,
- .node = node,
- }));
-}
// TODO: Make parsing numeric literals not rely on the C standard libary.
str_node->token = expect_token(parser, Token_Type_Literal_String);
str_node->addr = 0;
str_node->flags |= Ast_Flag_Comptime;
-
- add_node_to_process(parser, (AstNode *) str_node);
-
+
+ ENTITY_SUBMIT(str_node);
+
retval = (AstTyped *) str_node;
break;
}
fc->token = parser->prev - 1;
fc->filename = expect_token(parser, Token_Type_Literal_String);
fc->type = type_make_slice(parser->allocator, &basic_types[Basic_Kind_U8]);
-
- add_node_to_process(parser, (AstNode *) fc);
-
+
+ ENTITY_SUBMIT(fc);
+
retval = (AstTyped *) fc;
break;
}
AstStrLit* filename = make_node(AstStrLit, Ast_Kind_StrLit);
filename->token = str_token;
filename->addr = 0;
-
- add_node_to_process(parser, (AstNode *) filename);
+
+ ENTITY_SUBMIT(filename);
retval = (AstTyped *) filename;
break;
}
if (parser->curr->type != '}')
expect_token(parser, ',');
}
-
- add_node_to_process(parser, (AstNode *) ofunc);
+
+ ENTITY_SUBMIT(ofunc);
return (AstFunction *) ofunc;
}
pp->token = func_def->token;
pp->poly_params = polymorphic_vars;
pp->base_func = func_def;
-
- add_node_to_process(parser, (AstNode *) pp);
-
+
+ ENTITY_SUBMIT(pp);
return (AstFunction *) pp;
} else {
bh_arr_free(polymorphic_vars);
-
- add_node_to_process(parser, (AstNode *) func_def);
+
+ ENTITY_SUBMIT(func_def);
return func_def;
}
}
}
global_node->type_node = parse_type(parser);
-
- add_node_to_process(parser, (AstNode *) global_node);
+
+ ENTITY_SUBMIT(global_node);
return (AstTyped *) global_node;
}
node->token = symbol;
}
- // HACK
- add_node_to_process(parser, (AstNode *) node);
+ // HACK: This should maybe be entered elsewhere?
+ ENTITY_SUBMIT(node);
}
AstBinding* binding = make_node(AstBinding, Ast_Kind_Binding);
switch ((u16) parser->curr->type) {
case Token_Type_Keyword_Use: {
AstNode* use_node = parse_use_stmt(parser);
- add_node_to_process(parser, use_node);
+ ENTITY_SUBMIT(use_node);
return NULL;
}
memres->initial_value = parse_expression(parser, 1);
memres->flags |= private_kind;
-
- add_node_to_process(parser, (AstNode *) memres);
-
+
+ ENTITY_SUBMIT(memres);
+
AstBinding* binding = make_node(AstBinding, Ast_Kind_Binding);
binding->token = symbol;
binding->node = (AstNode *) memres;
include->name = bh_strdup(parser->allocator, str_token->text);
token_toggle_end(str_token);
}
-
- return (AstNode *) include;
+
+ ENTITY_SUBMIT(include);
+ return NULL;
}
else if (parse_possible_directive(parser, "load_path")) {
AstInclude* include = make_node(AstInclude, Ast_Kind_Load_Path);
include->name = bh_strdup(parser->allocator, str_token->text);
token_toggle_end(str_token);
}
-
- return (AstNode *) include;
+
+ ENTITY_SUBMIT(include);
+ return NULL;
}
else {
OnyxToken* directive_token = expect_token(parser, '#');
parser.hit_unexpected_token = 0;
parser.scope_stack = NULL;
- parser.results = (ParseResults) {
- .allocator = global_heap_allocator,
-
- .nodes_to_process = NULL,
- };
-
parser.polymorph_context = (PolymorphicContext) {
.root_node = NULL,
.poly_params = NULL,
};
bh_arr_new(global_heap_allocator, parser.scope_stack, 4);
- bh_arr_new(parser.results.allocator, parser.results.nodes_to_process, 4);
return parser;
}
bh_arr_free(parser->scope_stack);
}
-ParseResults onyx_parse(OnyxParser *parser) {
+void onyx_parse(OnyxParser *parser) {
// NOTE: Skip comments at the beginning of the file
while (consume_token_if_next(parser, Token_Type_Comment));
AstUsePackage* implicit_use_builtin = make_node(AstUsePackage, Ast_Kind_Use_Package);
implicit_use_builtin->package = (AstPackage *) &builtin_package_node;
- add_node_to_process(parser, (AstNode *) implicit_use_builtin);
-
+ ENTITY_SUBMIT(implicit_use_builtin);
+
while (parser->curr->type != Token_Type_End_Stream) {
- if (parser->hit_unexpected_token) return parser->results;
+ 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 parser->results;
+ if (parser->hit_unexpected_token) return;
switch (curr_stmt->kind) {
- case Ast_Kind_Load_File:
- case Ast_Kind_Load_Path:
- add_node_to_process(parser, curr_stmt);
- break;
-
case Ast_Kind_Binding: {
Scope* target_scope = parser->package->scope;
}
bh_arr_pop(parser->scope_stack);
- return parser->results;
}