MAJOR bug fix with binop code generation
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 26 Jun 2020 19:57:42 +0000 (14:57 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 26 Jun 2020 19:57:42 +0000 (14:57 -0500)
include/bh.h
include/onyxparser.h
include/onyxwasm.h
onyx
progs/test.onyx
src/onyxwasm.c

index f528ad26023efae00da3feb907e02df7345c7382..455c79635d27ecb046a5a7448df99d1a1514a4c9 100644 (file)
@@ -470,49 +470,49 @@ typedef struct bh__arr {
 } bh__arr;
 
 #ifndef BH_ARR_GROW_FORMULA
-#define BH_ARR_GROW_FORMULA(x)        ((x) > 0 ? ((x) << 1) : 4)
+#define BH_ARR_GROW_FORMULA(x)       ((x) > 0 ? ((x) << 1) : 4)
 #endif
 
 #define bh_arr(T)                    T*
-#define bh__arrhead(arr)            (((bh__arr *)(arr)) - 1)
+#define bh__arrhead(arr)             (((bh__arr *)(arr)) - 1)
 
 #define bh_arr_allocator(arr)        (arr ? bh__arrhead(arr)->allocator : bh_heap_allocator())
-#define bh_arr_length(arr)             (arr ? bh__arrhead(arr)->length : 0)
+#define bh_arr_length(arr)           (arr ? bh__arrhead(arr)->length : 0)
 #define bh_arr_capacity(arr)         (arr ? bh__arrhead(arr)->capacity : 0)
-#define bh_arr_size(arr)            (arr ? bh__arrhead(arr)->capacity * sizeof(*(arr)) : 0)
-#define bh_arr_valid(arr, i)        (arr ? (i32)(i) < bh__arrhead(arr)->length : 0)
+#define bh_arr_size(arr)             (arr ? bh__arrhead(arr)->capacity * sizeof(*(arr)) : 0)
+#define bh_arr_valid(arr, i)         (arr ? (i32)(i) < bh__arrhead(arr)->length : 0)
 
-#define bh_arr_pop(arr)                ((arr)[--bh__arrhead(arr)->length])
-#define bh_arr_last(arr)            ((arr)[bh__arrhead(arr)->length - 1])
-#define bh_arr_end(arr, i)            ((i) >= &(arr)[bh_arr_length(arr)])
+#define bh_arr_pop(arr)              ((arr)[--bh__arrhead(arr)->length])
+#define bh_arr_last(arr)             ((arr)[bh__arrhead(arr)->length - 1])
+#define bh_arr_end(arr, i)           ((i) >= &(arr)[bh_arr_length(arr)])
 
 #define bh_arr_new(allocator_, arr, cap)    (bh__arr_grow((allocator_), (void**) &(arr), sizeof(*(arr)), cap))
 #define bh_arr_free(arr)                    (bh__arr_free((void**) &(arr)))
 #define bh_arr_copy(allocator_, arr)        (bh__arr_copy((allocator_), (arr), sizeof(*(arr))))
 
-#define bh_arr_grow(arr, cap)         (bh__arr_grow(bh_arr_allocator(arr), (void **) &(arr), sizeof(*(arr)), cap))
+#define bh_arr_grow(arr, cap)          (bh__arr_grow(bh_arr_allocator(arr), (void **) &(arr), sizeof(*(arr)), cap))
 #define bh_arr_shrink(arr, cap)        (bh__arr_shrink((void **) &(arr), sizeof(*(arr)), cap))
-#define bh_arr_set_length(arr, n)    ( \
+#define bh_arr_set_length(arr, n)      ( \
     bh__arr_grow(bh_arr_allocator(arr), (void **) &(arr), sizeof(*(arr)), n), \
     bh__arrhead(arr)->length = n)
 
-#define bh_arr_insertn(arr, i, n)    (bh__arr_insertn((void **) &(arr), sizeof(*(arr)), i, n))
+#define bh_arr_insertn(arr, i, n)      (bh__arr_insertn((void **) &(arr), sizeof(*(arr)), i, n))
 
-#define bh_arr_insert_end(arr, n)    ( \
+#define bh_arr_insert_end(arr, n)      ( \
     bh__arr_grow(bh_arr_allocator(arr), (void **) &(arr), sizeof(*(arr)), bh_arr_length(arr) + n), \
     bh__arrhead(arr)->length += n)
 
-#define bh_arr_push(arr, value)     ( \
+#define bh_arr_push(arr, value)       ( \
     bh__arr_grow(bh_arr_allocator(arr), (void **) &(arr), sizeof(*(arr)), bh_arr_length(arr) + 1), \
     arr[bh__arrhead(arr)->length++] = value)
 
-#define bh_arr_is_empty(arr)        (arr ? bh__arrhead(arr)->length == 0 : 1)
-#define bh_arr_clear(arr)            (arr ? (bh__arrhead(arr)->length = 0) : 0)
+#define bh_arr_is_empty(arr)          (arr ? bh__arrhead(arr)->length == 0 : 1)
+#define bh_arr_clear(arr)             (arr ? (bh__arrhead(arr)->length = 0) : 0)
 
-#define bh_arr_deleten(arr, i, n)    (bh__arr_deleten((void **) &(arr), sizeof(*(arr)), i, n))
-#define bh_arr_fastdelete(arr, i)    (arr[i] = arr[--bh__arrhead(arr)->length])
+#define bh_arr_deleten(arr, i, n)     (bh__arr_deleten((void **) &(arr), sizeof(*(arr)), i, n))
+#define bh_arr_fastdelete(arr, i)     (arr[i] = arr[--bh__arrhead(arr)->length])
 
-#define bh_arr_each(T, var, arr)            for (T* var = (arr); !bh_arr_end((arr), var); var++)
+#define bh_arr_each(T, var, arr)      for (T* var = (arr); !bh_arr_end((arr), var); var++)
 
 b32 bh__arr_grow(bh_allocator alloc, void** arr, i32 elemsize, i32 cap);
 b32 bh__arr_shrink(void** arr, i32 elemsize, i32 cap);
@@ -570,26 +570,26 @@ typedef struct bh__table {
 #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_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_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)) = (T) 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_put(T, tab, key, value)      (*((T *) bh__table_put((bh__table *) tab, sizeof(T), key)) = (T) 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
 
index 94e934bcfda186968cffdf506cecba769a112590..521a195f6004797f72f8b1a87966fbdddbcbea60 100644 (file)
@@ -110,18 +110,18 @@ typedef enum OnyxUnaryOp {
 } OnyxUnaryOp;
 
 typedef enum OnyxBinaryOp {
-    ONYX_BINARY_OP_ADD,
-    ONYX_BINARY_OP_MINUS,
-    ONYX_BINARY_OP_MULTIPLY,
-    ONYX_BINARY_OP_DIVIDE,
-    ONYX_BINARY_OP_MODULUS,
-
-    ONYX_BINARY_OP_EQUAL,
-    ONYX_BINARY_OP_NOT_EQUAL,
-    ONYX_BINARY_OP_LESS,
-    ONYX_BINARY_OP_LESS_EQUAL,
-    ONYX_BINARY_OP_GREATER,
-    ONYX_BINARY_OP_GREATER_EQUAL,
+    ONYX_BINARY_OP_ADD           = 0,
+    ONYX_BINARY_OP_MINUS         = 1,
+    ONYX_BINARY_OP_MULTIPLY      = 2,
+    ONYX_BINARY_OP_DIVIDE        = 3,
+    ONYX_BINARY_OP_MODULUS       = 4,
+
+    ONYX_BINARY_OP_EQUAL         = 5,
+    ONYX_BINARY_OP_NOT_EQUAL     = 6,
+    ONYX_BINARY_OP_LESS          = 7,
+    ONYX_BINARY_OP_LESS_EQUAL    = 8,
+    ONYX_BINARY_OP_GREATER       = 9,
+    ONYX_BINARY_OP_GREATER_EQUAL = 10,
 } OnyxBinaryOp;
 
 struct OnyxAstNodeBinOp {
index f73d1b1b575ba56b817cb35e3ceb6b493862597a..b86e2c5a9aad00d9218d18f149cc1141c6a55461 100644 (file)
@@ -27,170 +27,170 @@ typedef enum WasmInstructionType {
 
     // NOTE: Control flow
     WI_BLOCK_START                    = 0x02,
-    WI_BLOCK_END                    = 0x0B, // NOTE: These ends are not unique
-    WI_LOOP_START                    = 0x03,
-    WI_LOOP_END                        = 0x0B,
-    WI_IF_START                        = 0x04,
-    WI_ELSE                            = 0x05,
-    WI_IF_END                        = 0x0B,
-    WI_JUMP                            = 0x0C,
-    WI_COND_JUMP                    = 0x0D,
-    WI_JUMP_TABLE                    = 0x0E,
-    WI_RETURN                        = 0x0F,
-    WI_CALL                            = 0x10,
-    WI_CALL_INDIRECT                = 0x11,
+    WI_BLOCK_END                      = 0x0B, // NOTE: These ends are not unique
+    WI_LOOP_START                     = 0x03,
+    WI_LOOP_END                       = 0x0B,
+    WI_IF_START                       = 0x04,
+    WI_ELSE                           = 0x05,
+    WI_IF_END                         = 0x0B,
+    WI_JUMP                           = 0x0C,
+    WI_COND_JUMP                      = 0x0D,
+    WI_JUMP_TABLE                     = 0x0E,
+    WI_RETURN                         = 0x0F,
+    WI_CALL                           = 0x10,
+    WI_CALL_INDIRECT                  = 0x11,
 
     // NOTE: Parametric instructions
-    WI_DROP                            = 0x1A,
-    WI_SELECT                        = 0x1B,
+    WI_DROP                           = 0x1A,
+    WI_SELECT                         = 0x1B,
 
     // NOTE: Variable instructions
-    WI_LOCAL_GET                    = 0x20,
-    WI_LOCAL_SET                    = 0x21,
-    WI_LOCAL_TEE                    = 0x22,
-    WI_GLOBAL_GET                    = 0x23,
-    WI_GLOBAL_SET                    = 0x24,
+    WI_LOCAL_GET                      = 0x20,
+    WI_LOCAL_SET                      = 0x21,
+    WI_LOCAL_TEE                      = 0x22,
+    WI_GLOBAL_GET                     = 0x23,
+    WI_GLOBAL_SET                     = 0x24,
 
     // NOTE: Memory instructions
-    WI_I32_LOAD                        = 0x28,
-    WI_I64_LOAD                        = 0x29,
-    WI_F32_LOAD                        = 0x2A,
-    WI_F64_LOAD                        = 0x2B,
-    WI_I32_LOAD_8_S                    = 0x2C,
-    WI_I32_LOAD_8_U                    = 0x2D,
-    WI_I32_LOAD_16_S                = 0x2E,
-    WI_I32_LOAD_16_U                = 0x2F,
-    WI_I64_LOAD_8_S                    = 0x30,
-    WI_I64_LOAD_8_U                    = 0x31,
-    WI_I64_LOAD_16_S                = 0x32,
-    WI_I64_LOAD_16_U                = 0x33,
-    WI_I64_LOAD_32_S                = 0x34,
-    WI_I64_LOAD_32_U                = 0x35,
-    WI_I32_STORE                    = 0x36,
-    WI_I64_STORE                    = 0x37,
-    WI_F32_STORE                    = 0x38,
-    WI_F64_STORE                    = 0x39,
+    WI_I32_LOAD                       = 0x28,
+    WI_I64_LOAD                       = 0x29,
+    WI_F32_LOAD                       = 0x2A,
+    WI_F64_LOAD                       = 0x2B,
+    WI_I32_LOAD_8_S                   = 0x2C,
+    WI_I32_LOAD_8_U                   = 0x2D,
+    WI_I32_LOAD_16_S                  = 0x2E,
+    WI_I32_LOAD_16_U                  = 0x2F,
+    WI_I64_LOAD_8_S                   = 0x30,
+    WI_I64_LOAD_8_U                   = 0x31,
+    WI_I64_LOAD_16_S                  = 0x32,
+    WI_I64_LOAD_16_U                  = 0x33,
+    WI_I64_LOAD_32_S                  = 0x34,
+    WI_I64_LOAD_32_U                  = 0x35,
+    WI_I32_STORE                      = 0x36,
+    WI_I64_STORE                      = 0x37,
+    WI_F32_STORE                      = 0x38,
+    WI_F64_STORE                      = 0x39,
     WI_I32_STORE_8                    = 0x3A,
-    WI_I32_STORE_16                    = 0x3B,
+    WI_I32_STORE_16                   = 0x3B,
     WI_I64_STORE_8                    = 0x3C,
-    WI_I64_STORE_16                    = 0x3D,
-    WI_I64_STORE_32                    = 0x3E,
+    WI_I64_STORE_16                   = 0x3D,
+    WI_I64_STORE_32                   = 0x3E,
     WI_MEMORY_SIZE                    = 0x3F,
     WI_MEMORY_GROW                    = 0x40,
 
     // NOTE: Numeric Instructions
-    WI_I32_CONST                    = 0x41,
-    WI_I64_CONST                    = 0x42,
-    WI_F32_CONST                    = 0x43,
-    WI_F64_CONST                    = 0x44,
-
-    WI_I32_EQZ                        = 0x45, // NOTE: Autoincremented from here
-    WI_I32_EQ,
-    WI_I32_NE,
-    WI_I32_LT_S,
-    WI_I32_LT_U,
-    WI_I32_GT_S,
-    WI_I32_GT_U,
-    WI_I32_LE_S,
-    WI_I32_LE_U,
-    WI_I32_GE_S,
-    WI_I32_GE_U,
-
-    WI_I64_EQZ,
-    WI_I64_EQ,
-    WI_I64_NE,
-    WI_I64_LT_S,
-    WI_I64_LT_U,
-    WI_I64_GT_S,
-    WI_I64_GT_U,
-    WI_I64_LE_S,
-    WI_I64_LE_U,
-    WI_I64_GE_S,
-    WI_I64_GE_U,
-
-    WI_F32_EQ,
-    WI_F32_NE,
-    WI_F32_LT,
-    WI_F32_GT,
-    WI_F32_LE,
-    WI_F32_GE,
-
-    WI_F64_EQ,
-    WI_F64_NE,
-    WI_F64_LT,
-    WI_F64_GT,
-    WI_F64_LE,
-    WI_F64_GE,
-
-    WI_I32_CLZ,
-    WI_I32_CTZ,
-    WI_I32_POPCNT,
-    WI_I32_ADD,
-    WI_I32_SUB,
-    WI_I32_MUL,
-    WI_I32_DIV_S,
-    WI_I32_DIV_U,
-    WI_I32_REM_S,
-    WI_I32_REM_U,
-    WI_I32_AND,
-    WI_I32_OR,
-    WI_I32_XOR,
-    WI_I32_SHL,
-    WI_I32_SHR_S,
-    WI_I32_SHR_U,
-    WI_I32_ROTL,
-    WI_I32_ROTR,
-
-    WI_I64_CLZ,
-    WI_I64_CTZ,
-    WI_I64_POPCNT,
-    WI_I64_ADD,
-    WI_I64_SUB,
-    WI_I64_MUL,
-    WI_I64_DIV_S,
-    WI_I64_DIV_U,
-    WI_I64_REM_S,
-    WI_I64_REM_U,
-    WI_I64_AND,
-    WI_I64_OR,
-    WI_I64_XOR,
-    WI_I64_SHL,
-    WI_I64_SHR_S,
-    WI_I64_SHR_U,
-    WI_I64_ROTL,
-    WI_I64_ROTR,
-
-    WI_F32_ABS,
-    WI_F32_NEG,
-    WI_F32_CEIL,
-    WI_F32_FLOOR,
-    WI_F32_TRUNC,
-    WI_F32_NEAREST,
-    WI_F32_SQRT,
-    WI_F32_ADD,
-    WI_F32_SUB,
-    WI_F32_MUL,
-    WI_F32_DIV,
-    WI_F32_MIN,
-    WI_F32_MAX,
-    WI_F32_COPYSIGN,
-
-    WI_F64_ABS,
-    WI_F64_NEG,
-    WI_F64_CEIL,
-    WI_F64_FLOOR,
-    WI_F64_TRUNC,
-    WI_F64_NEAREST,
-    WI_F64_SQRT,
-    WI_F64_ADD,
-    WI_F64_SUB,
-    WI_F64_MUL,
-    WI_F64_DIV,
-    WI_F64_MIN,
-    WI_F64_MAX,
-    WI_F64_COPYSIGN,
-
-    WI_I32_FROM_I64                    = 0xA7,
+    WI_I32_CONST                      = 0x41,
+    WI_I64_CONST                      = 0x42,
+    WI_F32_CONST                      = 0x43,
+    WI_F64_CONST                      = 0x44,
+
+    WI_I32_EQZ                        = 0x45,
+    WI_I32_EQ                         = 0x46,
+    WI_I32_NE                         = 0x47,
+    WI_I32_LT_S                       = 0x48,
+    WI_I32_LT_U                       = 0x49,
+    WI_I32_GT_S                       = 0x4a,
+    WI_I32_GT_U                       = 0x4b,
+    WI_I32_LE_S                       = 0x4c,
+    WI_I32_LE_U                       = 0x4d,
+    WI_I32_GE_S                       = 0x4e,
+    WI_I32_GE_U                       = 0x4f,
+
+    WI_I64_EQZ                        = 0x50,
+    WI_I64_EQ                         = 0x51,
+    WI_I64_NE                         = 0x52,
+    WI_I64_LT_S                       = 0x53,
+    WI_I64_LT_U                       = 0x54,
+    WI_I64_GT_S                       = 0x55,
+    WI_I64_GT_U                       = 0x56,
+    WI_I64_LE_S                       = 0x57,
+    WI_I64_LE_U                       = 0x58,
+    WI_I64_GE_S                       = 0x59,
+    WI_I64_GE_U                       = 0x5a,
+
+    WI_F32_EQ                         = 0x5b,
+    WI_F32_NE                         = 0x5c,
+    WI_F32_LT                         = 0x5d,
+    WI_F32_GT                         = 0x5e,
+    WI_F32_LE                         = 0x5f,
+    WI_F32_GE                         = 0x60,
+
+    WI_F64_EQ                         = 0x61,
+    WI_F64_NE                         = 0x62,
+    WI_F64_LT                         = 0x63,
+    WI_F64_GT                         = 0x64,
+    WI_F64_LE                         = 0x65,
+    WI_F64_GE                         = 0x66,
+
+    WI_I32_CLZ                        = 0x67,
+    WI_I32_CTZ                        = 0x68,
+    WI_I32_POPCNT                     = 0x69,
+    WI_I32_ADD                        = 0x6a,
+    WI_I32_SUB                        = 0x6b,
+    WI_I32_MUL                        = 0x6c,
+    WI_I32_DIV_S                      = 0x6d,
+    WI_I32_DIV_U                      = 0x6e,
+    WI_I32_REM_S                      = 0x6f,
+    WI_I32_REM_U                      = 0x70,
+    WI_I32_AND                        = 0x71,
+    WI_I32_OR                         = 0x72,
+    WI_I32_XOR                        = 0x73,
+    WI_I32_SHL                        = 0x74,
+    WI_I32_SHR_S                      = 0x75,
+    WI_I32_SHR_U                      = 0x76,
+    WI_I32_ROTL                       = 0x77,
+    WI_I32_ROTR                       = 0x78,
+
+    WI_I64_CLZ                        = 0x79,
+    WI_I64_CTZ                        = 0x7a,
+    WI_I64_POPCNT                     = 0x7b,
+    WI_I64_ADD                        = 0x7c,
+    WI_I64_SUB                        = 0x7d,
+    WI_I64_MUL                        = 0x7e,
+    WI_I64_DIV_S                      = 0x7f,
+    WI_I64_DIV_U                      = 0x80,
+    WI_I64_REM_S                      = 0x81,
+    WI_I64_REM_U                      = 0x82,
+    WI_I64_AND                        = 0x83,
+    WI_I64_OR                         = 0x84,
+    WI_I64_XOR                        = 0x85,
+    WI_I64_SHL                        = 0x86,
+    WI_I64_SHR_S                      = 0x87,
+    WI_I64_SHR_U                      = 0x88,
+    WI_I64_ROTL                       = 0x89,
+    WI_I64_ROTR                       = 0x8a,
+
+    WI_F32_ABS                        = 0x8b,
+    WI_F32_NEG                        = 0x8c,
+    WI_F32_CEIL                       = 0x8d,
+    WI_F32_FLOOR                      = 0x8e,
+    WI_F32_TRUNC                      = 0x8f,
+    WI_F32_NEAREST                    = 0x90,
+    WI_F32_SQRT                       = 0x91,
+    WI_F32_ADD                        = 0x92,
+    WI_F32_SUB                        = 0x93,
+    WI_F32_MUL                        = 0x94,
+    WI_F32_DIV                        = 0x95,
+    WI_F32_MIN                        = 0x96,
+    WI_F32_MAX                        = 0x97,
+    WI_F32_COPYSIGN                   = 0x98,
+
+    WI_F64_ABS                        = 0x99,
+    WI_F64_NEG                        = 0x9a,
+    WI_F64_CEIL                       = 0x9b,
+    WI_F64_FLOOR                      = 0x9c,
+    WI_F64_TRUNC                      = 0x9d,
+    WI_F64_NEAREST                    = 0x9e,
+    WI_F64_SQRT                       = 0x9f,
+    WI_F64_ADD                        = 0xA0,
+    WI_F64_SUB                        = 0xA1,
+    WI_F64_MUL                        = 0xA2,
+    WI_F64_DIV                        = 0xA3,
+    WI_F64_MIN                        = 0xA4,
+    WI_F64_MAX                        = 0xA5,
+    WI_F64_COPYSIGN                   = 0xA6,
+
+    WI_I32_FROM_I64                  = 0xA7,
     WI_I32_FROM_F32_S                = 0xA8,
     WI_I32_FROM_F32_U                = 0xA9,
     WI_I32_FROM_F64_S                = 0xAA,
@@ -207,18 +207,18 @@ typedef enum WasmInstructionType {
     WI_F32_FROM_I32_U                = 0xB3,
     WI_F32_FROM_I64_S                = 0xB4,
     WI_F32_FROM_I64_U                = 0xB5,
-    WI_F32_FROM_F64                    = 0xB6,
+    WI_F32_FROM_F64                  = 0xB6,
 
     WI_F64_FROM_I32_S                = 0xB7,
     WI_F64_FROM_I32_U                = 0xB8,
     WI_F64_FROM_I64_S                = 0xB9,
     WI_F64_FROM_I64_U                = 0xBA,
-    WI_F64_FROM_F32                    = 0xBB,
+    WI_F64_FROM_F32                  = 0xBB,
 
-    WI_I32_REINTERPRET_F32            = 0xBC,
-    WI_I64_REINTERPRET_F64            = 0xBD,
-    WI_F32_REINTERPRET_I32            = 0xBE,
-    WI_F64_REINTERPRET_I64            = 0xBF,
+    WI_I32_REINTERPRET_F32           = 0xBC,
+    WI_I64_REINTERPRET_F64           = 0xBD,
+    WI_F32_REINTERPRET_I32           = 0xBE,
+    WI_F64_REINTERPRET_I64           = 0xBF,
 } WasmInstructionType;
 
 typedef union {
@@ -250,8 +250,8 @@ typedef struct WasmFunc {
 } WasmFunc;
 
 typedef enum WasmForeignKind {
-    WASM_FOREIGN_FUNCTION = 0x00,
-    WASM_FOREIGN_TABLE     = 0x01,
+    WASM_FOREIGN_FUNCTION   = 0x00,
+    WASM_FOREIGN_TABLE      = 0x01,
     WASM_FOREIGN_MEMORY     = 0x02,
     WASM_FOREIGN_GLOBAL     = 0x03,
 } WasmForeignKind;
@@ -273,6 +273,8 @@ typedef struct OnyxWasmModule {
     // NOTE: Mapping from local ast node ptrs to indicies
     bh_imap local_map;
 
+    bh_arr(u8) structured_jump_target;
+
     // 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.
diff --git a/onyx b/onyx
index 9ce36fd1abca2cc2cf9e0f4ffedaf81a7e5a9ce4..1342320070f7dec55390d54d1e1f8bfc7d38de45 100755 (executable)
Binary files a/onyx and b/onyx differ
index db4a5d46a7c4b186b9a894e85f456602b6767af3..b0b72f5b04857b7862e7781a1d55d119d6dd49be 100644 (file)
@@ -36,10 +36,17 @@ export main :: proc {
 
         x = 0;
         while x < 5 {
+            if x == 3 {
+                x = x + 1;
+                continue;
+            }
+
             print_i32((x + y * 5) % 10);
             x = x + 1;
         }
 
+        if y > 2 { break; }
+
         y = y + 1;
     }
 }
index eec71c03043ebe7aed6141a592bb62fd4789db64..01c369f0d47d8b19d747d4833481c0a5cb9647d8 100644 (file)
@@ -241,6 +241,28 @@ static void compile_block(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNodeBlock*
     bh_arr_push(func->code, ((WasmInstruction){ WI_BLOCK_END, 0x00 }));
 }
 
+static void compile_structured_jump(OnyxWasmModule* mod, WasmFunc* func, b32 jump_backward) {
+    i32 labelidx = 0;
+    u8 wanted = jump_backward ? 2 : 1;
+    b32 success = 0;
+
+    i32 len = bh_arr_length(mod->structured_jump_target) - 1;
+    for (u8* t = &bh_arr_last(mod->structured_jump_target); len >= 0; len--, t--) {
+        if (*t == wanted) {
+            success = 1;
+            break;
+        }
+
+        labelidx++;
+    }
+
+    if (success) {
+        bh_arr_push(func->code, ((WasmInstruction){ WI_JUMP, labelidx }));
+    } else {
+        assert(("Invalid structured jump", 0));
+    }
+}
+
 static void compile_statement(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNode* stmt) {
     switch (stmt->kind) {
         case ONYX_AST_NODE_KIND_SCOPE: break;
@@ -248,6 +270,8 @@ static void compile_statement(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNode*
         case ONYX_AST_NODE_KIND_ASSIGNMENT: compile_assignment(mod, func, stmt); break;
         case ONYX_AST_NODE_KIND_IF: compile_if(mod, func, (OnyxAstNodeIf *) stmt); break;
         case ONYX_AST_NODE_KIND_WHILE: compile_while(mod, func, (OnyxAstNodeWhile *) stmt); break;
+        case ONYX_AST_NODE_KIND_BREAK: compile_structured_jump(mod, func, 0); break;
+        case ONYX_AST_NODE_KIND_CONTINUE: compile_structured_jump(mod, func, 1); break;
         case ONYX_AST_NODE_KIND_CALL: compile_expression(mod, func, stmt); break;
         case ONYX_AST_NODE_KIND_BLOCK: compile_block(mod, func, (OnyxAstNodeBlock *) stmt); break;
 
@@ -269,6 +293,8 @@ static void compile_if(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNodeIf* if_no
     compile_expression(mod, func, if_node->cond);
     bh_arr_push(func->code, ((WasmInstruction){ WI_IF_START, 0x40 }));
 
+    bh_arr_push(mod->structured_jump_target, 0);
+
     if (if_node->true_block) {
         // NOTE: This is kind of gross, but making a function for this doesn't feel right
 
@@ -297,6 +323,8 @@ static void compile_if(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNodeIf* if_no
         }
     }
 
+    bh_arr_pop(mod->structured_jump_target);
+
     bh_arr_push(func->code, ((WasmInstruction){ WI_IF_END, 0x00 }));
 }
 
@@ -308,10 +336,16 @@ static void compile_while(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNodeWhile*
     bh_arr_push(func->code, ((WasmInstruction){ WI_I32_EQZ, 0x00 }));
     bh_arr_push(func->code, ((WasmInstruction){ WI_COND_JUMP, 0x01 }));
 
+    bh_arr_push(mod->structured_jump_target, 1);
+    bh_arr_push(mod->structured_jump_target, 2);
+
     forll (OnyxAstNode, stmt, while_node->body->body, next) {
         compile_statement(mod, func, stmt);
     }
 
+    bh_arr_pop(mod->structured_jump_target);
+    bh_arr_pop(mod->structured_jump_target);
+
     bh_arr_push(func->code, ((WasmInstruction){ WI_JUMP, 0x00 }));
 
     bh_arr_push(func->code, ((WasmInstruction){ WI_LOOP_END, 0x00 }));
@@ -357,7 +391,13 @@ static void compile_binop(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNodeBinOp*
     }
 
     WasmType operator_type = onyx_type_to_wasm_type(binop->left->type);
-    WasmInstructionType binop_instr = binop_map[binop->operation][operator_type];
+    i32 optype = 0;
+    if (operator_type == WASM_TYPE_INT32) optype = 0;
+    else if (operator_type == WASM_TYPE_INT64) optype = 1;
+    else if (operator_type == WASM_TYPE_FLOAT32) optype = 2;
+    else if (operator_type == WASM_TYPE_FLOAT64) optype = 3;
+
+    WasmInstructionType binop_instr = binop_map[(i32) binop->operation][optype];
 
     if (binop_instr == WI_NOP) {
         assert(("Invalid type and operation", 0));
@@ -368,7 +408,7 @@ static void compile_binop(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNodeBinOp*
     // the signed equivalent
     if (is_sign_significant) {
         if (binop->left->type->is_unsigned) {
-            binop_instr += 1;
+            binop_instr = (WasmInstructionType) ((i32) binop_instr + 1);
         }
     }
 
@@ -677,12 +717,18 @@ OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc) {
 
         .imports = NULL,
         .next_import_func_idx = 0,
+
+        .structured_jump_target = NULL,
     };
 
     bh_arr_new(alloc, module.functypes, 4);
     bh_arr_new(alloc, module.funcs, 4);
     bh_arr_new(alloc, module.imports, 4);
 
+    // NOTE: 16 is probably needlessly large
+    bh_arr_new(bh_heap_allocator(), module.structured_jump_target, 16);
+    bh_arr_set_length(module.structured_jump_target, 0);
+
     bh_table_init(bh_heap_allocator(), module.type_map, 61);
     bh_table_init(bh_heap_allocator(), module.exports, 61);