From bfb22fec3ff154edce051129efd2461a4413f09a Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Mon, 15 Jun 2020 23:12:17 -0500 Subject: [PATCH] Code clean up and added "start" section output --- .gitignore | 1 + docs/plan | 71 +++++++++++++++++++++++++++++++++++++++------ onyx | Bin 141488 -> 137224 bytes progs/minimal.onyx | 4 ++- src/onyx.c | 67 ++++++++++++++++++++++++------------------ src/onyxutils.c | 4 +-- src/onyxwasm.c | 45 ++++++++++++++++++---------- 7 files changed, 135 insertions(+), 57 deletions(-) diff --git a/.gitignore b/.gitignore index 8ca5336c..e11e2b69 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ tags test.c test *.wasm +*.html diff --git a/docs/plan b/docs/plan index d78b4992..d91c21b5 100644 --- a/docs/plan +++ b/docs/plan @@ -31,28 +31,81 @@ HOW: at once would be overwhelming and unsatisfying. The current progress of each stage: Stage 1 (MVP): - [ ] Can declare procedures - [ ] Procedures have params and returns of the following types: + [X] Can declare procedures + [X] Procedures have params and returns of the following types: - i32, u32 - i64, u64 - f32, f64 - [ ] Procedures have locals of the same set of types - [ ] Locals are declared in the following way - local : (const) (type) (= initial value); + [X] Procedures have locals of the same set of types + [X] Locals are declared in the following way + local : (type) ((= or :) initial value); - if const is specified, the value is unmodifiable + if : is used, the value is unmodifiable if type is specified, that is assumed to be the correct type if type is not specified, the type of initial value is used as the type - [ ] Five basic math operations are legal: + [X] Five basic math operations are legal: + - * / % - [ ] Math operations are sign aware and only operate on operands of the same type - [ ] All casts are explicit using this syntax: + [X] Math operations are sign aware and only operate on operands of the same type + [X] All casts are explicit using this syntax: X as T casts X to type T + [ ] Numeric literals are parsed and minimum type detected + [ ] Comparison operators + [ ] Proper boolean type [ ] Conditional branching works as expected [ ] Curly braces are required for all bodies of blocks [ ] Simple while loop is functioning as expected [ ] break and continue semantics + [ ] Function calling works for the builtin types + [ ] Function return values are type checked + + Stage 2: + [ ] Order of symbol declaration is irrelevant + Either: + make a graph of symbol dependencies and produce a schedule on the graph + that would allow for all symbols to be resolved + + OR + + Do as many passes on the parse tree as needed to resolve all symbols. + This could be slow but it would be easier than creating a graph + scheduling algorithm. + + [ ] Devise and implement a simple set of implicit type casting rules. + - Numeric literals always type cast to whatever type is needed (very flexible). + + [ ] Start work on evaluating compile time known values. + - An expression marked COMPTIME will be reduced to its value in the parse tree. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/onyx b/onyx index 532e9c8dca6cd6f33c97a34c8a62fb2c9bacbc7a..74ff9b5d862da4e596e74b3de33f281ac0dcdca4 100755 GIT binary patch delta 41252 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 delta 42395 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 MpSF6YKUbIh2Xci5Pyhe` diff --git a/progs/minimal.onyx b/progs/minimal.onyx index ba83edb0..17df6c75 100644 --- a/progs/minimal.onyx +++ b/progs/minimal.onyx @@ -19,4 +19,6 @@ export diff_square :: proc (a i32, b i32) -> i32 { return (c * d) as i32; } -export dummy :: proc () { } +export main :: proc () { + +} diff --git a/src/onyx.c b/src/onyx.c index 2c5e9d2b..c55a7b31 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -19,23 +19,16 @@ int main(int argc, char *argv[]) { bh_allocator alloc = bh_heap_allocator(); + // NOTE: 1st: Read file contents bh_file_contents fc = bh_file_read_contents(alloc, &source_file); bh_file_close(&source_file); + // NOTE: 2nd: Tokenize the contents OnyxTokenizer tokenizer = onyx_tokenizer_create(alloc, &fc); onyx_lex_tokens(&tokenizer); bh_arr(OnyxToken) token_arr = tokenizer.tokens; -#if 0 - bh_printf("There are %d tokens (Allocated space for %d tokens)\n", bh_arr_length(token_arr), bh_arr_capacity(token_arr)); - - bh_arr_each(OnyxToken, it, token_arr) { - onyx_token_null_toggle(*it); - bh_printf("%s (%s:%l:%l)\n", onyx_get_token_type_name(it->type), it->pos.filename, it->pos.line, it->pos.column); - onyx_token_null_toggle(*it); - } -#endif - + // NOTE: Create the buffer for where compiler messages will be written bh_arena msg_arena; bh_arena_init(&msg_arena, alloc, 4096); bh_allocator msg_alloc = bh_arena_allocator(&msg_arena); @@ -43,10 +36,13 @@ int main(int argc, char *argv[]) { OnyxMessages msgs; onyx_message_create(msg_alloc, &msgs); + // NOTE: Create the arena where AST nodes will exist + // Prevents nodes from being scattered across memory due to fragmentation bh_arena ast_arena; bh_arena_init(&ast_arena, alloc, 16 * 1024 * 1024); // 16MB bh_allocator ast_alloc = bh_arena_allocator(&ast_arena); + // NOTE: 3rd: parse the tokens to an AST OnyxParser parser = onyx_parser_create(ast_alloc, &tokenizer, &msgs); OnyxAstNode* program = onyx_parse(&parser); @@ -56,13 +52,42 @@ int main(int argc, char *argv[]) { onyx_message_print(&msgs); goto main_exit; } else { - onyx_ast_print(program, 0); + // onyx_ast_print(program, 0); bh_printf("\nNo errors.\n"); } + // NOTE: 4th: Generate a WASM module from the parse tree and + // write it to a file. OnyxWasmModule wasm_mod = onyx_wasm_generate_module(alloc, program); -#if 1 + bh_file out_file; + bh_file_create(&out_file, "out.wasm"); + onyx_wasm_module_write_to_file(&wasm_mod, out_file); + bh_file_close(&out_file); + + onyx_wasm_module_free(&wasm_mod); +main_exit: // NOTE: Cleanup, since C doesn't have defer + bh_arena_free(&msg_arena); + bh_arena_free(&ast_arena); + onyx_parser_free(&parser); + onyx_tokenizer_free(&tokenizer); + bh_file_contents_free(&fc); + + return 0; +} + +// NOTE: Old bits of code that may be useful again at some point. +#if 0 + bh_printf("There are %d tokens (Allocated space for %d tokens)\n", bh_arr_length(token_arr), bh_arr_capacity(token_arr)); + + bh_arr_each(OnyxToken, it, token_arr) { + onyx_token_null_toggle(*it); + bh_printf("%s (%s:%l:%l)\n", onyx_get_token_type_name(it->type), it->pos.filename, it->pos.line, it->pos.column); + onyx_token_null_toggle(*it); + } +#endif + +#if 0 // NOTE: Ensure type table made correctly bh_printf("Type map:\n"); @@ -83,7 +108,7 @@ int main(int argc, char *argv[]) { } #endif -#if 1 +#if 0 // NOTE: Ensure the export table was built correctly bh_printf("Function types:\n"); @@ -96,19 +121,3 @@ int main(int argc, char *argv[]) { bh_printf("%s: %d %d\n", key, value.kind, value.idx); bh_hash_each_end; #endif - - bh_file out_file; - bh_file_create(&out_file, "out.wasm"); - onyx_wasm_module_write_to_file(&wasm_mod, out_file); - bh_file_close(&out_file); - - onyx_wasm_module_free(&wasm_mod); -main_exit: // NOTE: Cleanup, since C doesn't have defer - bh_arena_free(&msg_arena); - bh_arena_free(&ast_arena); - onyx_parser_free(&parser); - onyx_tokenizer_free(&tokenizer); - bh_file_contents_free(&fc); - - return 0; -} diff --git a/src/onyxutils.c b/src/onyxutils.c index aff6aba5..ba50b4ee 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -89,8 +89,8 @@ void onyx_ast_print(OnyxAstNode* node, i32 indent) { } case ONYX_AST_NODE_KIND_RETURN: { - if (node->next) { - onyx_ast_print(node->next, indent + 1); + if (node->left) { + onyx_ast_print(node->left, indent + 1); } break; diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 35aabd43..4b9f2007 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -510,24 +510,9 @@ static void process_function_definition(OnyxWasmModule* mod, OnyxAstNodeFuncDef* count++; } - - bh_printf("\nLocals for function: %b\n", fd->token->token, fd->token->length); - bh_printf("\tI32 count: %d\n", wasm_func.locals.i32_count); - bh_printf("\tI64 count: %d\n", wasm_func.locals.i64_count); - bh_printf("\tF32 count: %d\n", wasm_func.locals.f32_count); - bh_printf("\tF64 count: %d\n", wasm_func.locals.f64_count); - bh_hash_each_start(i32, mod->local_map); - bh_printf("\t%s -> %d\n", key, value); - bh_hash_each_end; - // Generate code process_function_body(mod, &wasm_func, fd); - bh_printf("Code for function:\n"); - bh_arr_each(WasmInstruction, instr, wasm_func.code) { - bh_printf("\t%s\t%xd\n", wi_string(instr->type), instr->data.i1); - } - bh_arr_push(mod->funcs, wasm_func); // NOTE: Clear the local map on exit of generating this function @@ -719,6 +704,34 @@ static i32 output_exportsection(OnyxWasmModule* module, bh_buffer* buff) { return buff->length - prev_len; } +static i32 output_startsection(OnyxWasmModule* module, bh_buffer* buff) { + i32 prev_len = buff->length; + + i32 start_idx = -1; + bh_hash_each_start(WasmExport, module->exports) { + if (value.kind == WASM_EXPORT_FUNCTION) { + if (strncmp("main", key, 5) == 0) { + start_idx = value.idx; + break; + } + } + } bh_hash_each_end; + + if (start_idx != -1) { + bh_buffer_write_byte(buff, WASM_SECTION_ID_START); + + i32 start_leb_len, section_leb_len; + u8* start_leb = uint_to_uleb128((u64) start_idx, &start_leb_len); + u8* section_leb = uint_to_uleb128((u64) start_leb_len, §ion_leb_len); + bh_buffer_append(buff, section_leb, section_leb_len); + + start_leb = uint_to_uleb128((u64) start_idx, &start_leb_len); + bh_buffer_append(buff, start_leb, start_leb_len); + } + + return buff->length - prev_len; +} + static i32 output_locals(WasmFunc* func, bh_buffer* buff) { i32 prev_len = buff->length; @@ -840,8 +853,8 @@ void onyx_wasm_module_write_to_file(OnyxWasmModule* module, bh_file file) { output_typesection(module, &master_buffer); output_funcsection(module, &master_buffer); output_exportsection(module, &master_buffer); + output_startsection(module, &master_buffer); output_codesection(module, &master_buffer); - bh_file_write(&file, master_buffer.data, master_buffer.length); } -- 2.25.1