"The compiler for the Onyx programming language.\n"
"\n"
"Usage:\n"
- "\tonyx [-o <target file>] [-ast] <input files>\n"
+ "\tonyx [-o <target file>] [-ast] [-verbose] <input files>\n"
"\tonyx -help\n"
"\nFlags:\n"
"\t-o <target_file> Specify the target file (default: out.wasm)\n"
"\t-ast Print the abstract syntax tree after parsing\n"
+ "\t-verbose Verbose output\n"
"\t-help Print this help message\n";
typedef enum CompileAction {
bh_allocator allocator;
CompileAction action;
+ u32 verbose_output : 1;
u32 print_ast : 1;
bh_arr(const char *) files;
} CompilerProgress;
typedef struct CompilerState {
+ OnyxCompileOptions* options;
+
bh_arena ast_arena, msg_arena, sp_arena;
bh_allocator token_alloc, ast_alloc, msg_alloc, sp_alloc;
.allocator = alloc,
.action = ONYX_COMPILE_ACTION_PRINT_HELP,
+ .verbose_output = 0,
.print_ast = 0,
.files = NULL,
else if (!strcmp(argv[i], "-ast")) {
options.print_ast = 1;
}
+ else if (!strcmp(argv[i], "-verbose")) {
+ options.verbose_output = 1;
+ }
else {
options.action = ONYX_COMPILE_ACTION_COMPILE;
bh_arr_push(options.files, argv[i]);
return options;
}
-void compile_opts_free(OnyxCompileOptions* opts) {
+static void compile_opts_free(OnyxCompileOptions* opts) {
bh_arr_free(opts->files);
}
-OnyxAstNode* parse_source_file(CompilerState* compiler_state, bh_file_contents* file_contents) {
+static OnyxAstNode* parse_source_file(CompilerState* compiler_state, bh_file_contents* file_contents) {
// NOTE: Maybe don't want to recreate the tokenizer and parser for every file
+ if (compiler_state->options->verbose_output)
+ bh_printf("[Lexing] %s\n", file_contents->filename);
+
OnyxTokenizer tokenizer = onyx_tokenizer_create(compiler_state->token_alloc, file_contents);
- bh_printf("[Lexing] %s\n", file_contents->filename);
onyx_lex_tokens(&tokenizer);
- bh_printf("[Parsing] %s\n", file_contents->filename);
+ if (compiler_state->options->verbose_output)
+ bh_printf("[Parsing] %s\n", file_contents->filename);
+
OnyxParser parser = onyx_parser_create(compiler_state->ast_alloc, &tokenizer, &compiler_state->msgs);
return onyx_parse(&parser);
}
-CompilerProgress process_source_file(CompilerState* compiler_state, OnyxCompileOptions* opts, char* filename) {
+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;
bh_file file;
return ONYX_COMPILER_PROGRESS_FAILED_READ;
}
- bh_printf("[Reading] %s\n", file.filename);
+ if (compiler_state->options->verbose_output)
+ bh_printf("[Reading] %s\n", file.filename);
+
bh_file_contents fc = bh_file_read_contents(compiler_state->token_alloc, &file);
bh_file_close(&file);
OnyxAstNode* root_node = parse_source_file(compiler_state, &fc);
- if (opts->print_ast) {
+ if (compiler_state->options->print_ast) {
onyx_ast_print(root_node, 0);
bh_printf("\n");
}
}
}
-i32 onyx_compile(OnyxCompileOptions* opts, CompilerState* compiler_state) {
+static void compiler_state_init(CompilerState* compiler_state, OnyxCompileOptions* opts) {
+ compiler_state->options = opts;
+
+ bh_arr_new(global_heap_allocator, compiler_state->program.uses, 4);
+ bh_arr_new(global_heap_allocator, compiler_state->program.foreigns, 4);
+ bh_arr_new(global_heap_allocator, compiler_state->program.globals, 4);
+ bh_arr_new(global_heap_allocator, compiler_state->program.functions, 4);
bh_arena_init(&compiler_state->msg_arena, opts->allocator, 4096);
compiler_state->msg_alloc = bh_arena_allocator(&compiler_state->msg_arena);
// NOTE: Add all files passed by command line to the queue
bh_arr_each(const char *, filename, opts->files)
bh_arr_push(compiler_state->queued_files, (char *) *filename);
+}
+static i32 onyx_compile(CompilerState* compiler_state) {
// NOTE: While the queue is not empty, process the next file
while (!bh_arr_is_empty(compiler_state->queued_files)) {
- CompilerProgress result = process_source_file(compiler_state, opts, (char *) compiler_state->queued_files[0]);
+ CompilerProgress result = process_source_file(compiler_state, (char *) compiler_state->queued_files[0]);
if (result != ONYX_COMPILER_PROGRESS_SUCCESS)
return result;
// NOTE: Check types and semantic rules
- bh_printf("[Checking semantics]\n");
+ if (compiler_state->options->verbose_output)
+ bh_printf("[Checking semantics]\n");
+
OnyxSemPassState sp_state = onyx_sempass_create(compiler_state->sp_alloc, compiler_state->ast_alloc, &compiler_state->msgs);
onyx_sempass(&sp_state, &compiler_state->program);
// NOTE: Generate WASM instructions
- bh_printf("[Generating WASM]\n");
- compiler_state->wasm_mod = onyx_wasm_module_create(opts->allocator, &compiler_state->msgs);
+ if (compiler_state->options->verbose_output)
+ bh_printf("[Generating WASM]\n");
+
+ compiler_state->wasm_mod = onyx_wasm_module_create(compiler_state->options->allocator, &compiler_state->msgs);
onyx_wasm_module_compile(&compiler_state->wasm_mod, &compiler_state->program);
if (onyx_message_has_errors(&compiler_state->msgs)) {
// NOTE: Output to file
bh_file output_file;
- if (bh_file_create(&output_file, opts->target_file) != BH_FILE_ERROR_NONE) {
+ if (bh_file_create(&output_file, compiler_state->options->target_file) != BH_FILE_ERROR_NONE) {
return ONYX_COMPILER_PROGRESS_FAILED_OUTPUT;
}
- bh_printf("[Writing WASM] %s\n", output_file.filename);
+ if (compiler_state->options->verbose_output)
+ bh_printf("[Writing WASM] %s\n", output_file.filename);
+
onyx_wasm_module_write_to_file(&compiler_state->wasm_mod, output_file);
return ONYX_COMPILER_PROGRESS_SUCCESS;
}
-void compiler_state_free(CompilerState* cs) {
+static void compiler_state_free(CompilerState* cs) {
bh_arena_free(&cs->ast_arena);
bh_arena_free(&cs->msg_arena);
bh_arena_free(&cs->sp_arena);
.wasm_mod = { 0 }
};
- bh_arr_new(global_heap_allocator, compile_state.program.uses, 4);
- bh_arr_new(global_heap_allocator, compile_state.program.foreigns, 4);
- bh_arr_new(global_heap_allocator, compile_state.program.globals, 4);
- bh_arr_new(global_heap_allocator, compile_state.program.functions, 4);
+ compiler_state_init(&compile_state, &compile_opts);
CompilerProgress compiler_progress = ONYX_COMPILER_PROGRESS_FAILED_READ;
return 1;
case ONYX_COMPILE_ACTION_COMPILE:
- compiler_progress = onyx_compile(&compile_opts, &compile_state);
+ compiler_progress = onyx_compile(&compile_state);
break;
default: break;
break;
case ONYX_COMPILER_PROGRESS_SUCCESS:
- bh_printf("Successfully compiled to '%s'\n", compile_opts.target_file);
+ if (compile_opts.verbose_output) bh_printf("Successfully compiled to '%s'\n", compile_opts.target_file);
break;
}