Added procedure declarations at the expression level; properly using elems now
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 27 Jul 2020 21:37:39 +0000 (16:37 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 27 Jul 2020 21:37:39 +0000 (16:37 -0500)
include/onyxwasm.h
onyx
progs/ez.onyx
progs/fcf.onyx
src/onyxparser.c
src/onyxwasm.c

index 72a5493e5c214f1f54b90753d9e0bc8f94d56c4d..c8e4831e88e1cbd0dd2b6b4131aa11ee006a8075 100644 (file)
@@ -295,6 +295,9 @@ typedef struct OnyxWasmModule {
     // NOTE: Mapping from local ast node ptrs to indicies
     bh_imap local_map;
 
+    // NOTE: Mapping ptrs to elements
+    bh_imap elem_map;
+
     // NOTE: Used internally as a map from strings that represent function types,
     // 0x7f 0x7f : 0x7f ( (i32, i32) -> i32 )
     // to the function type index if it has been created.
@@ -308,15 +311,16 @@ typedef struct OnyxWasmModule {
     bh_arr(WasmGlobal)    globals;
     bh_arr(WasmFunc)      funcs;
     bh_arr(WasmDatum)     data;
+    bh_arr(i32)           elems;
 
-    u32 next_type_idx;
     u32 export_count;
-    u32 element_count;
+    u32 next_type_idx;
     u32 next_func_idx;
     u32 next_foreign_func_idx;
     u32 next_global_idx;
     u32 next_foreign_global_idx;
     u32 next_datum_offset;
+    u32 next_elem_idx;
 } OnyxWasmModule;
 
 OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc);
diff --git a/onyx b/onyx
index 5691a378a7c311f3b29a4a1352769f9ce575a5a7..4865923646d7e8f1f9a5ddd670b6a63fb449c24b 100755 (executable)
Binary files a/onyx and b/onyx differ
index e4f056cb5116e640fd6238e6353a7be1d9945091..061cf1029064a37eae5b0de3c1a2c8b0873f035d 100644 (file)
@@ -14,7 +14,7 @@ Foo :: struct {
 }
 
 foo_sum :: proc (use this: ^Foo) -> i32 {
-    this.foo_other();
+    foo_other(this);
     return x + y;
 }
 
@@ -62,7 +62,7 @@ proc #export "main" {
     foo.st = st;
     print(alignof Foo);
     print(sizeof Foo);
-    print(foo.foo_sum());
+    print(foo_sum(foo));
     print_st(foo.st, 20);
 
     pa := (__heap_start as i32 + sizeof Foo) as ^PrintableArray;
index f043423fadb39a36fae023f6f5e9fb66da0e3248..f8eea8f8e67e7d0f9ca0b4488b31197e37c9acd9 100644 (file)
@@ -30,6 +30,18 @@ echo :: proc (i: i32) -> i32 {
     return i;
 }
 
+I32Array :: struct {
+    length : i32;
+    data   : ^i32;
+}
+
+array_map :: proc (arr: I32Array, map: proc (i32) -> i32) {
+    for i: 0, arr.length arr.data[i] = map(arr.data[i]);
+}
+
+minus_one :: proc (n: i32) -> i32 { return n - 1; }
+double :: proc (n: i32) -> i32 { return n << 1; }
+
 proc #export "main" {
        call_me(echo, 10);
 
@@ -48,4 +60,14 @@ proc #export "main" {
     dc.right = 19;
 
     print(execute(dc));
+
+    len :: 10;
+    data := (__heap_start as i32 + sizeof DeferredCall) as ^i32;
+    for i: 0, len data[i] = i;
+    print(data as [] i32, len);
+
+    add_one :: proc (n: i32) -> i32 { return n + 1; };
+
+    array_map(len, data, add_one);
+    print(data as [] i32, len);
 }
index 7555e23789f4a14383b9175541459ab5e1b171bb..6ea6d391c629dd07bb0dbbe60b949135541c5973 100644 (file)
@@ -255,6 +255,16 @@ static AstTyped* parse_factor(OnyxParser* parser) {
             break;
         }
 
+        case Token_Type_Keyword_Proc: {
+            retval = (AstTyped *) parse_function_definition(parser);
+            retval->flags |= Ast_Flag_Function_Used;
+
+            // TODO: Maybe move this somewhere else?
+            add_node_to_process(parser, (AstNode *) retval);
+
+            break;
+        }
+
         default:
             onyx_message_add(Msg_Type_Unexpected_Token,
                     parser->curr->pos,
index 56afd0455e7131642bcc7291e4a84c89e774c0fd..687e27b6b73c0d66420c6dadabf07ed54cc56696 100644 (file)
@@ -240,6 +240,7 @@ static WasmType onyx_type_to_wasm_type(Type* type) {
 }
 
 static i32 generate_type_idx(OnyxWasmModule* mod, Type* ft);
+static i32 get_element_idx(OnyxWasmModule* mod, AstFunction* func);
 
 #define WI(instr) bh_arr_push(code, ((WasmInstruction){ instr, 0x00 }))
 #define WID(instr, data) bh_arr_push(code, ((WasmInstruction){ instr, data }))
@@ -915,8 +916,8 @@ COMPILE_FUNC(expression, AstTyped* expr) {
         }
 
         case Ast_Kind_Function: {
-            i32 funcidx = bh_imap_get(&mod->index_map, (u64) expr);
-            WID(WI_I32_CONST, funcidx);
+            i32 elemidx = get_element_idx(mod, (AstFunction *) expr);
+            WID(WI_I32_CONST, elemidx);
             break;
         }
 
@@ -1192,6 +1193,22 @@ static i32 generate_type_idx(OnyxWasmModule* mod, Type* ft) {
     return type_idx;
 }
 
+static i32 get_element_idx(OnyxWasmModule* mod, AstFunction* func) {
+    if (bh_imap_has(&mod->elem_map, (u64) func)) {
+        return bh_imap_get(&mod->elem_map, (u64) func);
+    } else {
+        i32 idx = mod->next_elem_idx;
+        bh_imap_put(&mod->elem_map, (u64) func, idx);
+
+        i32 func_idx = bh_imap_get(&mod->index_map, (u64) func);
+        bh_arr_push(mod->elems, func_idx);
+
+        mod->next_elem_idx++;
+
+        return idx;
+    }
+}
+
 static inline b32 should_compile_function(AstFunction* fd) {
     // NOTE: Don't output intrinsic functions
     if (fd->flags & Ast_Flag_Intrinsic) return 0;
@@ -1431,7 +1448,8 @@ OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc) {
         .data = NULL,
         .next_datum_offset = 0,
 
-        .element_count = 0,
+        .elems = NULL,
+        .next_elem_idx = 0,
 
         .structured_jump_target = NULL,
     };
@@ -1441,6 +1459,7 @@ OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc) {
     bh_arr_new(alloc, module.imports, 4);
     bh_arr_new(alloc, module.globals, 4);
     bh_arr_new(alloc, module.data, 4);
+    bh_arr_new(alloc, module.elems, 4);
 
     // NOTE: 16 is probably needlessly large
     bh_arr_new(global_heap_allocator, module.structured_jump_target, 16);
@@ -1451,6 +1470,7 @@ OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc) {
 
     bh_imap_init(&module.index_map, global_heap_allocator, 128);
     bh_imap_init(&module.local_map, global_heap_allocator, 16);
+    bh_imap_init(&module.elem_map,  global_heap_allocator, 16);
 
     return module;
 }
@@ -1470,7 +1490,6 @@ void onyx_wasm_module_compile(OnyxWasmModule* module, ProgramInfo* program) {
         switch (entity->type) {
             case Entity_Type_Function_Header: {
                 if (!should_compile_function(entity->function)) break;
-                module->element_count++;
 
                 u64 func_idx;
                 if ((entity->function->flags & Ast_Flag_Foreign) != 0)
@@ -1670,6 +1689,8 @@ static i32 output_funcsection(OnyxWasmModule* module, bh_buffer* buff) {
 }
 
 static i32 output_tablesection(OnyxWasmModule* module, bh_buffer* buff) {
+    if (bh_arr_length(module->elems) == 0) return 0;
+
     i32 prev_len = buff->length;
     bh_buffer_write_byte(buff, WASM_SECTION_ID_TABLE);
 
@@ -1682,7 +1703,7 @@ static i32 output_tablesection(OnyxWasmModule* module, bh_buffer* buff) {
 
     // NOTE: funcrefs are the only valid table element type
     bh_buffer_write_byte(&vec_buff, 0x70);
-    output_limits(module->element_count, -1, &vec_buff);
+    output_limits(bh_arr_length(module->elems), -1, &vec_buff);
 
     leb = uint_to_uleb128((u64) (vec_buff.length), &leb_len);
     bh_buffer_append(buff, leb, leb_len);
@@ -1839,6 +1860,8 @@ static i32 output_startsection(OnyxWasmModule* module, bh_buffer* buff) {
 }
 
 static i32 output_elemsection(OnyxWasmModule* module, bh_buffer* buff) {
+    if (bh_arr_length(module->elems) == 0) return 0;
+
     i32 prev_len = buff->length;
 
     bh_buffer_write_byte(buff, WASM_SECTION_ID_ELEMENT);
@@ -1846,8 +1869,6 @@ static i32 output_elemsection(OnyxWasmModule* module, bh_buffer* buff) {
     bh_buffer vec_buff;
     bh_buffer_init(&vec_buff, buff->allocator, 128);
 
-    u32 func_count = bh_arr_length(module->funcs) + module->next_foreign_func_idx;
-
     i32 leb_len;
     u8* leb;
 
@@ -1861,11 +1882,11 @@ static i32 output_elemsection(OnyxWasmModule* module, bh_buffer* buff) {
     bh_buffer_write_byte(&vec_buff, 0x00);
     bh_buffer_write_byte(&vec_buff, WI_BLOCK_END);
 
-    leb = uint_to_uleb128((u64) func_count, &leb_len);
+    leb = uint_to_uleb128((u64) bh_arr_length(module->elems), &leb_len);
     bh_buffer_append(&vec_buff, leb, leb_len);
 
-    fori (funcidx, 0, func_count - 1) {
-        leb = uint_to_uleb128((u64) funcidx, &leb_len);
+    bh_arr_each(i32, elem, module->elems) {
+        leb = uint_to_uleb128((u64) *elem, &leb_len);
         bh_buffer_append(&vec_buff, leb, leb_len);
     }