Lots of small changes; initial function calling
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 18 Jun 2020 00:09:13 +0000 (19:09 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 18 Jun 2020 00:09:13 +0000 (19:09 -0500)
include/bh.h
include/onyxparser.h
include/onyxwasm.h
onyx
progs/minimal.onyx
src/onyx.c
src/onyxlex.c
src/onyxparser.c
src/onyxutils.c
src/onyxwasm.c

index 9d6ea6d073e786dd21151f59fba4484b2411cc65..687b51ab4a99ba853b32a29fb83d852e62935c09 100644 (file)
@@ -535,12 +535,12 @@ void bh__arr_deleten(void **arr, i32 elemsize, i32 index, i32 numelems);
 
 
 //-------------------------------------------------------------------------------------
-// HASH TABLE FUNCTIONS
+// STRING HASH TABLE FUNCTIONS
 //-------------------------------------------------------------------------------------
-#ifndef BH_NO_HASHTABLE
+#ifndef BH_NO_TABLE
 
 #ifdef BH_DEFINE
-u64 bh__hash_function(const char* str, i32 len, i32 mod) {
+u64 bh__table_hash_function(const char* str, i32 len, i32 mod) {
        u64 hash = 5381;
        i32 c, l = 0;
        if (len == 0) len = ((u32) 1 << 31) - 1; // TODO: Verify this is right
@@ -553,62 +553,62 @@ u64 bh__hash_function(const char* str, i32 len, i32 mod) {
 }
 #endif
 
-typedef struct bh_hash_iterator {
+typedef struct bh_table_iterator {
        ptr *tab, *endtab;
        i32 elemsize, arrlen;
        ptr entry;
-} bh_hash_iterator;
+} bh_table_iterator;
 
-typedef struct bh__hash {
+typedef struct bh__table {
        bh_allocator allocator;
-       u64 hash_size; // NOTE: u64 since padding will make it 8-bytes no matter what
+       u64 table_size; // NOTE: u64 since padding will make it 8-bytes no matter what
        ptr arrs[];
-} bh__hash;
-
-#define bh_hash(T)             T*
-
-#ifdef BH_HASH_SIZE_SAFE
-       #define bh_hash_init(allocator_, tab, hs)       bh__hash_init(allocator_, (bh__hash **)&(tab), hs)
-       #define bh_hash_free(tab)                                       bh__hash_free((bh__hash **)&(tab))
-       #define bh_hash_put(T, tab, key, value)         (assert(sizeof(T) == sizeof(*(tab))), (*((T *) bh__hash_put((bh__hash *) tab, sizeof(T), key)) = (T) value))
-       #define bh_hash_has(T, tab, key)                        (assert(sizeof(T) == sizeof(*(tab))), (bh__hash_has((bh__hash *) tab, sizeof(T), key)))
-       #define bh_hash_get(T, tab, key)                        (assert(sizeof(T) == sizeof(*(tab))), (*((T *) bh__hash_get((bh__hash *) tab, sizeof(T), key))))
-       #define bh_hash_delete(T, tab, key)                     (assert(sizeof(T) == sizeof(*(tab))), bh__hash_delete((bh__hash *) tab, sizeof(T), key))
-       #define bh_hash_clear(tab)                                      (bh__hash_clear((bh__hash *) tab))
-
-       #define bh_hash_iter_setup(T, tab)                      (assert(sizeof(T) == sizeof(*(tab))), bh__hash_iter_setup((bh__hash *) tab, sizeof(T)))
-       #define bh_hash_iter_key(it)                            ((char *)(bh_pointer_add(it.entry, it.elemsize + sizeof(u16))))
-       #define bh_hash_iter_value(T, it)                       (*(T *)it.entry)
+} bh__table;
+
+#define bh_table(T)            T*
+
+#ifdef BH_TABLE_SIZE_SAFE
+       #define bh_table_init(allocator_, tab, hs)      bh__table_init(allocator_, (bh__table **)&(tab), hs)
+       #define bh_table_free(tab)                                      bh__table_free((bh__table **)&(tab))
+       #define bh_table_put(T, tab, key, value)        (assert(sizeof(T) == sizeof(*(tab))), (*((T *) bh__table_put((bh__table *) tab, sizeof(T), key)) = (T) value))
+       #define bh_table_has(T, tab, key)                       (assert(sizeof(T) == sizeof(*(tab))), (bh__table_has((bh__table *) tab, sizeof(T), key)))
+       #define bh_table_get(T, tab, key)                       (assert(sizeof(T) == sizeof(*(tab))), (*((T *) bh__table_get((bh__table *) tab, sizeof(T), key))))
+       #define bh_table_delete(T, tab, key)                    (assert(sizeof(T) == sizeof(*(tab))), bh__table_delete((bh__table *) tab, sizeof(T), key))
+       #define bh_table_clear(tab)                                     (bh__table_clear((bh__table *) tab))
+
+       #define bh_table_iter_setup(T, tab)                     (assert(sizeof(T) == sizeof(*(tab))), bh__table_iter_setup((bh__table *) tab, sizeof(T)))
+       #define bh_table_iter_key(it)                           ((char *)(bh_pointer_add(it.entry, it.elemsize + sizeof(u16))))
+       #define bh_table_iter_value(T, it)                      (*(T *)it.entry)
 #else
-       #define bh_hash_init(allocator_, tab, hs)       bh__hash_init(allocator_, (bh__hash **)&(tab), hs)
-       #define bh_hash_free(tab)                                       bh__hash_free((bh__hash **)&(tab))
-       #define bh_hash_put(T, tab, key, value)         (*((T *) bh__hash_put((bh__hash *) tab, sizeof(T), key)) = value)
-       #define bh_hash_has(T, tab, key)                        (bh__hash_has((bh__hash *) tab, sizeof(T), key))
-       #define bh_hash_get(T, tab, key)                        (*((T *) bh__hash_get((bh__hash *) tab, sizeof(T), key)))
-       #define bh_hash_delete(T, tab, key)                     (bh__hash_delete((bh__hash *) tab, sizeof(T), key))
-       #define bh_hash_clear(tab)                                      (bh__hash_clear((bh__hash *) tab))
-
-       #define bh_hash_iter_setup(T, tab)                      (bh__hash_iter_setup((bh__hash *) tab, sizeof(T)))
-       #define bh_hash_iter_key(it)                            ((char *)(bh_pointer_add(it.entry, it.elemsize + sizeof(u16))))
-       #define bh_hash_iter_value(T, it)                       (*(T *)it.entry)
+       #define bh_table_init(allocator_, tab, hs)      bh__table_init(allocator_, (bh__table **)&(tab), hs)
+       #define bh_table_free(tab)                                      bh__table_free((bh__table **)&(tab))
+       #define bh_table_put(T, tab, key, value)        (*((T *) bh__table_put((bh__table *) tab, sizeof(T), key)) = value)
+       #define bh_table_has(T, tab, key)                       (bh__table_has((bh__table *) tab, sizeof(T), key))
+       #define bh_table_get(T, tab, key)                       (*((T *) bh__table_get((bh__table *) tab, sizeof(T), key)))
+       #define bh_table_delete(T, tab, key)                    (bh__table_delete((bh__table *) tab, sizeof(T), key))
+       #define bh_table_clear(tab)                                     (bh__table_clear((bh__table *) tab))
+
+       #define bh_table_iter_setup(T, tab)                     (bh__table_iter_setup((bh__table *) tab, sizeof(T)))
+       #define bh_table_iter_key(it)                           ((char *)(bh_pointer_add(it.entry, it.elemsize + sizeof(u16))))
+       #define bh_table_iter_value(T, it)                      (*(T *)it.entry)
 #endif
 
-#define bh_hash_each_start(T, table) { \
-       bh_hash_iterator it = bh_hash_iter_setup(T, (table)); \
-       while (bh_hash_iter_next(&it)) { \
-               const char* key = bh_hash_iter_key(it); \
-               T value = bh_hash_iter_value(T, it);
-#define bh_hash_each_end                       } }
-
-b32 bh__hash_init(bh_allocator allocator, bh__hash **table, i32 hash_size);
-b32 bh__hash_free(bh__hash **table);
-ptr bh__hash_put(bh__hash *table, i32 elemsize, char *key);
-b32 bh__hash_has(bh__hash *table, i32 elemsize, char *key);
-ptr bh__hash_get(bh__hash *table, i32 elemsize, char *key);
-void bh__hash_delete(bh__hash *table, i32 elemsize, char *key);
-void bh__hash_clear(bh__hash *table);
-bh_hash_iterator bh__hash_iter_setup(bh__hash *table, i32 elemsize);
-b32 bh_hash_iter_next(bh_hash_iterator* it);
+#define bh_table_each_start(T, table) { \
+       bh_table_iterator it = bh_table_iter_setup(T, (table)); \
+       while (bh_table_iter_next(&it)) { \
+               const char* key = bh_table_iter_key(it); \
+               T value = bh_table_iter_value(T, it);
+#define bh_table_each_end                      } }
+
+b32 bh__table_init(bh_allocator allocator, bh__table **table, i32 table_size);
+b32 bh__table_free(bh__table **table);
+ptr bh__table_put(bh__table *table, i32 elemsize, char *key);
+b32 bh__table_has(bh__table *table, i32 elemsize, char *key);
+ptr bh__table_get(bh__table *table, i32 elemsize, char *key);
+void bh__table_delete(bh__table *table, i32 elemsize, char *key);
+void bh__table_clear(bh__table *table);
+bh_table_iterator bh__table_iter_setup(bh__table *table, i32 elemsize);
+b32 bh_table_iter_next(bh_table_iterator* it);
 
 #endif
 
@@ -616,6 +616,59 @@ b32 bh_hash_iter_next(bh_hash_iterator* it);
 
 
 
+
+
+
+
+//-------------------------------------------------------------------------------
+// IMAP (integer to integer map)
+//-------------------------------------------------------------------------------
+#ifndef BH_NO_IMAP
+
+typedef u64 bh_imap_key_t;
+
+typedef struct bh__imap_entry {
+    bh_imap_key_t key, value;
+} bh__imap_entry;
+
+typedef struct bh_imap {
+    bh_allocator allocator;
+    bh_arr(bh__imap_entry) keys;
+} bh_imap;
+
+
+void bh_imap_init(bh_imap* imap, bh_allocator alloc);
+void bh_imap_free(bh_imap* imap);
+void bh_imap_put(bh_imap* imap, bh_imap_key_t key, bh_imap_key_t value);
+b32 bh_imap_has(bh_imap* imap, bh_imap_key_t key);
+bh_imap_key_t bh_imap_get(bh_imap* imap, bh_imap_key_t key);
+void bh_imap_delete(bh_imap* imap, bh_imap_key_t key);
+
+#ifdef BH_DEFINE
+#endif // BH_DEFINE
+
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 
 //-------------------------------------------------------------------------------
 // OTHER COMMON DATA STRUCTURES
@@ -1608,6 +1661,7 @@ void bh__arr_insertn(void **arr, i32 elemsize, i32 index, i32 numelems) {
 
                bh__arr* arrptr = bh__arrhead(*arr);
                if (!bh__arr_grow(bh_arr_allocator(arr), arr, elemsize, arrptr->length + numelems)) return; // Fail case
+               arrptr = bh__arrhead(*arr);
                memmove(
                        (char *)(*arr) + elemsize * (index + numelems),
                        (char *)(*arr) + elemsize * index,
@@ -1633,26 +1687,26 @@ void bh__arr_insertn(void **arr, i32 elemsize, i32 index, i32 numelems) {
 
 
 //-------------------------------------------------------------------------------------
-// HASHTABLE IMPLEMENTATION
+// TABLE IMPLEMENTATION
 //-------------------------------------------------------------------------------------
-#ifndef BH_NO_HASHTABLE
+#ifndef BH_NO_TABLE
 
-b32 bh__hash_init(bh_allocator allocator, bh__hash **table, i32 hash_size) {
-       *table = bh_alloc(allocator, sizeof(bh__hash) + sizeof(ptr) * hash_size);
+b32 bh__table_init(bh_allocator allocator, bh__table **table, i32 table_size) {
+       *table = bh_alloc(allocator, sizeof(bh__table) + sizeof(ptr) * table_size);
        if (*table == NULL) return 0;
 
        (*table)->allocator = allocator;
-       (*table)->hash_size = hash_size;
+       (*table)->table_size = table_size;
 
-       for (i32 i = 0; i < hash_size; i++) {
+       for (i32 i = 0; i < table_size; i++) {
                (*table)->arrs[i] = NULL;
        }
 
        return 1;
 }
 
-b32 bh__hash_free(bh__hash **table) {
-       for (i32 i = 0; i < (*table)->hash_size; i++) {
+b32 bh__table_free(bh__table **table) {
+       for (i32 i = 0; i < (*table)->table_size; i++) {
                if ((*table)->arrs[i] != NULL) {
                        bh_arr_free((*table)->arrs[i]);
                }
@@ -1663,10 +1717,10 @@ b32 bh__hash_free(bh__hash **table) {
 }
 
 // Assumes NULL terminated string for key
-ptr bh__hash_put(bh__hash *table, i32 elemsize, char *key) {
+ptr bh__table_put(bh__table *table, i32 elemsize, char *key) {
        elemsize += (elemsize & 1);
 
-       u64 index = bh__hash_function(key, 0, table->hash_size);
+       u64 index = bh__table_hash_function(key, 0, table->table_size);
        u8 arr_was_new = 0;
 
        ptr arrptr = table->arrs[index];
@@ -1716,10 +1770,10 @@ found_matching:
        return bh_pointer_add(arrptr, -(sizeof(u16) + elemsize));
 }
 
-b32 bh__hash_has(bh__hash *table, i32 elemsize, char *key) {
+b32 bh__table_has(bh__table *table, i32 elemsize, char *key) {
        elemsize += (elemsize & 1);
 
-       u64 index = bh__hash_function(key, 0, table->hash_size);
+       u64 index = bh__table_hash_function(key, 0, table->table_size);
 
        ptr arrptr = table->arrs[index];
        if (arrptr == NULL) return 0;
@@ -1739,10 +1793,10 @@ b32 bh__hash_has(bh__hash *table, i32 elemsize, char *key) {
        return 0;
 }
 
-ptr bh__hash_get(bh__hash *table, i32 elemsize, char *key) {
+ptr bh__table_get(bh__table *table, i32 elemsize, char *key) {
        elemsize += (elemsize & 1);
 
-       u64 index = bh__hash_function(key, 0, table->hash_size);
+       u64 index = bh__table_hash_function(key, 0, table->table_size);
 
        ptr arrptr = table->arrs[index];
        if (arrptr == NULL) return 0;
@@ -1764,10 +1818,10 @@ ptr bh__hash_get(bh__hash *table, i32 elemsize, char *key) {
        return NULL;
 }
 
-void bh__hash_delete(bh__hash *table, i32 elemsize, char *key) {
+void bh__table_delete(bh__table *table, i32 elemsize, char *key) {
        elemsize += (elemsize & 1);
 
-       u64 index = bh__hash_function(key, 0, table->hash_size);
+       u64 index = bh__table_hash_function(key, 0, table->table_size);
 
        ptr arrptr = table->arrs[index], walker;
        if (arrptr == NULL) return; // Didn't exist
@@ -1801,8 +1855,8 @@ found_matching:
        (*(u64 *) arrptr)--;
 }
 
-void bh__hash_clear(bh__hash *table) {
-       for (i32 i = 0; i < table->hash_size; i++) {
+void bh__table_clear(bh__table *table) {
+       for (i32 i = 0; i < table->table_size; i++) {
                if (table->arrs[i] != NULL) {
                        // NOTE: Set length property to 0
                        *((u64 *) table->arrs[i]) = 0;
@@ -1811,19 +1865,19 @@ void bh__hash_clear(bh__hash *table) {
        }
 }
 
-bh_hash_iterator bh__hash_iter_setup(bh__hash *table, i32 elemsize) {
+bh_table_iterator bh__table_iter_setup(bh__table *table, i32 elemsize) {
        elemsize += (elemsize & 1);
 
-       bh_hash_iterator it = {
+       bh_table_iterator it = {
                .tab = table->arrs,
-               .endtab = table->arrs + table->hash_size,
+               .endtab = table->arrs + table->table_size,
                .elemsize = elemsize,
                .entry = NULL
        };
        return it;
 }
 
-b32 bh_hash_iter_next(bh_hash_iterator* it) {
+b32 bh_table_iter_next(bh_table_iterator* it) {
        if (it->tab == NULL) return 0;
 
        if (it->entry != NULL) {
@@ -1858,6 +1912,88 @@ step_to_next:
 
 #endif // ifndef BH_NO_HASHTABLE
 
+
+
+//-------------------------------------------------------------------------------------
+// IMAP IMPLEMENTATION
+//-------------------------------------------------------------------------------------
+#ifndef BH_NO_IMAP
+void bh_imap_init(bh_imap* imap, bh_allocator alloc) {
+    imap->allocator = alloc;
+    imap->keys = NULL;
+
+    bh_arr_new(alloc, imap->keys, 4);
+}
+
+void bh_imap_free(bh_imap* imap) {
+    bh_arr_free(imap->keys);
+    imap->keys = NULL;
+}
+
+b32 bh__imap_get_index(bh_imap* imap, bh_imap_key_t key, i32* pos) {
+    i32 low = 0;
+    i32 high = bh_arr_length(imap->keys);
+    i32 middle = 0;
+    bh__imap_entry tmp;
+
+    while (high > low) {
+        middle = (high + low) / 2;
+        tmp = imap->keys[middle];
+
+        if (tmp.key == key) {
+            if (pos) *pos = middle;
+            return 1;
+        } else if (tmp.key < key) {
+            low = middle + 1;
+            middle++;
+        } else if (tmp.key > key) {
+            high = middle;
+        }
+    }
+
+    if (pos) *pos = middle;
+    return 0;
+}
+
+void bh_imap_put(bh_imap* imap, bh_imap_key_t key, bh_imap_key_t value) {
+    i32 middle = 0;
+    b32 found_existing = bh__imap_get_index(imap, key, &middle);
+
+    if (found_existing) {
+        imap->keys[middle].value = value;
+    } else {
+        bh_arr_insertn(imap->keys, middle, 1);
+        imap->keys[middle].key = key;
+        imap->keys[middle].value = value;
+    }
+}
+
+b32 bh_imap_has(bh_imap* imap, bh_imap_key_t key) {
+    return bh__imap_get_index(imap, key, NULL);
+}
+
+bh_imap_key_t bh_imap_get(bh_imap* imap, bh_imap_key_t key) {
+    i32 middle = 0;
+    b32 found_existing = bh__imap_get_index(imap, key, &middle);
+
+    if (found_existing) {
+        return imap->keys[middle].value;
+    } else {
+        return 0;
+    }
+}
+
+void bh_imap_delete(bh_imap* imap, bh_imap_key_t key) {
+    i32 middle = 0;
+    b32 found_existing = bh__imap_get_index(imap, key, &middle);
+
+    if (found_existing) {
+        bh_arr_deleten(imap->keys, middle, 1);
+    }
+}
+
+#endif // ifndef BH_NO_IMAP
+
 #endif // ifdef BH_DEFINE
 
 #endif // ifndef BH_H
index 631fc0925a8468d8f9f03903bc4d355e337f545a..47786d40c125dbc4bb7f201614d0c1f36f7f2d03 100644 (file)
@@ -1,7 +1,6 @@
 #ifndef ONYXPARSER_H
 #define ONYXPARSER_H
 
-#define BH_NO_STRING
 #include "bh.h"
 
 #include "onyxlex.h"
@@ -27,7 +26,7 @@ typedef struct OnyxParser {
        // NOTE: A table of the current identifiers in the current scope.
        // If the identifier doesn't at the time of parsing, it is an error.
        // Cleared at the end of a block.
-       bh_hash(OnyxAstNode*) identifiers;
+       bh_table(OnyxAstNode*) identifiers;
        OnyxAstNodeScope *curr_scope;
 
        OnyxMessages *msgs;
index 4f7cf685fe2c3dd2414d572739903dcb1f18715c..52e0c74ad8b639c35943d8d1d74e6e5dc96e847c 100644 (file)
@@ -1,7 +1,6 @@
 #ifndef ONYXWASM_H
 #define ONYXWASM_H
 
-#define BH_NO_STRING
 #include "bh.h"
 
 #include "onyxparser.h"
@@ -266,20 +265,22 @@ typedef struct OnyxWasmModule {
        bh_allocator allocator;
 
        // NOTE: Mapping to local indicies currently in scope.
-       bh_hash(i32) local_map;
+       bh_table(i32) local_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.
-       bh_hash(i32) type_map;
+       bh_table(i32) type_map;
        i32 next_type_idx;
        // NOTE: This have to be pointers because the type is variadic in size
        bh_arr(WasmFuncType*) functypes;
 
        bh_arr(WasmFunc) funcs;
+    // NOTE: Maps from ast node pointers to the function index
+    bh_imap func_map;
        i32 next_func_idx;
 
-       bh_hash(WasmExport) exports;
+       bh_table(WasmExport) exports;
        i32 export_count;
 } OnyxWasmModule;
 
diff --git a/onyx b/onyx
index 54fb7e20cea62187341433b97188c40a2131f32b..cbaebf60c297e57c8c59b1e6365c1cc2420cfaf0 100755 (executable)
Binary files a/onyx and b/onyx differ
index 79fa48570564b7d57b7798edbde0a0aec241ebd8..e19b7ed2c8a018e7b7a466942cbadc071b359f5d 100644 (file)
@@ -1,13 +1,12 @@
-
-export add :: proc (a i32, b i32) -> i32 {
-       return a + b;
+foo :: proc () -> i32 {
+       return 10 as i32;
 }
 
-export foo :: proc (foo i32, bar i32) -> i32 {
-       return 10 as i32;
+add :: proc (a i32, b i32) -> i32 {
+       return a + b;
 }
 
-export diff_square :: proc (a i32, b i32) -> i32 {
+diff_square :: proc (a i32, b i32) -> i32 {
        // Typechecked
        c := a - b; // Mutable
        d :: a + b; // Constant
@@ -15,6 +14,12 @@ export diff_square :: proc (a i32, b i32) -> i32 {
        return (c * d) as i32;
 }
 
+export do_stuff :: proc () -> i32 {
+       res := diff_square((2 + 3) as i32, (4 + 5) as i32);
+       res = res + foo();
+    return res;
+}
+
 export main :: proc () {
-       add(2, 3);
+    output :: do_stuff();
 }
index c55a7b311db64b72005a8bf2b6c54ce8cb416342..5a07b655b7d83728ca14f969cdb526c4ab0e2655 100644 (file)
@@ -1,4 +1,3 @@
-#define BH_NO_STRING
 // #define BH_DEBUG
 #define BH_DEFINE
 #include "bh.h"
@@ -52,9 +51,9 @@ int main(int argc, char *argv[]) {
                onyx_message_print(&msgs);
                goto main_exit;
        } else {
-               // onyx_ast_print(program, 0);
-               bh_printf("\nNo errors.\n");
-       }
+               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.
index 0a4c3035d6b186a93b8560bad503ef49b01acaf0..9e9a0104b5e2f6036a912276e012b4ea124f9fe3 100644 (file)
@@ -57,8 +57,8 @@ static const char* onyx_token_type_names[] = {
 };
 
 #ifndef LITERAL_TOKEN
-#define LITERAL_TOKEN(token, token_type) \
-       if (token_lit(tokenizer, &tk, token, token_type)) goto token_parsed;
+#define LITERAL_TOKEN(token, word, token_type) \
+       if (token_lit(tokenizer, &tk, token, word, token_type)) goto token_parsed;
 #endif
 
 #ifndef INCREMENT_CURR_TOKEN
@@ -71,9 +71,12 @@ static const char* onyx_token_type_names[] = {
 }
 #endif
 
-static b32 token_lit(OnyxTokenizer* tokenizer, OnyxToken* tk, char* lit, OnyxTokenType type) {
+static b32 token_lit(OnyxTokenizer* tokenizer, OnyxToken* tk, char* lit, b32 is_word, OnyxTokenType type) {
        i64 len = chars_match(tokenizer->curr, lit);
        if (len > 0) {
+        if (is_word && char_is_alphanum(*(tokenizer->curr + len)) || charset_contains("_$", *(tokenizer->curr + len)))
+            return 0;
+
                tk->type = type;
                tk->token = tokenizer->curr;
                tk->length = len;
@@ -131,45 +134,45 @@ OnyxToken* onyx_get_token(OnyxTokenizer* tokenizer) {
                goto token_parsed;
        }
 
-       LITERAL_TOKEN("struct", TOKEN_TYPE_KEYWORD_STRUCT);
-       LITERAL_TOKEN("export", TOKEN_TYPE_KEYWORD_EXPORT);
-       LITERAL_TOKEN("use", TOKEN_TYPE_KEYWORD_USE);
-       LITERAL_TOKEN("if", TOKEN_TYPE_KEYWORD_IF);
-       LITERAL_TOKEN("else", TOKEN_TYPE_KEYWORD_ELSE);
-       LITERAL_TOKEN("foreign", TOKEN_TYPE_KEYWORD_FOREIGN);
-       LITERAL_TOKEN("for", TOKEN_TYPE_KEYWORD_FOR);
-       LITERAL_TOKEN("return", TOKEN_TYPE_KEYWORD_RETURN);
-       LITERAL_TOKEN("do", TOKEN_TYPE_KEYWORD_DO);
-       LITERAL_TOKEN("proc", TOKEN_TYPE_KEYWORD_PROC);
-       LITERAL_TOKEN("global", TOKEN_TYPE_KEYWORD_GLOBAL);
-       LITERAL_TOKEN("as", TOKEN_TYPE_KEYWORD_CAST);
-       LITERAL_TOKEN("->", TOKEN_TYPE_RIGHT_ARROW);
-       LITERAL_TOKEN("<-", TOKEN_TYPE_RIGHT_ARROW);
-       LITERAL_TOKEN("<=", TOKEN_TYPE_SYM_LESS_EQUAL);
-       LITERAL_TOKEN(">=", TOKEN_TYPE_SYM_GREATER_EQUAL);
-       LITERAL_TOKEN("(", TOKEN_TYPE_OPEN_PAREN);
-       LITERAL_TOKEN(")", TOKEN_TYPE_CLOSE_PAREN);
-       LITERAL_TOKEN("{", TOKEN_TYPE_OPEN_BRACE);
-       LITERAL_TOKEN("}", TOKEN_TYPE_CLOSE_BRACE);
-       LITERAL_TOKEN("[", TOKEN_TYPE_OPEN_BRACKET);
-       LITERAL_TOKEN("]", TOKEN_TYPE_CLOSE_BRACKET);
-       LITERAL_TOKEN("+", TOKEN_TYPE_SYM_PLUS);
-       LITERAL_TOKEN("-", TOKEN_TYPE_SYM_MINUS);
-       LITERAL_TOKEN("*", TOKEN_TYPE_SYM_STAR);
-       LITERAL_TOKEN(".", TOKEN_TYPE_SYM_DOT);
-       LITERAL_TOKEN("%", TOKEN_TYPE_SYM_PERCENT);
-       LITERAL_TOKEN("/", TOKEN_TYPE_SYM_FSLASH);
-       LITERAL_TOKEN("\\", TOKEN_TYPE_SYM_BSLASH);
-       LITERAL_TOKEN(":", TOKEN_TYPE_SYM_COLON);
-       LITERAL_TOKEN(";", TOKEN_TYPE_SYM_SEMICOLON);
-       LITERAL_TOKEN(",", TOKEN_TYPE_SYM_COMMA);
-       LITERAL_TOKEN(">", TOKEN_TYPE_SYM_GREATER);
-       LITERAL_TOKEN("<", TOKEN_TYPE_SYM_LESS);
-       LITERAL_TOKEN("=", TOKEN_TYPE_SYM_EQUALS);
-       LITERAL_TOKEN("~", TOKEN_TYPE_SYM_TILDE);
-       LITERAL_TOKEN("!", TOKEN_TYPE_SYM_BANG);
-       LITERAL_TOKEN("^", TOKEN_TYPE_SYM_CARET);
-       LITERAL_TOKEN("&", TOKEN_TYPE_SYM_AMPERSAND);
+       LITERAL_TOKEN("struct",  1, TOKEN_TYPE_KEYWORD_STRUCT);
+       LITERAL_TOKEN("export",  1, TOKEN_TYPE_KEYWORD_EXPORT);
+       LITERAL_TOKEN("use",     1, TOKEN_TYPE_KEYWORD_USE);
+       LITERAL_TOKEN("if",      1, TOKEN_TYPE_KEYWORD_IF);
+       LITERAL_TOKEN("else",    1, TOKEN_TYPE_KEYWORD_ELSE);
+       LITERAL_TOKEN("foreign", 1, TOKEN_TYPE_KEYWORD_FOREIGN);
+       LITERAL_TOKEN("for",     1, TOKEN_TYPE_KEYWORD_FOR);
+       LITERAL_TOKEN("return",  1, TOKEN_TYPE_KEYWORD_RETURN);
+       LITERAL_TOKEN("do",      1, TOKEN_TYPE_KEYWORD_DO);
+       LITERAL_TOKEN("proc",    1, TOKEN_TYPE_KEYWORD_PROC);
+       LITERAL_TOKEN("global",  1, TOKEN_TYPE_KEYWORD_GLOBAL);
+       LITERAL_TOKEN("as",      1, TOKEN_TYPE_KEYWORD_CAST);
+       LITERAL_TOKEN("->",      0, TOKEN_TYPE_RIGHT_ARROW);
+       LITERAL_TOKEN("<-",      0, TOKEN_TYPE_RIGHT_ARROW);
+       LITERAL_TOKEN("<=",      0, TOKEN_TYPE_SYM_LESS_EQUAL);
+       LITERAL_TOKEN(">=",      0, TOKEN_TYPE_SYM_GREATER_EQUAL);
+       LITERAL_TOKEN("(",       0, TOKEN_TYPE_OPEN_PAREN);
+       LITERAL_TOKEN(")",       0, TOKEN_TYPE_CLOSE_PAREN);
+       LITERAL_TOKEN("{",       0, TOKEN_TYPE_OPEN_BRACE);
+       LITERAL_TOKEN("}",       0, TOKEN_TYPE_CLOSE_BRACE);
+       LITERAL_TOKEN("[",       0, TOKEN_TYPE_OPEN_BRACKET);
+       LITERAL_TOKEN("]",       0, TOKEN_TYPE_CLOSE_BRACKET);
+       LITERAL_TOKEN("+",       0, TOKEN_TYPE_SYM_PLUS);
+       LITERAL_TOKEN("-",       0, TOKEN_TYPE_SYM_MINUS);
+       LITERAL_TOKEN("*",       0, TOKEN_TYPE_SYM_STAR);
+       LITERAL_TOKEN(".",       0, TOKEN_TYPE_SYM_DOT);
+       LITERAL_TOKEN("%",       0, TOKEN_TYPE_SYM_PERCENT);
+       LITERAL_TOKEN("/",       0, TOKEN_TYPE_SYM_FSLASH);
+       LITERAL_TOKEN("\\",      0, TOKEN_TYPE_SYM_BSLASH);
+       LITERAL_TOKEN(":",       0, TOKEN_TYPE_SYM_COLON);
+       LITERAL_TOKEN(";",       0, TOKEN_TYPE_SYM_SEMICOLON);
+       LITERAL_TOKEN(",",       0, TOKEN_TYPE_SYM_COMMA);
+       LITERAL_TOKEN(">",       0, TOKEN_TYPE_SYM_GREATER);
+       LITERAL_TOKEN("<",       0, TOKEN_TYPE_SYM_LESS);
+       LITERAL_TOKEN("=",       0, TOKEN_TYPE_SYM_EQUALS);
+       LITERAL_TOKEN("~",       0, TOKEN_TYPE_SYM_TILDE);
+       LITERAL_TOKEN("!",       0, TOKEN_TYPE_SYM_BANG);
+       LITERAL_TOKEN("^",       0, TOKEN_TYPE_SYM_CARET);
+       LITERAL_TOKEN("&",       0, TOKEN_TYPE_SYM_AMPERSAND);
 
        // Symbols
        if (char_is_alpha(*tk.token)) {
index dff9dbba464bc47ba165428947b6d762f1da1a48..b2fa36848851591628d8129698560363cbdf65ad 100644 (file)
@@ -153,8 +153,8 @@ static OnyxAstNode* lookup_identifier(OnyxParser* parser, OnyxToken* token) {
        OnyxAstNode* ident = NULL;
 
        onyx_token_null_toggle(*token);
-       if (bh_hash_has(OnyxAstNode*, parser->identifiers, token->token)) {
-               ident = bh_hash_get(OnyxAstNode*, parser->identifiers, token->token);
+       if (bh_table_has(OnyxAstNode*, parser->identifiers, token->token)) {
+               ident = bh_table_get(OnyxAstNode*, parser->identifiers, token->token);
        }
        onyx_token_null_toggle(*token);
 
@@ -170,11 +170,11 @@ static void insert_identifier(OnyxParser* parser, OnyxAstNode* ident, b32 is_loc
        }
 
        onyx_token_null_toggle(*local->token);
-       if (bh_hash_has(OnyxAstNode*, parser->identifiers, local->token->token)) {
-               local->shadowed = bh_hash_get(OnyxAstNode*, parser->identifiers, local->token->token);
+       if (bh_table_has(OnyxAstNode*, parser->identifiers, local->token->token)) {
+               local->shadowed = bh_table_get(OnyxAstNode*, parser->identifiers, local->token->token);
        }
 
-       bh_hash_put(OnyxAstNodeLocal*, parser->identifiers, local->token->token, local);
+       bh_table_put(OnyxAstNodeLocal*, parser->identifiers, local->token->token, local);
        onyx_token_null_toggle(*local->token);
 }
 
@@ -183,9 +183,9 @@ static void remove_identifier(OnyxParser* parser, OnyxAstNode* ident) {
 
        onyx_token_null_toggle(*local->token);
        if (local->shadowed) {
-               bh_hash_put(OnyxAstNode*, parser->identifiers, local->token->token, local->shadowed);
+               bh_table_put(OnyxAstNode*, parser->identifiers, local->token->token, local->shadowed);
        } else {
-               bh_hash_delete(OnyxAstNode*, parser->identifiers, local->token->token);
+               bh_table_delete(OnyxAstNode*, parser->identifiers, local->token->token);
        }
        onyx_token_null_toggle(*local->token);
 }
@@ -221,6 +221,10 @@ static OnyxAstNode* parse_factor(OnyxParser* parser) {
 
                                OnyxAstNodeCall* call_node = (OnyxAstNodeCall *) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_CALL);
                                call_node->callee = sym_node;
+                               // NOTE: Return type is stored on function definition's type
+                               // This may have to change if we want multiple returns
+                               call_node->type = sym_node->type;
+
                                OnyxAstNode** prev = &call_node->arguments;
                                OnyxAstNode* curr = NULL;
                                while (parser->curr_token->type != TOKEN_TYPE_CLOSE_PAREN) {
@@ -301,6 +305,11 @@ static OnyxAstNode* parse_bin_op(OnyxParser* parser, OnyxAstNode* left) {
                bin_op->left = left;
                bin_op->right = right;
                bin_op->type = left->type;
+
+               if ((left->flags & ONYX_AST_FLAG_COMPTIME) != 0 && (right->flags & ONYX_AST_FLAG_COMPTIME) != 0) {
+                       bin_op->flags |= ONYX_AST_FLAG_COMPTIME;
+               }
+
                return bin_op;
        }
 
@@ -561,10 +570,10 @@ static OnyxTypeInfo* parse_type(OnyxParser* parser) {
 
        onyx_token_null_toggle(*symbol);
 
-       if (!bh_hash_has(OnyxAstNode*, parser->identifiers, symbol->token)) {
+       if (!bh_table_has(OnyxAstNode*, parser->identifiers, symbol->token)) {
                onyx_message_add(parser->msgs, ONYX_MESSAGE_TYPE_UNKNOWN_TYPE, symbol->pos, symbol->token);
        } else {
-               OnyxAstNode* type_info_node = bh_hash_get(OnyxAstNode*, parser->identifiers, symbol->token);
+               OnyxAstNode* type_info_node = bh_table_get(OnyxAstNode*, parser->identifiers, symbol->token);
 
                if (type_info_node->kind == ONYX_AST_NODE_KIND_TYPE) {
                        type_info = type_info_node->type;
@@ -676,8 +685,8 @@ static OnyxAstNode* parse_top_level_statement(OnyxParser* parser) {
 
                                        onyx_token_null_toggle(*symbol);
 
-                                       if (!bh_hash_has(OnyxAstNode *, parser->identifiers, symbol->token)) {
-                                               bh_hash_put(OnyxAstNode *, parser->identifiers, symbol->token, (OnyxAstNode *) func_def);
+                                       if (!bh_table_has(OnyxAstNode *, parser->identifiers, symbol->token)) {
+                                               bh_table_put(OnyxAstNode *, parser->identifiers, symbol->token, (OnyxAstNode *) func_def);
                                        } else {
                                                onyx_message_add(parser->msgs,
                                                                ONYX_MESSAGE_TYPE_FUNCTION_REDEFINITION,
@@ -735,13 +744,13 @@ OnyxAstNode* onyx_ast_node_new(bh_allocator alloc, OnyxAstNodeKind kind) {\
 OnyxParser onyx_parser_create(bh_allocator alloc, OnyxTokenizer *tokenizer, OnyxMessages* msgs) {
        OnyxParser parser;
 
-       bh_hash_init(bh_heap_allocator(), parser.identifiers, 61);
+       bh_table_init(bh_heap_allocator(), parser.identifiers, 61);
 
        OnyxTypeInfo* it = &builtin_types[0];
        while (it->kind != 0xffffffff) {
                OnyxAstNode* tmp = onyx_ast_node_new(alloc, ONYX_AST_NODE_KIND_TYPE);
                tmp->type = it;
-               bh_hash_put(OnyxAstNode*, parser.identifiers, (char *)it->name, tmp);
+               bh_table_put(OnyxAstNode*, parser.identifiers, (char *)it->name, tmp);
                it++;
        }
 
@@ -756,7 +765,7 @@ OnyxParser onyx_parser_create(bh_allocator alloc, OnyxTokenizer *tokenizer, Onyx
 }
 
 void onyx_parser_free(OnyxParser* parser) {
-       bh_hash_free(parser->identifiers);
+       bh_table_free(parser->identifiers);
 }
 
 OnyxAstNode* onyx_parse(OnyxParser *parser) {
index ba50b4eec8fc2bea2fd50dfc9320b005926b1810..74aecf9d992b8191b5854987a5372f187875b3ee 100644 (file)
@@ -98,6 +98,9 @@ void onyx_ast_print(OnyxAstNode* node, i32 indent) {
 
        case ONYX_AST_NODE_KIND_LITERAL: {
                bh_printf("%b", node->token->token, node->token->length);
+               if (node->next) {
+                       onyx_ast_print(node->next, indent);
+               }
                break;
        }
 
@@ -110,6 +113,16 @@ void onyx_ast_print(OnyxAstNode* node, i32 indent) {
                break;
        }
 
+       case ONYX_AST_NODE_KIND_CALL: {
+               OnyxAstNodeCall* call = &node->as_call;
+               bh_printf("%b", call->callee->token->token, call->callee->token->length);
+               onyx_ast_print(call->arguments, indent + 1);
+               if (call->next) {
+                       onyx_ast_print(call->next, indent);
+               }
+               break;
+       }
+
        default: {
                onyx_ast_print(node->left, indent + 1);
                onyx_ast_print(node->right, indent + 1);
index 2dcff896e0bdfc55cfbdf91cdcf0ddeb60fffed0..e30fae20dd0b52a5ad458acd003e1393e24bea4b 100644 (file)
@@ -249,7 +249,7 @@ static void process_statement(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNode*
 static void process_assign_lval(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNode* lval) {
        if (lval->kind == ONYX_AST_NODE_KIND_LOCAL || lval->kind == ONYX_AST_NODE_KIND_PARAM) {
                onyx_token_null_toggle(*lval->token);
-               i32 localidx = bh_hash_get(i32, mod->local_map, lval->token->token);
+               i32 localidx = bh_table_get(i32, mod->local_map, lval->token->token);
                onyx_token_null_toggle(*lval->token);
 
                bh_arr_push(func->code, ((WasmInstruction){ WI_LOCAL_SET, localidx }));
@@ -339,7 +339,7 @@ static void process_expression(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNode*
                case ONYX_AST_NODE_KIND_PARAM:
                        {
                                onyx_token_null_toggle(*expr->token);
-                               i32 localidx = bh_hash_get(i32, mod->local_map, expr->token->token);
+                               i32 localidx = bh_table_get(i32, mod->local_map, expr->token->token);
                                onyx_token_null_toggle(*expr->token);
 
                                bh_arr_push(func->code, ((WasmInstruction){ WI_LOCAL_GET, localidx }));
@@ -360,7 +360,14 @@ static void process_expression(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNode*
 
                case ONYX_AST_NODE_KIND_CALL:
                        {
-                               DEBUG_HERE;
+                               OnyxAstNodeCall* call = &expr->as_call;
+                               forll (OnyxAstNode, arg, call->arguments, next) {
+                                       process_expression(mod, func, arg);
+                               }
+
+                i32 func_idx = (i32) bh_imap_get(&mod->func_map, (u64) call->callee);
+                bh_arr_push(func->code, ((WasmInstruction){ WI_CALL, func_idx }));
+
                                break;
                        }
 
@@ -442,8 +449,8 @@ static void process_function_definition(OnyxWasmModule* mod, OnyxAstNodeFuncDef*
        *t = '\0';
 
        i32 type_idx = 0;
-       if (bh_hash_has(i32, mod->type_map, type_repr_buf)) {
-               type_idx = bh_hash_get(i32, mod->type_map, type_repr_buf);
+       if (bh_table_has(i32, mod->type_map, type_repr_buf)) {
+               type_idx = bh_table_get(i32, mod->type_map, type_repr_buf);
        } else {
                // NOTE: Make a new type
                // TODO: Ensure that this isn't going to break things because of alignment
@@ -456,7 +463,7 @@ static void process_function_definition(OnyxWasmModule* mod, OnyxAstNodeFuncDef*
 
                bh_arr_push(mod->functypes, type);
 
-               bh_hash_put(i32, mod->type_map, type_repr_buf, mod->next_type_idx);
+               bh_table_put(i32, mod->type_map, type_repr_buf, mod->next_type_idx);
                type_idx = mod->next_type_idx;
                mod->next_type_idx++;
        }
@@ -472,6 +479,7 @@ static void process_function_definition(OnyxWasmModule* mod, OnyxAstNodeFuncDef*
                .code = NULL,
        };
        i32 func_idx = mod->next_func_idx++;
+    bh_imap_put(&mod->func_map, (u64) fd, func_idx);
 
        if (fd->flags & ONYX_AST_FLAG_EXPORTED) {
                onyx_token_null_toggle(*fd->token);
@@ -480,7 +488,7 @@ static void process_function_definition(OnyxWasmModule* mod, OnyxAstNodeFuncDef*
                        .kind = WASM_EXPORT_FUNCTION,
                        .idx = func_idx,
                };
-               bh_hash_put(WasmExport, mod->exports, fd->token->token, wasm_export);
+               bh_table_put(WasmExport, mod->exports, fd->token->token, wasm_export);
                mod->export_count++;
 
                onyx_token_null_toggle(*fd->token);
@@ -493,7 +501,7 @@ static void process_function_definition(OnyxWasmModule* mod, OnyxAstNodeFuncDef*
        i32 localidx = 0;
        forll (OnyxAstNodeParam, param, fd->params, next) {
                onyx_token_null_toggle(*param->token);
-               bh_hash_put(i32, mod->local_map, param->token->token, localidx++);
+               bh_table_put(i32, mod->local_map, param->token->token, localidx++);
                onyx_token_null_toggle(*param->token);
        }
 
@@ -506,7 +514,7 @@ static void process_function_definition(OnyxWasmModule* mod, OnyxAstNodeFuncDef*
                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++);
+                               bh_table_put(i32, mod->local_map, local->token->token, localidx++);
                                onyx_token_null_toggle(*local->token);
 
                                (*count)++;
@@ -522,7 +530,7 @@ static void process_function_definition(OnyxWasmModule* mod, OnyxAstNodeFuncDef*
        bh_arr_push(mod->funcs, wasm_func);
 
        // NOTE: Clear the local map on exit of generating this function
-       bh_hash_clear(mod->local_map);
+       bh_table_clear(mod->local_map);
 }
 
 OnyxWasmModule onyx_wasm_generate_module(bh_allocator alloc, OnyxAstNode* program) {
@@ -543,9 +551,11 @@ OnyxWasmModule onyx_wasm_generate_module(bh_allocator alloc, OnyxAstNode* progra
        bh_arr_new(alloc, module.functypes, 4);
        bh_arr_new(alloc, module.funcs, 4);
 
-       bh_hash_init(bh_heap_allocator(), module.local_map, 61);
-       bh_hash_init(bh_heap_allocator(), module.type_map, 61);
-       bh_hash_init(bh_heap_allocator(), module.exports, 61);
+       bh_table_init(bh_heap_allocator(), module.local_map, 61);
+       bh_table_init(bh_heap_allocator(), module.type_map, 61);
+       bh_table_init(bh_heap_allocator(), module.exports, 61);
+
+    bh_imap_init(&module.func_map, bh_heap_allocator());
 
        OnyxAstNode* walker = program;
        while (walker) {
@@ -565,9 +575,9 @@ OnyxWasmModule onyx_wasm_generate_module(bh_allocator alloc, OnyxAstNode* progra
 void onyx_wasm_module_free(OnyxWasmModule* module) {
        bh_arr_free(module->functypes);
        bh_arr_free(module->funcs);
-       bh_hash_free(module->local_map);
-       bh_hash_free(module->type_map);
-       bh_hash_free(module->exports);
+       bh_table_free(module->local_map);
+       bh_table_free(module->type_map);
+       bh_table_free(module->exports);
 }
 
 
@@ -690,7 +700,7 @@ static i32 output_exportsection(OnyxWasmModule* module, bh_buffer* buff) {
        bh_buffer_append(&vec_buff, leb, leb_len);
 
        i32 key_len = 0;
-       bh_hash_each_start(WasmExport, module->exports);
+       bh_table_each_start(WasmExport, module->exports);
                key_len = strlen(key);
                leb = uint_to_uleb128((u64) key_len, &leb_len);
                bh_buffer_append(&vec_buff, leb, leb_len);
@@ -699,7 +709,7 @@ static i32 output_exportsection(OnyxWasmModule* module, bh_buffer* buff) {
                bh_buffer_write_byte(&vec_buff, (u8) (value.kind));
                leb = uint_to_uleb128((u64) value.idx, &leb_len);
                bh_buffer_append(&vec_buff, leb, leb_len);
-       bh_hash_each_end;
+       bh_table_each_end;
 
        leb = uint_to_uleb128((u64) (vec_buff.length), &leb_len);
        bh_buffer_append(buff, leb, leb_len);
@@ -714,14 +724,14 @@ 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) {
+       bh_table_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;
+       } bh_table_each_end;
 
        if (start_idx != -1) {
                bh_buffer_write_byte(buff, WASM_SECTION_ID_START);
@@ -799,6 +809,12 @@ static void output_instruction(WasmInstruction* instr, bh_buffer* buff) {
                        bh_buffer_write_byte(buff, 0); // TODO: Actually output the literal
                        break;
 
+        case WI_CALL:
+            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;
+
                default:
                        bh_buffer_write_byte(buff, (u8) instr->type);
        }