From: Brendan Hansen Date: Mon, 15 Jun 2020 16:02:31 +0000 (-0500) Subject: GENERATING A WORKING BINARY! X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=8398213ca500d2d707ab0d263f593bfc5363096c;p=onyx.git GENERATING A WORKING BINARY! --- diff --git a/onyx b/onyx index eb95d4a8..532e9c8d 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/minimal.onyx b/progs/minimal.onyx index 1f1f75f5..ba83edb0 100644 --- a/progs/minimal.onyx +++ b/progs/minimal.onyx @@ -7,7 +7,7 @@ export foo :: proc (foo i32, bar i32) -> i32 { return 10 as i32; } -export diff_square :: proc (a i32, b i32) -> i64 { +export diff_square :: proc (a i32, b i32) -> i32 { // Typechecked c := a - b; // Mutable d :: a + b; // Constant @@ -16,7 +16,7 @@ export diff_square :: proc (a i32, b i32) -> i64 { f :: 10; }; - return (c * d) as i64; + return (c * d) as i32; } -export dummy :: proc () -> void { } +export dummy :: proc () { } diff --git a/src/onyxparser.c b/src/onyxparser.c index c271c0f6..00530182 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -583,10 +583,14 @@ static OnyxAstNodeFuncDef* parse_function_definition(OnyxParser* parser) { OnyxAstNodeParam* params = parse_function_params(parser); func_def->params = params; - expect(parser, TOKEN_TYPE_RIGHT_ARROW); + if (parser->curr_token->type == TOKEN_TYPE_RIGHT_ARROW) { + expect(parser, TOKEN_TYPE_RIGHT_ARROW); - OnyxTypeInfo* return_type = parse_type(parser); - func_def->return_type = return_type; + OnyxTypeInfo* return_type = parse_type(parser); + func_def->return_type = return_type; + } else { + func_def->return_type = &builtin_types[ONYX_TYPE_INFO_KIND_VOID]; + } for (OnyxAstNodeParam* p = func_def->params; p != NULL; p = p->next) { insert_identifier(parser, (OnyxAstNode *) p, 0); diff --git a/src/onyxwasm.c b/src/onyxwasm.c index b719acbe..35aabd43 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -205,7 +205,6 @@ static WasmType onyx_type_to_wasm_type(OnyxTypeInfo* type) { if (type->size == 8) return WASM_TYPE_FLOAT64; } - // TODO: Should produce an error message if this isn't successful return WASM_TYPE_VOID; } @@ -458,9 +457,14 @@ static void process_function_definition(OnyxWasmModule* mod, OnyxAstNodeFuncDef* WasmFunc wasm_func = { .type_idx = type_idx, + .locals = { + .i32_count = 0, + .i64_count = 0, + .f32_count = 0, + .f64_count = 0, + }, .code = NULL, }; - bh_arr_push(mod->funcs, wasm_func); i32 func_idx = mod->next_func_idx++; if (fd->flags & ONYX_AST_FLAG_EXPORTED) { @@ -487,13 +491,31 @@ static void process_function_definition(OnyxWasmModule* mod, OnyxAstNodeFuncDef* onyx_token_null_toggle(*param->token); } - forll (OnyxAstNodeLocal, local, fd->body->scope->last_local, prev_local) { - onyx_token_null_toggle(*local->token); - bh_hash_put(i32, mod->local_map, local->token->token, localidx++); - onyx_token_null_toggle(*local->token); + static const WasmType local_types[4] = { WASM_TYPE_INT32, WASM_TYPE_INT64, WASM_TYPE_FLOAT32, WASM_TYPE_FLOAT64 }; + + // HACK: This assumes that the order of the count members + // is the same as the order of the local_types above + u8* count = &wasm_func.locals.i32_count; + fori (ti, 0, 3) { + forll (OnyxAstNodeLocal, local, fd->body->scope->last_local, prev_local) { + if (onyx_type_to_wasm_type(local->type) == local_types[ti]) { + onyx_token_null_toggle(*local->token); + bh_hash_put(i32, mod->local_map, local->token->token, localidx++); + onyx_token_null_toggle(*local->token); + + (*count)++; + } + } + + 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; @@ -506,6 +528,8 @@ static void process_function_definition(OnyxWasmModule* mod, OnyxAstNodeFuncDef* 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 bh_hash_clear(mod->local_map); } @@ -695,6 +719,93 @@ static i32 output_exportsection(OnyxWasmModule* module, bh_buffer* buff) { return buff->length - prev_len; } +static i32 output_locals(WasmFunc* func, bh_buffer* buff) { + i32 prev_len = buff->length; + + // NOTE: Output vector length + i32 total_locals = + (i32) (func->locals.i32_count != 0) + + (i32) (func->locals.i64_count != 0) + + (i32) (func->locals.f32_count != 0) + + (i32) (func->locals.f64_count != 0); + + i32 leb_len; + u8* leb = uint_to_uleb128((u64) total_locals, &leb_len); + bh_buffer_append(buff, leb, leb_len); + + if (func->locals.i32_count != 0) { + leb = uint_to_uleb128((u64) func->locals.i32_count, &leb_len); + bh_buffer_append(buff, leb, leb_len); + bh_buffer_write_byte(buff, WASM_TYPE_INT32); + } + if (func->locals.i64_count != 0) { + leb = uint_to_uleb128((u64) func->locals.i64_count, &leb_len); + bh_buffer_append(buff, leb, leb_len); + bh_buffer_write_byte(buff, WASM_TYPE_INT64); + } + if (func->locals.f32_count != 0) { + leb = uint_to_uleb128((u64) func->locals.f32_count, &leb_len); + bh_buffer_append(buff, leb, leb_len); + bh_buffer_write_byte(buff, WASM_TYPE_FLOAT32); + } + if (func->locals.f64_count != 0) { + leb = uint_to_uleb128((u64) func->locals.f64_count, &leb_len); + bh_buffer_append(buff, leb, leb_len); + bh_buffer_write_byte(buff, WASM_TYPE_FLOAT64); + } + + return buff->length - prev_len; +} + +static void output_instruction(WasmInstruction* instr, bh_buffer* buff) { + i32 leb_len; + u8* leb; + switch (instr->type) { + case WI_LOCAL_GET: + case WI_LOCAL_SET: + bh_buffer_write_byte(buff, (u8) instr->type); + leb = uint_to_uleb128((u64) instr->data.i1, &leb_len); + bh_buffer_append(buff, leb, leb_len); + break; + + case WI_BLOCK_START: + bh_buffer_write_byte(buff, (u8) instr->type); + leb = uint_to_uleb128((u64) instr->data.i1, &leb_len); + bh_buffer_append(buff, leb, leb_len); + break; + + case WI_I32_CONST: + case WI_I64_CONST: + bh_buffer_write_byte(buff, (u8) instr->type); + bh_buffer_write_byte(buff, 0); // TODO: Actually output the literal + break; + + default: + bh_buffer_write_byte(buff, (u8) instr->type); + } +} + +static i32 output_code(WasmFunc* func, bh_buffer* buff) { + + bh_buffer code_buff; + bh_buffer_init(&code_buff, buff->allocator, 128); + + // Output locals + output_locals(func, &code_buff); + + // Output code + bh_arr_each(WasmInstruction, instr, func->code) output_instruction(instr, &code_buff); + + i32 leb_len; + u8* leb = uint_to_uleb128((u64) code_buff.length, &leb_len); + bh_buffer_append(buff, leb, leb_len); + + bh_buffer_concat(buff, code_buff); + bh_buffer_free(&code_buff); + + return 0; +} + static i32 output_codesection(OnyxWasmModule* module, bh_buffer* buff) { i32 prev_len = buff->length; @@ -707,8 +818,9 @@ static i32 output_codesection(OnyxWasmModule* module, bh_buffer* buff) { u8* leb = uint_to_uleb128((u64) bh_arr_length(module->funcs), &leb_len); bh_buffer_append(&vec_buff, leb, leb_len); - bh_arr_each(WasmFunc, func, module->funcs) { - } + // DEBUG_HERE; + + bh_arr_each(WasmFunc, func, module->funcs) output_code(func, &vec_buff); leb = uint_to_uleb128((u64) (vec_buff.length), &leb_len); bh_buffer_append(buff, leb, leb_len);