Everything is now part of a global "Context" that everything has access to.
@echo off
-set SOURCE_FILES=src/onyx.c src/onyxastnodes.c src/onyxbuiltins.c src/onyxchecker.c src/onyxclone.c src/onyxdoc.c src/onyxentities.c src/onyxerrors.c src/onyxlex.c src/onyxparser.c src/onyxsempass.c src/onyxsymres.c src/onyxtypes.c src/onyxutils.c src/onyxwasm.c
+set SOURCE_FILES=src/onyx.c src/onyxastnodes.c src/onyxbuiltins.c src/onyxchecker.c src/onyxclone.c src/onyxdoc.c src/onyxentities.c src/onyxerrors.c src/onyxlex.c src/onyxparser.c src/onyxsymres.c src/onyxtypes.c src/onyxutils.c src/onyxwasm.c
if "%1" == "1" (
set FLAGS=/O2 /MT /Z7
#!/bin/sh
-C_FILES="onyx onyxastnodes onyxbuiltins onyxchecker onyxclone onyxdoc onyxentities onyxerrors onyxlex onyxparser onyxsempass onyxsymres onyxtypes onyxutils onyxwasm"
+C_FILES="onyx onyxastnodes onyxbuiltins onyxchecker onyxclone onyxdoc onyxentities onyxerrors onyxlex onyxparser onyxsymres onyxtypes onyxutils onyxwasm"
TARGET='./bin/onyx'
CC='gcc'
Scope *private_scope;
};
-// NOTE: Simple data structure for storing what comes out of the parser
-typedef struct ProgramInfo {
- Scope *global_scope;
+typedef enum CompileAction CompileAction;
+enum CompileAction {
+ ONYX_COMPILE_ACTION_COMPILE,
+ ONYX_COMPILE_ACTION_DOCUMENT,
+ ONYX_COMPILE_ACTION_PRINT_HELP,
+};
+
+typedef struct CompileOptions CompileOptions;
+struct CompileOptions {
+ bh_allocator allocator;
+ CompileAction action;
+
+ u32 verbose_output : 31;
+ u32 fun_output : 1;
+
+ bh_arr(const char *) included_folders;
+ bh_arr(const char *) files;
+ const char* target_file;
+};
+typedef struct Context Context;
+struct Context {
bh_table(Package *) packages;
EntityHeap entities;
- u32 foreign_global_count;
-} ProgramInfo;
+ Scope *global_scope;
+
+ CompileOptions* options;
+
+ bh_arena token_arena, ast_arena;
+ bh_allocator token_alloc, ast_alloc;
+
+ bh_arr(bh_file_contents) loaded_files;
+};
+
+extern Context context;
// NOTE: Basic internal types constructed in the parser
extern AstBasicType basic_type_void;
extern bh_arr(AstTyped *) operator_overloads[Binary_Op_Count];
-void initialize_builtins(bh_allocator a, ProgramInfo* prog);
+void initialize_builtins(bh_allocator a);
// NOTE: Useful not inlined functions
bh_arr(DocPackage) package_docs;
} OnyxDocumentation;
-OnyxDocumentation onyx_docs_generate(ProgramInfo* prog);
+OnyxDocumentation onyx_docs_generate();
void onyx_docs_emit(OnyxDocumentation* doc);
#endif
#include <stdarg.h>
-#define ONYX_ERR_BUFFER_SIZE 256
-
typedef struct OnyxError {
OnyxFilePos pos;
char *text;
bh_arena msg_arena;
bh_allocator msg_alloc;
- // NOTE: Pointer to a table mapping file paths to
- // their file contents. Used for better error messages
- bh_table(bh_file_contents)* file_contents;
+ // NOTE: Pointer to a array of all the loaded files.
+ bh_arr(bh_file_contents)* file_contents;
bh_arr(OnyxError) errors;
} OnyxErrors;
extern OnyxErrors msgs;
-void onyx_errors_init(bh_table(bh_file_contents)* files);
+void onyx_errors_init(bh_arr(bh_file_contents)* files);
void onyx_report_error(OnyxFilePos pos, char * format, ...);
void onyx_errors_print();
b32 onyx_has_errors();
typedef struct OnyxParser {
bh_allocator allocator;
- ProgramInfo *program;
Package *package;
Scope *file_scope;
const char* onyx_ast_node_kind_string(AstKind kind);
void* onyx_ast_node_new(bh_allocator alloc, i32 size, AstKind kind);
-OnyxParser onyx_parser_create(bh_allocator alloc, OnyxTokenizer *tokenizer, ProgramInfo *program);
+OnyxParser onyx_parser_create(bh_allocator alloc, OnyxTokenizer *tokenizer);
void onyx_parser_free(OnyxParser* parser);
ParseResults onyx_parse(OnyxParser *parser);
+++ /dev/null
-#ifndef ONYXSEMPASS_H
-#define ONYXSEMPASS_H
-
-#include "bh.h"
-
-#include "onyxlex.h"
-#include "onyxastnodes.h"
-#include "onyxerrors.h"
-
-typedef struct SemState {
- // NOTE: Adding node_allocator in case we need
- // to make any more node in the tree
- bh_allocator allocator, node_allocator;
-
- // NOTE: Used wherever
- ProgramInfo* program;
-
- // NOTE: Used in symbol resolution phase
- Package* curr_package;
- Scope* global_scope;
- Scope* curr_scope;
- AstFunction* curr_function;
- bh_arr(AstBlock *) block_stack;
-
- // NOTE: Used in type checking phase
- Type* expected_return_type;
-
- u32 defer_allowed : 1;
-} SemState;
-
-extern SemState semstate;
-
-AstType* symres_type(AstType* type);
-
-// TODO: This should be moved elsewhere.
-void onyx_sempass_init(bh_allocator alloc, bh_allocator node_alloc);
-
-#endif
const char* onyx_ast_node_kind_string(AstKind kind);
-void program_info_init(ProgramInfo* prog, bh_allocator alloc);
-Package* program_info_package_lookup(ProgramInfo* prog, char* package_name);
-Package* program_info_package_lookup_or_create(ProgramInfo* prog, char* package_name, Scope* parent_scope, bh_allocator alloc);
+Package* package_lookup(char* package_name);
+Package* package_lookup_or_create(char* package_name, Scope* parent_scope, bh_allocator alloc);
void scope_include(Scope* target, Scope* source, OnyxFilePos pos);
b32 symbol_introduce(Scope* scope, OnyxToken* tkn, AstNode* symbol);
extern OnyxWasmModule global_wasm_module;
OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc);
-void onyx_wasm_module_compile(OnyxWasmModule* module, ProgramInfo* program);
+void onyx_wasm_module_compile(OnyxWasmModule* module);
void onyx_wasm_module_free(OnyxWasmModule* module);
void onyx_wasm_module_write_to_file(OnyxWasmModule* module, bh_file file);
#include "onyxlex.h"
#include "onyxerrors.h"
#include "onyxparser.h"
-#include "onyxsempass.h"
#include "onyxutils.h"
#include "onyxwasm.h"
#include "onyxdoc.h"
+Context context;
+
static const char* docstring = "Onyx compiler version " VERSION "\n"
"\n"
"\t-o <target_file> Specify the target file (default: out.wasm)\n"
"\t--verbose Verbose output\n";
-typedef enum CompileAction {
- ONYX_COMPILE_ACTION_COMPILE,
- ONYX_COMPILE_ACTION_DOCUMENT,
- ONYX_COMPILE_ACTION_PRINT_HELP,
-} CompileAction;
-
-typedef struct OnyxCompileOptions {
- bh_allocator allocator;
- CompileAction action;
-
- u32 verbose_output : 2;
- u32 fun_output : 1;
-
- bh_arr(const char *) included_folders;
- bh_arr(const char *) files;
- const char* target_file;
-} OnyxCompileOptions;
-
-static OnyxCompileOptions compile_opts_parse(bh_allocator alloc, int argc, char *argv[]) {
- OnyxCompileOptions options = {
+static CompileOptions compile_opts_parse(bh_allocator alloc, int argc, char *argv[]) {
+ CompileOptions options = {
.allocator = alloc,
.action = ONYX_COMPILE_ACTION_PRINT_HELP,
return options;
}
-static void compile_opts_free(OnyxCompileOptions* opts) {
+static void compile_opts_free(CompileOptions* opts) {
bh_arr_free(opts->files);
bh_arr_free(opts->included_folders);
}
ONYX_COMPILER_PROGRESS_SUCCESS
} CompilerProgress;
-typedef struct CompilerState {
- OnyxCompileOptions* options;
-
- bh_arena ast_arena, sp_arena;
- bh_allocator token_alloc, ast_alloc, sp_alloc;
-
- bh_table(bh_file_contents) loaded_files;
-
- ProgramInfo prog_info;
-} CompilerState;
-
-static char* lookup_included_file(CompilerState* cs, char* filename);
+static char* lookup_included_file(char* filename);
static AstInclude* create_load(bh_allocator alloc, char* filename) {
AstInclude* include_node = onyx_ast_node_new(alloc, sizeof(AstInclude), Ast_Kind_Load_File);
return include_node;
}
-static void compiler_state_init(CompilerState* compiler_state, OnyxCompileOptions* opts) {
- compiler_state->options = opts;
+static void context_init(CompileOptions* opts) {
+ context.options = opts;
- program_info_init(&compiler_state->prog_info, global_heap_allocator);
+ context.global_scope = scope_create(global_heap_allocator, NULL, (OnyxFilePos) { 0 });
+ bh_table_init(global_heap_allocator, context.packages, 16);
- bh_table_init(opts->allocator, compiler_state->loaded_files, 15);
- onyx_errors_init(&compiler_state->loaded_files);
+ // NOTE: This will be initialized upon the first call to entity_heap_insert.
+ context.entities.entities = NULL;
- compiler_state->token_alloc = opts->allocator;
+ onyx_errors_init(&context.loaded_files);
- // NOTE: Create the arena where AST nodes will exist
+ // NOTE: Create the arena where tokens and AST nodes will exist
// Prevents nodes from being scattered across memory due to fragmentation
- bh_arena_init(&compiler_state->ast_arena, opts->allocator, 16 * 1024 * 1024); // 16MB
- compiler_state->ast_alloc = bh_arena_allocator(&compiler_state->ast_arena);
-
- bh_arena_init(&compiler_state->sp_arena, opts->allocator, 16 * 1024);
- compiler_state->sp_alloc = bh_arena_allocator(&compiler_state->sp_arena);
+ bh_arena_init(&context.token_arena, global_heap_allocator, 16 * 1024 * 1024); // 16MB
+ context.token_alloc = bh_arena_allocator(&context.token_arena);
- onyx_sempass_init(compiler_state->sp_alloc, compiler_state->ast_alloc);
+ bh_arena_init(&context.ast_arena, global_heap_allocator, 16 * 1024 * 1024); // 16MB
+ context.ast_alloc = bh_arena_allocator(&context.ast_arena);
// HACK
- global_wasm_module = onyx_wasm_module_create(compiler_state->options->allocator);
+ // MOVE TO CONTEXT
+ global_wasm_module = onyx_wasm_module_create(context.options->allocator);
// NOTE: Add builtin entities to pipeline.
- entity_heap_insert(&compiler_state->prog_info.entities, ((Entity) {
+ entity_heap_insert(&context.entities, ((Entity) {
.state = Entity_State_Parse_Builtin,
.type = Entity_Type_Load_File,
.package = NULL,
- .include = create_load(compiler_state->sp_alloc, "core/builtin"),
+ .include = create_load(context.ast_alloc, "core/builtin"),
}));
- entity_heap_insert(&compiler_state->prog_info.entities, ((Entity) {
+ entity_heap_insert(&context.entities, ((Entity) {
.state = Entity_State_Resolve_Symbols,
.type = Entity_Type_Global_Header,
.global = &builtin_stack_top
}));
- entity_heap_insert(&compiler_state->prog_info.entities, ((Entity) {
+ entity_heap_insert(&context.entities, ((Entity) {
.state = Entity_State_Resolve_Symbols,
.type = Entity_Type_Global,
.global = &builtin_stack_top
// NOTE: Add all files passed by command line to the queue
bh_arr_each(const char *, filename, opts->files) {
- entity_heap_insert(&compiler_state->prog_info.entities, ((Entity) {
+ entity_heap_insert(&context.entities, ((Entity) {
.state = Entity_State_Parse,
.type = Entity_Type_Load_File,
.package = NULL,
- .include = create_load(compiler_state->sp_alloc, (char *) *filename),
+ .include = create_load(context.ast_alloc, (char *) *filename),
}));
}
}
-static void compiler_state_free(CompilerState* cs) {
- bh_arena_free(&cs->ast_arena);
- bh_arena_free(&cs->sp_arena);
- bh_table_free(cs->loaded_files);
+static void context_free() {
+ bh_arena_free(&context.ast_arena);
+ bh_arr_free(context.loaded_files);
- compile_opts_free(cs->options);
+ compile_opts_free(context.options);
}
// NOTE: This should not be called until immediately before using the return value.
// This function can return a static variable which will change if this is called
// another time. -brendanfh 2020/10/09
-static char* lookup_included_file(CompilerState* cs, char* filename) {
+static char* lookup_included_file(char* filename) {
static char path[256];
fori (i, 0, 256) path[i] = 0;
fori (i, 0, 128) if (fn[i] == '/') fn[i] = DIR_SEPARATOR;
- bh_arr_each(const char *, folder, cs->options->included_folders) {
+ bh_arr_each(const char *, folder, context.options->included_folders) {
if ((*folder)[strlen(*folder) - 1] != DIR_SEPARATOR)
bh_snprintf(path, 256, "%s%c%s", *folder, DIR_SEPARATOR, fn);
else
#undef DIR_SEPARATOR
}
-static ParseResults parse_source_file(CompilerState* compiler_state, bh_file_contents* file_contents) {
- OnyxTokenizer tokenizer = onyx_tokenizer_create(compiler_state->token_alloc, file_contents);
+static ParseResults 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(compiler_state->ast_alloc, &tokenizer, &compiler_state->prog_info);
+ OnyxParser parser = onyx_parser_create(context.ast_alloc, &tokenizer);
return onyx_parse(&parser);
}
-static void merge_parse_results(CompilerState* compiler_state, ParseResults* results) {
+static void merge_parse_results(ParseResults* results) {
Entity ent;
bh_arr_each(NodeToProcess, n, results->nodes_to_process) {
AstNode* node = n->node;
ent.state = Entity_State_Parse;
ent.type = Entity_Type_Load_File;
ent.include = (AstInclude *) node;
- entity_heap_insert(&compiler_state->prog_info.entities, ent);
+ entity_heap_insert(&context.entities, ent);
break;
}
ent.state = Entity_State_Parse;
ent.type = Entity_Type_Load_Path;
ent.include = (AstInclude *) node;
- entity_heap_insert(&compiler_state->prog_info.entities, ent);
+ entity_heap_insert(&context.entities, ent);
break;
}
if ((node->flags & Ast_Flag_Foreign) != 0) {
ent.type = Entity_Type_Foreign_Function_Header;
ent.function = (AstFunction *) node;
- entity_heap_insert(&compiler_state->prog_info.entities, ent);
+ entity_heap_insert(&context.entities, ent);
} else {
ent.type = Entity_Type_Function_Header;
ent.function = (AstFunction *) node;
- entity_heap_insert(&compiler_state->prog_info.entities, ent);
+ entity_heap_insert(&context.entities, ent);
ent.type = Entity_Type_Function;
ent.function = (AstFunction *) node;
- entity_heap_insert(&compiler_state->prog_info.entities, ent);
+ 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(&compiler_state->prog_info.entities, ent);
+ entity_heap_insert(&context.entities, ent);
break;
}
if ((node->flags & Ast_Flag_Foreign) != 0) {
ent.type = Entity_Type_Foreign_Global_Header;
ent.global = (AstGlobal *) node;
- entity_heap_insert(&compiler_state->prog_info.entities, ent);
+ entity_heap_insert(&context.entities, ent);
} else {
ent.type = Entity_Type_Global_Header;
ent.global = (AstGlobal *) node;
- entity_heap_insert(&compiler_state->prog_info.entities, ent);
+ entity_heap_insert(&context.entities, ent);
ent.type = Entity_Type_Global;
ent.global = (AstGlobal *) node;
- entity_heap_insert(&compiler_state->prog_info.entities, ent);
+ entity_heap_insert(&context.entities, ent);
}
break;
}
case Ast_Kind_StrLit: {
ent.type = Entity_Type_String_Literal;
ent.strlit = (AstStrLit *) node;
- entity_heap_insert(&compiler_state->prog_info.entities, ent);
+ 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(&compiler_state->prog_info.entities, ent);
+ 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(&compiler_state->prog_info.entities, ent);
+ entity_heap_insert(&context.entities, ent);
// fallthrough
}
case Ast_Kind_Type_Alias: {
ent.type = Entity_Type_Type_Alias;
ent.type_alias = (AstType *) node;
- entity_heap_insert(&compiler_state->prog_info.entities, ent);
+ 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(&compiler_state->prog_info.entities, ent);
+ 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(&compiler_state->prog_info.entities, ent);
+ entity_heap_insert(&context.entities, ent);
break;
}
case Ast_Kind_Use: {
ent.type = Entity_Type_Use;
ent.use = (AstUse *) node;
- entity_heap_insert(&compiler_state->prog_info.entities, ent);
+ 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(&compiler_state->prog_info.entities, ent);
+ entity_heap_insert(&context.entities, ent);
ent.type = Entity_Type_Memory_Reservation;
ent.mem_res = (AstMemRes *) node;
- entity_heap_insert(&compiler_state->prog_info.entities, ent);
+ 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(&compiler_state->prog_info.entities, ent);
+ entity_heap_insert(&context.entities, ent);
break;
}
default: {
ent.type = Entity_Type_Expression;
ent.expr = (AstTyped *) node;
- entity_heap_insert(&compiler_state->prog_info.entities, ent);
+ entity_heap_insert(&context.entities, ent);
break;
}
}
}
}
-static CompilerProgress process_source_file(CompilerState* compiler_state, char* filename) {
- if (bh_table_has(bh_file_contents, compiler_state->loaded_files, filename)) return ONYX_COMPILER_PROGRESS_SUCCESS;
+static CompilerProgress process_source_file(char* filename) {
+ bh_arr_each(bh_file_contents, fc, context.loaded_files) {
+ // CLEANUP: Add duplicate resolutions, such as
+ // ./foo and ./test/../foo
+ // should be the same thing.
+ if (!strcmp(fc->filename, filename)) {
+ return ONYX_COMPILER_PROGRESS_SUCCESS;
+ }
+ }
bh_file file;
-
bh_file_error err = bh_file_open(&file, filename);
if (err != BH_FILE_ERROR_NONE) {
// bh_printf_err("Failed to open file %s\n", filename);
return ONYX_COMPILER_PROGRESS_FAILED_READ;
}
- bh_file_contents fc = bh_file_read_contents(compiler_state->token_alloc, &file);
+ bh_file_contents fc = bh_file_read_contents(context.token_alloc, &file);
bh_file_close(&file);
// POTENTIAL BUG: If there are too many files and too many collisions in the table,
// NOTE: Need to reget the value out of the table so token references work
- bh_table_put(bh_file_contents, compiler_state->loaded_files, (char *) filename, fc);
- fc = bh_table_get(bh_file_contents, compiler_state->loaded_files, (char *) filename);
+ bh_arr_push(context.loaded_files, fc);
- if (compiler_state->options->verbose_output == 2) {
+ if (context.options->verbose_output == 2) {
bh_printf("Processing source file: %s (%d bytes)\n", file.filename, fc.length);
}
- ParseResults results = parse_source_file(compiler_state, &fc);
- merge_parse_results(compiler_state, &results);
+ ParseResults results = parse_source_file(&fc);
+ merge_parse_results(&results);
if (onyx_has_errors()) {
return ONYX_COMPILER_PROGRESS_FAILED_PARSE;
}
}
-static b32 process_load_entity(CompilerState* compiler_state, Entity* ent) {
+static b32 process_load_entity(Entity* ent) {
assert(ent->type == Entity_Type_Load_File || ent->type == Entity_Type_Load_Path);
AstInclude* include = ent->include;
if (include->kind == Ast_Kind_Load_File) {
- char* filename = lookup_included_file(compiler_state, include->name);
+ char* filename = lookup_included_file(include->name);
char* formatted_name = bh_strdup(global_heap_allocator, filename);
- process_source_file(compiler_state, formatted_name);
+ process_source_file(formatted_name);
} else if (include->kind == Ast_Kind_Load_Path) {
- bh_arr_push(compiler_state->options->included_folders, include->name);
+ bh_arr_push(context.options->included_folders, include->name);
}
return 1;
}
-static b32 process_entity(CompilerState* compiler_state, Entity* ent) {
+static b32 process_entity(Entity* ent) {
i32 changed = 1;
- if (compiler_state->options->verbose_output == 3) {
+ if (context.options->verbose_output == 3) {
if (ent->expr && ent->expr->token)
printf("%s | %s | %s:%i:%i\n",
entity_state_strings[ent->state],
switch (ent->state) {
case Entity_State_Parse_Builtin:
- process_load_entity(compiler_state, ent);
+ process_load_entity(ent);
ent->state = Entity_State_Finalized;
if (onyx_has_errors()) return 0;
- initialize_builtins(compiler_state->ast_alloc, &compiler_state->prog_info);
- semstate.program = &compiler_state->prog_info;
+ initialize_builtins(context.ast_alloc);
break;
case Entity_State_Parse:
- process_load_entity(compiler_state, ent);
+ process_load_entity(ent);
ent->state = Entity_State_Finalized;
break;
}
// Just having fun with some visual output - brendanfh 2020/12/14
-static void output_dummy_progress_bar(CompilerState* compiler_state) {
- EntityHeap* eh = &compiler_state->prog_info.entities;
+static void output_dummy_progress_bar() {
+ EntityHeap* eh = &context.entities;
printf("\e[2;1H");
for (i32 i = 0; i < Entity_State_Count - 1; i++) {
}
}
-static i32 onyx_compile(CompilerState* compiler_state) {
+static i32 onyx_compile() {
u64 start_time = bh_time_curr();
- if (compiler_state->options->fun_output)
+ if (context.options->fun_output)
printf("\e[2J");
- while (!bh_arr_is_empty(compiler_state->prog_info.entities.entities)) {
- Entity ent = entity_heap_top(&compiler_state->prog_info.entities);
- entity_heap_remove_top(&compiler_state->prog_info.entities);
+ while (!bh_arr_is_empty(context.entities.entities)) {
+ Entity ent = entity_heap_top(&context.entities);
+ entity_heap_remove_top(&context.entities);
if (ent.state == Entity_State_Finalized) continue;
- if (compiler_state->options->fun_output) {
- output_dummy_progress_bar(compiler_state);
+ if (context.options->fun_output) {
+ output_dummy_progress_bar();
// Slowing things down for the effect
#if defined(_BH_WINDOWS)
}
}
- b32 changed = process_entity(compiler_state, &ent);
+ b32 changed = process_entity(&ent);
if (onyx_has_errors()) return ONYX_COMPILER_PROGRESS_ERROR;
// gonna keep this how it is for now. - brendanfh 2020/12/15
// if (changed && ent.state != Entity_State_Finalized)
- entity_heap_insert(&compiler_state->prog_info.entities, ent);
+ entity_heap_insert(&context.entities, ent);
}
// NOTE: Output to file
bh_file output_file;
- if (bh_file_create(&output_file, compiler_state->options->target_file) != BH_FILE_ERROR_NONE) {
+ if (bh_file_create(&output_file, context.options->target_file) != BH_FILE_ERROR_NONE) {
return ONYX_COMPILER_PROGRESS_FAILED_OUTPUT;
}
- if (compiler_state->options->verbose_output)
+ if (context.options->verbose_output)
bh_printf("Outputting to WASM file: %s\n", output_file.filename);
onyx_wasm_module_write_to_file(&global_wasm_module, output_file);
u64 duration = bh_time_duration(start_time);
- if (compiler_state->options->verbose_output > 0) {
+ if (context.options->verbose_output > 0) {
// TODO: Replace these with bh_printf when padded formatting is added.
printf("\nStatistics:\n");
printf(" Time taken: %lf seconds\n", (double) duration / 1000);
bh_managed_heap_init(&global_heap);
global_heap_allocator = bh_managed_heap_allocator(&global_heap);
- OnyxCompileOptions compile_opts = compile_opts_parse(global_heap_allocator, argc, argv);
-
- CompilerState compile_state = { 0 };
- compiler_state_init(&compile_state, &compile_opts);
+ CompileOptions compile_opts = compile_opts_parse(global_heap_allocator, argc, argv);
+ context_init(&compile_opts);
CompilerProgress compiler_progress = ONYX_COMPILER_PROGRESS_FAILED_READ;
-
switch (compile_opts.action) {
case ONYX_COMPILE_ACTION_PRINT_HELP:
// NOTE: This could probably be made better
return 1;
case ONYX_COMPILE_ACTION_COMPILE:
- compiler_progress = onyx_compile(&compile_state);
+ compiler_progress = onyx_compile();
break;
case ONYX_COMPILE_ACTION_DOCUMENT:
break;
}
- compiler_state_free(&compile_state);
+ context_free();
bh_scratch_free(&global_scratch);
bh_managed_heap_free(&global_heap);
#include "onyxastnodes.h"
-#include "onyxsempass.h"
#include "onyxparser.h"
#include "onyxutils.h"
// NOTE: Returns 1 if the conversion was successful.
b32 convert_numlit_to_type(AstNumLit* num, Type* type) {
if (num->type == NULL)
- num->type = type_build_from_ast(semstate.allocator, num->type_node);
+ num->type = type_build_from_ast(context.ast_alloc, num->type_node);
assert(num->type);
if (types_are_compatible(num->type, type)) return 1;
if (!type_check_or_auto_cast(&compound->exprs[i], type->Compound.types[i])) return 0;
}
- compound->type = type_build_compound_type(semstate.node_allocator, compound);
+ compound->type = type_build_compound_type(context.ast_alloc, compound);
return 1;
}
}
if (node->type == NULL)
- node->type = type_build_from_ast(semstate.allocator, node->type_node);
+ node->type = type_build_from_ast(context.ast_alloc, node->type_node);
if (node->kind == Ast_Kind_NumLit && node->type->kind == Type_Kind_Basic) {
if (node->type->Basic.kind == Basic_Kind_Int_Unsized) {
bh_arr(AstTyped *) operator_overloads[Binary_Op_Count] = { 0 };
-void initialize_builtins(bh_allocator a, ProgramInfo* prog) {
+void initialize_builtins(bh_allocator a) {
// HACK
builtin_package_token.text = bh_strdup(global_heap_allocator, builtin_package_token.text);
BuiltinSymbol* bsym = (BuiltinSymbol *) &builtin_symbols[0];
while (bsym->sym != NULL) {
if (bsym->package == NULL)
- symbol_builtin_introduce(prog->global_scope, bsym->sym, bsym->node);
+ symbol_builtin_introduce(context.global_scope, bsym->sym, bsym->node);
else {
- Package* p = program_info_package_lookup_or_create(
- prog,
- bsym->package,
- prog->global_scope,
- a);
+ Package* p = package_lookup_or_create(bsym->package, context.global_scope, a);
assert(p);
symbol_builtin_introduce(p->scope, bsym->sym, bsym->node);
bsym++;
}
- Package* p = program_info_package_lookup_or_create(prog, "builtin", prog->global_scope, a);
+ Package* p = package_lookup_or_create("builtin", context.global_scope, a);
builtin_string_type = (AstType *) symbol_raw_resolve(p->scope, "str");
if (builtin_string_type == NULL) {
#define BH_DEBUG
-#include "onyxsempass.h"
#include "onyxparser.h"
#include "onyxutils.h"
fill_in_poly_call_args(node->type_node);
if (node->type == NULL)
- node->type = type_build_from_ast(semstate.allocator, node->type_node);
+ node->type = type_build_from_ast(context.ast_alloc, node->type_node);
}
+// HACK: This should be baked into a structure, not a global variable.
+static Type* expected_return_type = NULL;
+
CheckStatus check_return(AstReturn* retnode) {
if (retnode->expr) {
CHECK(expression, &retnode->expr);
- if (!type_check_or_auto_cast(&retnode->expr, semstate.expected_return_type)) {
+ if (!type_check_or_auto_cast(&retnode->expr, expected_return_type)) {
onyx_report_error(retnode->token->pos,
"Expected to return a value of type '%s', returning value of type '%s'.",
- type_get_name(semstate.expected_return_type),
+ type_get_name(expected_return_type),
node_get_type_name(retnode->expr));
return Check_Error;
}
} else {
- if (semstate.expected_return_type->Basic.size > 0) {
+ if (expected_return_type->Basic.size > 0) {
onyx_report_error(retnode->token->pos,
"Returning from non-void function without value. Expected a value of type '%s'.",
- type_get_name(semstate.expected_return_type));
+ type_get_name(expected_return_type));
return Check_Error;
}
}
else if (iter_type->kind == Type_Kind_Array) {
can_iterate = 1;
- if (fornode->by_pointer) fornode->var->type = type_make_pointer(semstate.node_allocator, iter_type->Array.elem);
+ if (fornode->by_pointer) fornode->var->type = type_make_pointer(context.ast_alloc, iter_type->Array.elem);
else fornode->var->type = iter_type->Array.elem;
fornode->loop_type = For_Loop_Array;
lhs->exprs[i]->type = binop->right->type->Compound.types[i];
}
- lhs->type = type_build_compound_type(semstate.node_allocator, lhs);
+ lhs->type = type_build_compound_type(context.ast_alloc, lhs);
} else {
binop->left->type = binop->right->type;
else if (binop->operation == Binary_Op_Assign_Shr) operation = Binary_Op_Shr;
else if (binop->operation == Binary_Op_Assign_Sar) operation = Binary_Op_Sar;
- AstBinaryOp* new_right = make_binary_op(semstate.node_allocator, operation, binop->left, binop->right);
+ AstBinaryOp* new_right = make_binary_op(context.ast_alloc, operation, binop->left, binop->right);
new_right->token = binop->token;
CHECK(binaryop, &new_right, 0);
binop->type = &basic_types[Basic_Kind_Bool];
if (binop->flags & Ast_Flag_Comptime) {
// NOTE: Not a binary op
- *pbinop = (AstBinaryOp *) ast_reduce(semstate.node_allocator, (AstTyped *) binop);
+ *pbinop = (AstBinaryOp *) ast_reduce(context.ast_alloc, (AstTyped *) binop);
}
return Check_Success;
if (binop->flags & Ast_Flag_Comptime) {
// NOTE: Not a binary op
- *pbinop = (AstBinaryOp *) ast_reduce(semstate.node_allocator, (AstTyped *) binop);
+ *pbinop = (AstBinaryOp *) ast_reduce(context.ast_alloc, (AstTyped *) binop);
}
return Check_Success;
}
return NULL;
}
- AstCall* implicit_call = onyx_ast_node_new(semstate.node_allocator, sizeof(AstCall), Ast_Kind_Call);
+ AstCall* implicit_call = onyx_ast_node_new(context.ast_alloc, sizeof(AstCall), Ast_Kind_Call);
implicit_call->token = binop->token;
implicit_call->callee = overload;
implicit_call->va_kind = VA_Kind_Not_VA;
bh_arr_each(AstTyped *, arg, args.values)
- *arg = (AstTyped *) make_argument(semstate.node_allocator, *arg);
+ *arg = (AstTyped *) make_argument(context.ast_alloc, *arg);
implicit_call->args = args;
return implicit_call;
resolve_expression_type(binop->right);
if (!type_is_integer(binop->right->type)) goto bad_binaryop;
- AstNumLit* numlit = make_int_literal(semstate.node_allocator, type_size_of(binop->left->type->Pointer.elem));
+ AstNumLit* numlit = make_int_literal(context.ast_alloc, type_size_of(binop->left->type->Pointer.elem));
numlit->token = binop->right->token;
numlit->type = binop->right->type;
- AstBinaryOp* binop_node = make_binary_op(semstate.node_allocator, Binary_Op_Multiply, binop->right, (AstTyped *) numlit);
+ AstBinaryOp* binop_node = make_binary_op(context.ast_alloc, Binary_Op_Multiply, binop->right, (AstTyped *) numlit);
binop_node->token = binop->token;
CHECK(binaryop, &binop_node, 0);
if (binop->flags & Ast_Flag_Comptime) {
// NOTE: Not a binary op
- *pbinop = (AstBinaryOp *) ast_reduce(semstate.node_allocator, (AstTyped *) binop);
+ *pbinop = (AstBinaryOp *) ast_reduce(context.ast_alloc, (AstTyped *) binop);
}
return Check_Success;
if (unaryop->expr->flags & Ast_Flag_Comptime) {
unaryop->flags |= Ast_Flag_Comptime;
// NOTE: Not a unary op
- *punop = (AstUnaryOp *) ast_reduce(semstate.node_allocator, (AstTyped *) unaryop);
+ *punop = (AstUnaryOp *) ast_reduce(context.ast_alloc, (AstTyped *) unaryop);
}
return Check_Success;
fill_in_type((AstTyped *) al);
- al->type = type_make_array(semstate.allocator, al->type, bh_arr_length(al->values));
+ al->type = type_make_array(context.ast_alloc, al->type, bh_arr_length(al->values));
if (al->type == NULL || al->type->kind != Type_Kind_Array) {
onyx_report_error(al->token->pos, "Expected array type for array literal. This is a compiler bug.");
return Check_Error;
CHECK(expression, expr);
}
- compound->type = type_build_compound_type(semstate.node_allocator, compound);
+ compound->type = type_build_compound_type(context.ast_alloc, compound);
return Check_Success;
}
aof->expr->flags |= Ast_Flag_Address_Taken;
- aof->type = type_make_pointer(semstate.allocator, aof->expr->type);
+ aof->type = type_make_pointer(context.ast_alloc, aof->expr->type);
return Check_Success;
}
}
aa->kind = Ast_Kind_Slice;
- aa->type = type_make_slice(semstate.node_allocator, of);
+ aa->type = type_make_slice(context.ast_alloc, of);
aa->elem_size = type_size_of(of);
return Check_Success;
type_lookup_member(aa->addr->type, "data", &smem);
- AstFieldAccess* fa = make_field_access(semstate.node_allocator, aa->addr, "data");
+ AstFieldAccess* fa = make_field_access(context.ast_alloc, aa->addr, "data");
fa->type = smem.type;
fa->offset = smem.offset;
fa->idx = smem.idx;
// CLEANUP: Duplicating the string here isn't the best for effiency,
// but it fixes a lot of bugs, so here we are.
// - brendanfh 2020/12/08
- field->field = bh_strdup(semstate.allocator, field->token->text);
+ field->field = bh_strdup(context.ast_alloc, field->token->text);
token_toggle_end(field->token);
}
CheckStatus check_size_of(AstSizeOf* so) {
fill_in_array_count(so->so_ast_type);
- so->so_type = type_build_from_ast(semstate.allocator, so->so_ast_type);
+ so->so_type = type_build_from_ast(context.ast_alloc, so->so_ast_type);
if (so->so_type == NULL) {
onyx_report_error(so->token->pos, "Error with type used here.");
return Check_Error;
CheckStatus check_align_of(AstAlignOf* ao) {
fill_in_array_count(ao->ao_ast_type);
- ao->ao_type = type_build_from_ast(semstate.allocator, ao->ao_ast_type);
+ ao->ao_type = type_build_from_ast(context.ast_alloc, ao->ao_ast_type);
if (ao->ao_type == NULL) {
onyx_report_error(ao->token->pos, "Error with type used here.");
return Check_Error;
AstTyped* expr = *pexpr;
if (expr->kind > Ast_Kind_Type_Start && expr->kind < Ast_Kind_Type_End) {
return Check_Success;
- // if (expr->token) {
- // onyx_report_error(expr->token->pos, "Type used as part of an expression.");
- // }
- // else {
- // onyx_report_error((OnyxFilePos) { 0 }, "Type used as part of an expression somewhere in the program.");
- // }
- // return Check_Error;
}
fill_in_type(expr);
}
CheckStatus check_function(AstFunction* func) {
- semstate.expected_return_type = func->type->Function.return_type;
+ expected_return_type = func->type->Function.return_type;
if (func->body) {
CheckStatus status = check_block(func->body);
if (status != Check_Success && func->generated_from)
CheckStatus check_struct(AstStructType* s_node) {
// NOTE: fills in the stcache
- type_build_from_ast(semstate.allocator, (AstType *) s_node);
+ type_build_from_ast(context.ast_alloc, (AstType *) s_node);
if (s_node->stcache == NULL) return Check_Error;
bh_arr_each(StructMember *, smem, s_node->stcache->Struct.memarr) {
if (param->vararg_kind == VA_Kind_Untyped) {
// HACK
if (builtin_vararg_type_type == NULL)
- builtin_vararg_type_type = type_build_from_ast(semstate.node_allocator, builtin_vararg_type);
+ builtin_vararg_type_type = type_build_from_ast(context.ast_alloc, builtin_vararg_type);
local->type = builtin_vararg_type_type;
}
if (func->return_type != NULL) CHECK(type, func->return_type);
- func->type = type_build_function_type(semstate.node_allocator, func);
+ func->type = type_build_function_type(context.ast_alloc, func);
if ((func->flags & Ast_Flag_Exported) != 0) {
if ((func->flags & Ast_Flag_Foreign) != 0) {
cs = check_overloaded_function(ent->overloaded_function);
break;
- case Entity_Type_Foreign_Global_Header:
- semstate.program->foreign_global_count++;
- // fallthrough
-
case Entity_Type_Global:
cs = check_global(ent->global);
break;
return dp;
}
-OnyxDocumentation onyx_docs_generate(ProgramInfo* prog) {
+OnyxDocumentation onyx_docs_generate() {
OnyxDocumentation doc;
bh_arena_init(&doc.doc_arena, global_heap_allocator, 16 * 1024);
doc.package_docs = NULL;
bh_arr_new(global_heap_allocator, doc.package_docs, 16);
- bh_table_each_start(Package *, prog->packages);
+ bh_table_each_start(Package *, context.packages);
DocPackage dp = doc_package_create(value, a);
bh_arr_push(doc.package_docs, dp);
bh_table_each_end;
-
#include "onyxerrors.h"
#include "onyxutils.h"
-#define MAX_MSGS 100
-
OnyxErrors errors;
-void onyx_errors_init(bh_table(bh_file_contents)* files) {
+void onyx_errors_init(bh_arr(bh_file_contents)* files) {
errors.file_contents = files;
bh_arena_init(&errors.msg_arena, global_heap_allocator, 16 * 1024);
bh_arr_each(OnyxError, err, errors.errors) {
if (err->pos.filename) {
- bh_file_contents* fc = &bh_table_get(bh_file_contents, *errors.file_contents, (char *) err->pos.filename);
- print_detailed_message(err, fc);
+ bh_file_contents file_contents = { 0 };
+ bh_arr_each(bh_file_contents, fc, *errors.file_contents) {
+ if (!strcmp(fc->filename, err->pos.filename)) {
+ file_contents = *fc;
+ break;
+ }
+ }
+
+ print_detailed_message(err, &file_contents);
} else {
bh_printf("(%l,%l) %s\n", err->pos.line, err->pos.column, err->text);
AstPackage* package_node = make_node(AstPackage, Ast_Kind_Package);
if (parser->curr->type != Token_Type_Keyword_Package) {
- Package *package = program_info_package_lookup_or_create(
- parser->program,
- "main",
- parser->program->global_scope,
- parser->allocator);
+ Package *package = package_lookup_or_create("main", context.global_scope, parser->allocator);
package_node->token = NULL;
package_node->package = package;
strncat(package_name, symbol->text, 1023);
token_toggle_end(symbol);
- Package *newpackage = program_info_package_lookup_or_create(
- parser->program,
- package_name,
- parser->program->global_scope,
- parser->allocator);
+ Package *newpackage = package_lookup_or_create(package_name, context.global_scope, parser->allocator);
if (package != NULL) {
AstPackage* pnode = make_node(AstPackage, Ast_Kind_Package);
return node;
}
-OnyxParser onyx_parser_create(bh_allocator alloc, OnyxTokenizer *tokenizer, ProgramInfo* program) {
+OnyxParser onyx_parser_create(bh_allocator alloc, OnyxTokenizer *tokenizer) {
OnyxParser parser;
parser.allocator = alloc;
parser.tokenizer = tokenizer;
parser.curr = tokenizer->tokens;
parser.prev = NULL;
- parser.program = program;
parser.hit_unexpected_token = 0;
parser.block_stack = NULL;
ParseResults onyx_parse(OnyxParser *parser) {
// NOTE: Skip comments at the beginning of the file
- if (parser->curr->type == Token_Type_Comment)
+ while (parser->curr->type == Token_Type_Comment)
consume_token(parser);
parser->package = parse_package_name(parser)->package;
+++ /dev/null
-// TODO: This file has become useless. It should be removed soon.
-
-#define BH_DEBUG
-#include "onyxsempass.h"
-#include "onyxutils.h"
-
-SemState semstate;
-
-void onyx_sempass_init(bh_allocator alloc, bh_allocator node_alloc) {
- semstate = (SemState) {
- .allocator = alloc,
- .node_allocator = node_alloc,
-
- .global_scope = NULL,
- .curr_scope = NULL,
-
- .block_stack = NULL,
-
- .defer_allowed = 1,
- };
-
- bh_arr_new(global_heap_allocator, semstate.block_stack, 4);
-}
#define BH_DEBUG
-#include "onyxsempass.h"
#include "onyxparser.h"
#include "onyxutils.h"
#include "onyxastnodes.h"
#include "onyxerrors.h"
-static void scope_enter(Scope* new_scope);
-static void scope_leave();
+// Variables used during the symbol resolution phase.
+static Scope* curr_scope = NULL;
+static Package* curr_package = NULL;
+static AstFunction* curr_function = NULL;
+bh_arr(AstBlock *) block_stack = NULL;
AstType* symres_type(AstType* type);
static void symres_local(AstLocal** local, b32 add_to_block_locals);
static void symres_struct_defaults(AstType* st);
static void scope_enter(Scope* new_scope) {
- semstate.curr_scope = new_scope;
+ curr_scope = new_scope;
}
static void scope_leave() {
- semstate.curr_scope = semstate.curr_scope->parent;
+ curr_scope = curr_scope->parent;
}
AstType* symres_type(AstType* type) {
}
if (type->kind == Ast_Kind_Symbol) {
- return (AstType *) symbol_resolve(semstate.curr_scope, ((AstNode *) type)->token);
+ return (AstType *) symbol_resolve(curr_scope, ((AstNode *) type)->token);
}
if (type->kind == Ast_Kind_Field_Access) {
if (type->kind == Ast_Kind_Poly_Struct_Type) {
AstPolyStructType* pst_node = (AstPolyStructType *) type;
- pst_node->scope = scope_create(semstate.node_allocator, semstate.curr_scope, pst_node->token->pos);
+ pst_node->scope = scope_create(context.ast_alloc, curr_scope, pst_node->token->pos);
bh_arr_each(AstPolyStructParam, param, pst_node->poly_params) {
param->type_node = symres_type(param->type_node);
- param->type = type_build_from_ast(semstate.node_allocator, param->type_node);
+ param->type = type_build_from_ast(context.ast_alloc, param->type_node);
}
return type;
// of unique WASM locals and stack space needed.
// - brendanfh 2020/12/16
if (add_to_block_locals)
- bh_arr_push(bh_arr_last(semstate.block_stack)->allocate_exprs, (AstTyped *) *local);
+ bh_arr_push(bh_arr_last(block_stack)->allocate_exprs, (AstTyped *) *local);
- bh_arr_push(semstate.curr_function->allocate_exprs, (AstTyped *) *local);
+ bh_arr_push(curr_function->allocate_exprs, (AstTyped *) *local);
if ((*local)->token != NULL)
- symbol_introduce(semstate.curr_scope, (*local)->token, (AstNode *) *local);
+ symbol_introduce(curr_scope, (*local)->token, (AstNode *) *local);
}
static void symres_arguments(Arguments* args) {
if ((*pipe)->left == NULL) return;
bh_arr_insertn(call_node->args.values, 0, 1);
- call_node->args.values[0] = (AstTyped *) make_argument(semstate.node_allocator, (*pipe)->left);
+ call_node->args.values[0] = (AstTyped *) make_argument(context.ast_alloc, (*pipe)->left);
call_node->next = (*pipe)->next;
// NOTE: Not a BinaryOp node
bh_arr_each(AstTyped *, expr, al->values)
symres_expression(expr);
- if (bh_arr_length(semstate.block_stack) > 0) {
- bh_arr_push(bh_arr_last(semstate.block_stack)->allocate_exprs, (AstTyped *) al);
- bh_arr_push(semstate.curr_function->allocate_exprs, (AstTyped *) al);
+ if (bh_arr_length(block_stack) > 0) {
+ bh_arr_push(bh_arr_last(block_stack)->allocate_exprs, (AstTyped *) al);
+ bh_arr_push(curr_function->allocate_exprs, (AstTyped *) al);
}
}
switch ((*expr)->kind) {
case Ast_Kind_Symbol:
- *expr = (AstTyped *) symbol_resolve(semstate.curr_scope, ((AstNode *) *expr)->token);
+ *expr = (AstTyped *) symbol_resolve(curr_scope, ((AstNode *) *expr)->token);
break;
case Ast_Kind_Binary_Op:
// NOTE: This is a weird place to put this so maybe put it somewhere else eventually
// - brendanfh 2020/09/04
- builtin_range_type_type = type_build_from_ast(semstate.node_allocator, builtin_range_type);
+ builtin_range_type_type = type_build_from_ast(context.ast_alloc, builtin_range_type);
break;
case Ast_Kind_Function:
static void symres_if(AstIfWhile* ifnode) {
if (ifnode->assignment != NULL) {
- ifnode->scope = scope_create(semstate.node_allocator, semstate.curr_scope, ifnode->token->pos);
+ ifnode->scope = scope_create(context.ast_alloc, curr_scope, ifnode->token->pos);
scope_enter(ifnode->scope);
symres_local(&ifnode->local, 0);
static void symres_while(AstIfWhile* whilenode) {
if (whilenode->assignment != NULL) {
- whilenode->scope = scope_create(semstate.node_allocator, semstate.curr_scope, whilenode->token->pos);
+ whilenode->scope = scope_create(context.ast_alloc, curr_scope, whilenode->token->pos);
scope_enter(whilenode->scope);
symres_local(&whilenode->local, 0);
}
static void symres_for(AstFor* fornode) {
- fornode->scope = scope_create(semstate.node_allocator, semstate.curr_scope, fornode->token->pos);
+ fornode->scope = scope_create(context.ast_alloc, curr_scope, fornode->token->pos);
scope_enter(fornode->scope);
symres_expression(&fornode->iter);
static void symres_switch(AstSwitch* switchnode) {
if (switchnode->assignment != NULL) {
- switchnode->scope = scope_create(semstate.node_allocator, semstate.curr_scope, switchnode->token->pos);
+ switchnode->scope = scope_create(context.ast_alloc, curr_scope, switchnode->token->pos);
scope_enter(switchnode->scope);
- symbol_introduce(semstate.curr_scope, switchnode->local->token, (AstNode *) switchnode->local);
+ symbol_introduce(curr_scope, switchnode->local->token, (AstNode *) switchnode->local);
symres_statement((AstNode **) &switchnode->assignment);
}
AstEnumType* et = (AstEnumType *) use->expr;
bh_arr_each(AstEnumValue *, ev, et->values)
- symbol_introduce(semstate.curr_scope, (*ev)->token, (AstNode *) *ev);
+ symbol_introduce(curr_scope, (*ev)->token, (AstNode *) *ev);
return;
}
effective_type->kind == Ast_Kind_Poly_Call_Type) {
if (use->expr->type == NULL)
- use->expr->type = type_build_from_ast(semstate.node_allocator, use->expr->type_node);
+ use->expr->type = type_build_from_ast(context.ast_alloc, use->expr->type_node);
if (use->expr->type == NULL) goto cannot_use;
Type* st = use->expr->type;
st = st->Pointer.elem;
bh_table_each_start(StructMember, st->Struct.members);
- AstFieldAccess* fa = make_field_access(semstate.node_allocator, use->expr, value.name);
- symbol_raw_introduce(semstate.curr_scope, value.name, use->token->pos, (AstNode *) fa);
+ AstFieldAccess* fa = make_field_access(context.ast_alloc, use->expr, value.name);
+ symbol_raw_introduce(curr_scope, value.name, use->token->pos, (AstNode *) fa);
bh_table_each_end;
return;
if (onyx_has_errors()) return;
if (node_is_type((AstNode *) sln->value)) {
- sln->type = type_build_from_ast(semstate.node_allocator, sln->ast_type);
+ sln->type = type_build_from_ast(context.ast_alloc, sln->ast_type);
sln->kind = PSK_Type;
} else {
sln->kind = PSK_Value;
static void symres_block(AstBlock* block) {
if (block->scope == NULL)
- block->scope = scope_create(semstate.node_allocator, semstate.curr_scope, block->token->pos);
+ block->scope = scope_create(context.ast_alloc, curr_scope, block->token->pos);
scope_enter(block->scope);
- bh_arr_push(semstate.block_stack, block);
+ bh_arr_push(block_stack, block);
if (block->binding_scope != NULL)
scope_include(block->scope, block->binding_scope, block->token->pos);
if (block->body)
symres_statement_chain(&block->body);
- bh_arr_pop(semstate.block_stack);
+ bh_arr_pop(block_stack);
scope_leave();
}
void symres_function_header(AstFunction* func) {
if (func->scope == NULL)
- func->scope = scope_create(semstate.node_allocator, semstate.curr_scope, func->token->pos);
+ func->scope = scope_create(context.ast_alloc, curr_scope, func->token->pos);
func->flags |= Ast_Flag_Comptime;
param->local->type_node = symres_type(param->local->type_node);
}
- symbol_introduce(semstate.curr_scope, param->local->token, (AstNode *) param->local);
+ symbol_introduce(curr_scope, param->local->token, (AstNode *) param->local);
if (param->local->flags & Ast_Flag_Param_Use) {
if (param->local->type_node != NULL && param->local->type == NULL) {
- param->local->type = type_build_from_ast(semstate.allocator, param->local->type_node);
+ param->local->type = type_build_from_ast(context.ast_alloc, param->local->type_node);
}
if (type_is_struct(param->local->type)) {
}
bh_table_each_start(StructMember, st->Struct.members);
- AstFieldAccess* fa = make_field_access(semstate.node_allocator, (AstTyped *) param->local, value.name);
- symbol_raw_introduce(semstate.curr_scope, value.name, param->local->token->pos, (AstNode *) fa);
+ AstFieldAccess* fa = make_field_access(context.ast_alloc, (AstTyped *) param->local, value.name);
+ symbol_raw_introduce(curr_scope, value.name, param->local->token->pos, (AstNode *) fa);
bh_table_each_end;
} else if (param->local->type != NULL) {
void symres_function(AstFunction* func) {
scope_enter(func->scope);
- semstate.curr_function = func;
+ curr_function = func;
symres_block(func->body);
scope_leave();
static void symres_use_package(AstUsePackage* package) {
token_toggle_end(package->package->token);
- Package* p = program_info_package_lookup(semstate.program, package->package->token->text);
+ Package* p = package_lookup(package->package->token->text);
token_toggle_end(package->package->token);
if (p == NULL) {
return;
}
- if (p->scope == semstate.curr_scope) return;
+ if (p->scope == curr_scope) return;
if (package->alias != NULL) {
- AstPackage *pac_node = onyx_ast_node_new(semstate.node_allocator, sizeof(AstPackage), Ast_Kind_Package);
+ AstPackage *pac_node = onyx_ast_node_new(context.ast_alloc, sizeof(AstPackage), Ast_Kind_Package);
pac_node->package = p;
pac_node->token = package->alias;
- symbol_introduce(semstate.curr_scope, package->alias, (AstNode *) pac_node);
+ symbol_introduce(curr_scope, package->alias, (AstNode *) pac_node);
}
if (package->only != NULL) {
return;
}
- symbol_introduce(semstate.curr_scope, (*alias)->alias, thing);
+ symbol_introduce(curr_scope, (*alias)->alias, thing);
}
}
if (package->token != NULL)
pos = package->token->pos;
- scope_include(semstate.curr_scope, p->scope, pos);
+ scope_include(curr_scope, p->scope, pos);
}
}
static void symres_enum(AstEnumType* enum_node) {
if (enum_node->backing->kind == Ast_Kind_Symbol) {
- enum_node->backing = (AstType *) symbol_resolve(semstate.curr_scope, enum_node->backing->token);
+ enum_node->backing = (AstType *) symbol_resolve(curr_scope, enum_node->backing->token);
}
if (enum_node->backing == NULL) return;
- enum_node->backing_type = type_build_from_ast(semstate.allocator, enum_node->backing);
- enum_node->scope = scope_create(semstate.node_allocator, NULL, enum_node->token->pos);
+ enum_node->backing_type = type_build_from_ast(context.ast_alloc, enum_node->backing);
+ enum_node->scope = scope_create(context.ast_alloc, NULL, enum_node->token->pos);
- type_build_from_ast(semstate.node_allocator, (AstType *) enum_node);
+ type_build_from_ast(context.ast_alloc, (AstType *) enum_node);
u64 next_assign_value = (enum_node->flags & Ast_Flag_Enum_Is_Flags) ? 1 : 0;
bh_arr_each(AstEnumValue *, value, enum_node->values) {
(*value)->value->type = enum_node->etcache;
} else {
- AstNumLit* num = make_int_literal(semstate.node_allocator, next_assign_value);
+ AstNumLit* num = make_int_literal(context.ast_alloc, next_assign_value);
num->type = enum_node->etcache;
(*value)->value = num;
}
static void symres_polyproc(AstPolyProc* pp) {
- pp->poly_scope = semstate.curr_scope;
+ pp->poly_scope = curr_scope;
bh_arr_each(AstPolyParam, param, pp->poly_params) {
if (param->kind != PPK_Baked_Value) continue;
}
void symres_entity(Entity* ent) {
- if (ent->package) semstate.curr_package = ent->package;
+ if (block_stack == NULL)
+ bh_arr_new(global_heap_allocator, block_stack, 16);
+
+ if (ent->package) curr_package = ent->package;
Scope* old_scope = NULL;
if (ent->scope) {
- old_scope = semstate.curr_scope;
+ old_scope = curr_scope;
scope_enter(ent->scope);
}
ent->state = next_state;
if (ent->scope) {
- semstate.curr_scope = old_scope;
+ curr_scope = old_scope;
}
}
#include "onyxerrors.h"
#include "onyxparser.h"
#include "onyxastnodes.h"
-#include "onyxsempass.h"
bh_scratch global_scratch;
bh_allocator global_scratch_allocator;
//
// Program info and packages
//
-void program_info_init(ProgramInfo* prog, bh_allocator alloc) {
- prog->global_scope = scope_create(alloc, NULL, (OnyxFilePos) { 0 });
-
- bh_table_init(alloc, prog->packages, 16);
-
- // NOTE: This will be initialized upon the first call to entity_heap_insert.
- prog->entities.entities = NULL;
-}
-
-Package* program_info_package_lookup(ProgramInfo* prog, char* package_name) {
- if (bh_table_has(Package *, prog->packages, package_name)) {
- return bh_table_get(Package *, prog->packages, package_name);
+Package* package_lookup(char* package_name) {
+ if (bh_table_has(Package *, context.packages, package_name)) {
+ return bh_table_get(Package *, context.packages, package_name);
} else {
return NULL;
}
}
-Package* program_info_package_lookup_or_create(ProgramInfo* prog, char* package_name, Scope* parent_scope, bh_allocator alloc) {
- if (bh_table_has(Package *, prog->packages, package_name)) {
- return bh_table_get(Package *, prog->packages, package_name);
+Package* package_lookup_or_create(char* package_name, Scope* parent_scope, bh_allocator alloc) {
+ if (bh_table_has(Package *, context.packages, package_name)) {
+ return bh_table_get(Package *, context.packages, package_name);
} else {
Package* package = bh_alloc_item(alloc, Package);
package->scope = scope_create(alloc, parent_scope, (OnyxFilePos) { 0 });
package->private_scope = scope_create(alloc, package->scope, (OnyxFilePos) { 0 });
- bh_table_put(Package *, prog->packages, pac_name, package);
+ bh_table_put(Package *, context.packages, pac_name, package);
return package;
}
switch (sln->kind) {
case PSK_Type:
- node = onyx_ast_node_new(semstate.node_allocator, sizeof(AstTypeRawAlias), Ast_Kind_Type_Raw_Alias);
+ node = onyx_ast_node_new(context.ast_alloc, sizeof(AstTypeRawAlias), Ast_Kind_Type_Raw_Alias);
((AstTypeRawAlias *) node)->token = sln->poly_sym->token;
((AstTypeRawAlias *) node)->to = sln->type;
break;
.scope = solidified_func.poly_scope,
};
- entity_heap_insert(&semstate.program->entities, func_header_entity);
- entity_heap_insert(&semstate.program->entities, func_entity);
+ entity_heap_insert(&context.entities, func_header_entity);
+ entity_heap_insert(&context.entities, func_entity);
return 1;
}
OnyxFilePos poly_scope_pos = { 0 };
if (tkn) poly_scope_pos = tkn->pos;
- solidified_func.poly_scope = scope_create(semstate.node_allocator, pp->poly_scope, poly_scope_pos);
+ solidified_func.poly_scope = scope_create(context.ast_alloc, pp->poly_scope, poly_scope_pos);
insert_poly_slns_into_scope(solidified_func.poly_scope, slns);
if (header_only) {
- solidified_func.func = (AstFunction *) clone_function_header(semstate.node_allocator, pp->base_func);
+ solidified_func.func = (AstFunction *) clone_function_header(context.ast_alloc, pp->base_func);
solidified_func.func->flags |= Ast_Flag_Incomplete_Body;
} else {
- solidified_func.func = (AstFunction *) ast_clone(semstate.node_allocator, pp->base_func);
+ solidified_func.func = (AstFunction *) ast_clone(context.ast_alloc, pp->base_func);
}
solidified_func.func->flags |= Ast_Flag_From_Polymorphism;
static void ensure_solidified_function_has_body(AstPolyProc* pp, AstSolidifiedFunction solidified_func) {
if (solidified_func.func->flags & Ast_Flag_Incomplete_Body) {
- clone_function_body(semstate.node_allocator, solidified_func.func, pp->base_func);
+ clone_function_body(context.ast_alloc, solidified_func.func, pp->base_func);
// HACK: I'm asserting that this function should return without an error, because
// the only case where it can return an error is if there was a problem with the
bh_arr_push(elem_queue, ((PolySolveElem) {
.type_expr = (AstType*) ((AstArrayType *) elem.type_expr)->count_expr,
.kind = PSK_Value,
- .value = (AstTyped *) make_int_literal(semstate.node_allocator, elem.actual->Array.count)
+ .value = (AstTyped *) make_int_literal(context.ast_alloc, elem.actual->Array.count)
}));
bh_arr_push(elem_queue, ((PolySolveElem) {
return;
}
- Type* resolved_type = type_build_from_ast(semstate.node_allocator, (AstType *) value);
+ Type* resolved_type = type_build_from_ast(context.ast_alloc, (AstType *) value);
*resolved = ((PolySolveResult) { PSK_Type, .actual = resolved_type });
} else {
}
if (param->type == NULL)
- param->type = type_build_from_ast(semstate.node_allocator, param->type_expr);
+ param->type = type_build_from_ast(context.ast_alloc, param->type_expr);
if (!type_check_or_auto_cast(&value, param->type)) {
*err_msg = bh_aprintf(global_scratch_allocator,
// HACK: Some of these initializations assume that the entity for this polyproc has
// made it through the symbol resolution phase.
// - brendanfh 2020/12/25
- AstPolyProc* new_pp = onyx_ast_node_new(semstate.node_allocator, sizeof(AstPolyProc), Ast_Kind_Polymorphic_Proc);
+ AstPolyProc* new_pp = onyx_ast_node_new(context.ast_alloc, sizeof(AstPolyProc), Ast_Kind_Polymorphic_Proc);
new_pp->token = pp->token; // TODO: Change this to be the solidify->token
new_pp->base_func = pp->base_func;
new_pp->poly_scope = new_pp->poly_scope;
scope_clear(ps_type->scope);
insert_poly_slns_into_scope(ps_type->scope, slns);
- AstStructType* concrete_struct = (AstStructType *) ast_clone(semstate.node_allocator, ps_type->base_struct);
+ AstStructType* concrete_struct = (AstStructType *) ast_clone(context.ast_alloc, ps_type->base_struct);
bh_table_put(AstStructType *, ps_type->concrete_structs, unique_key, concrete_struct);
Entity struct_entity = {
return NULL;
}
- Type* cs_type = type_build_from_ast(semstate.node_allocator, (AstType *) concrete_struct);
+ Type* cs_type = type_build_from_ast(context.ast_alloc, (AstType *) concrete_struct);
cs_type->Struct.poly_sln = NULL;
bh_arr_new(global_heap_allocator, cs_type->Struct.poly_sln, bh_arr_length(slns));
AstTyped* default_value = func->params[idx].default_value;
if (default_value == NULL) return NULL;
- AstArgument* arg = make_argument(semstate.node_allocator, default_value);
+ AstArgument* arg = make_argument(context.ast_alloc, default_value);
return (AstNode *) arg;
}