GENERATING A WORKING BINARY!
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 15 Jun 2020 16:02:31 +0000 (11:02 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 15 Jun 2020 16:02:31 +0000 (11:02 -0500)
onyx
progs/minimal.onyx
src/onyxparser.c
src/onyxwasm.c

diff --git a/onyx b/onyx
index eb95d4a86bb1df2067243c148fd329359f830082..532e9c8dca6cd6f33c97a34c8a62fb2c9bacbc7a 100755 (executable)
Binary files a/onyx and b/onyx differ
index 1f1f75f5141c0c008369370dd81c608131841358..ba83edb0ce98601f2caf7f198bcf6b2d4703f797 100644 (file)
@@ -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 () { }
index c271c0f697014030178d608ca20534656421d2bb..00530182a2dcfadd5d742198fed1109d932ab69b 100644 (file)
@@ -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);
index b719acbe76e740de56a131e728680a1ddc14601f..35aabd435d2a7534e6ca41bd4f69835adff1cdf4 100644 (file)
@@ -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);