Lots of changes
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 11 Jun 2020 14:02:52 +0000 (09:02 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 11 Jun 2020 14:02:52 +0000 (09:02 -0500)
.gitignore
Makefile
include/bh.h
include/onyxmsgs.h
include/onyxwasm.h
onyx
progs/minimal.onyx
src/onyx.c
src/onyxmsgs.c
src/onyxparser.c
src/onyxwasm.c

index cd21766181996945bcff1cdf069bdf84ea330014..f9efa12457d7dde5851ab02a687f83ceaca1bb93 100644 (file)
@@ -1,3 +1,5 @@
 **/*.o
 *.o
 tags
+test.c
+test
index c1561f1d6e1cf12b5eac760cb7f7d5b73c3863b5..32e6043f227da4530930780a2b0d1983322e84b5 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,23 +1,23 @@
 OBJ_FILES=\
-       src/onyxlex.o \
-       src/onyxparser.o \
-       src/onyxmsgs.o \
-       src/onyxutils.o \
-       src/onyxwasm.o \
-       src/onyx.o
+       build/onyxlex.o \
+       build/onyxparser.o \
+       build/onyxmsgs.o \
+       build/onyxutils.o \
+       build/onyxwasm.o \
+       build/onyx.o
 
 CC=gcc
 INCLUDES=-I./include
 LIBS=
 FLAGS=-g
 
-%.o: %.c include/bh.h
+build/%.o: src/%.c include/bh.h
        $(CC) $(FLAGS) -c $< -o $@ $(INCLUDES)
 
 onyx: $(OBJ_FILES)
-       $(CC) $(FLAGS) $? -o $@ $(LIBS)
+       $(CC) $(FLAGS) $(OBJ_FILES) -o $@ $(LIBS)
 
 clean:
        rm $(OBJ_FILES) 2>&1 >/dev/null
 
-all: onyx clean
+all: onyx
index 92461df0f2c5db278da20a411ec4da32ff6d0f5e..dc8a93a3364b4aad36886c7e7e823656a86dea14 100644 (file)
@@ -9,22 +9,21 @@
 #include <stdlib.h>
 #include <stdarg.h>
 #include <string.h> // TODO: Replace with needed functions
+#include <stdint.h>
 #include <assert.h>
 
 //-------------------------------------------------------------------------------------
 // Better types
 //-------------------------------------------------------------------------------------
-typedef unsigned char u8;
-typedef unsigned short u16;
-typedef unsigned int u32;
-typedef unsigned long u64;
-typedef unsigned long long u128;
-typedef signed char i8;
-typedef signed short i16;
-typedef signed int i32;
-typedef signed long i64;
-typedef signed long long i128;
-typedef unsigned long isize;
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+typedef int8_t i8;
+typedef int16_t i16;
+typedef int32_t i32;
+typedef int64_t i64;
+typedef int64_t isize;
 typedef i32 b32;
 typedef void* ptr;
 
@@ -50,14 +49,40 @@ typedef void* ptr;
 //-------------------------------------------------------------------------------------
 // Better character functions
 //-------------------------------------------------------------------------------------
-b32 char_is_alpha(const char a);
-b32 char_is_num(const char a);
-b32 char_is_alphanum(const char a);
-b32 char_is_whitespace(const char a);
-b32 char_in_range(const char lo, const char hi, const char a);
-char charset_contains(const char* charset, char ch);
-i64 chars_match(char* ptr1, char* ptr2);
+inline b32 char_is_alpha(const char a) {
+       return ('a' <= a && a <= 'z') || ('A' <= a && a <= 'Z');
+}
+
+inline char charset_contains(const char* charset, char ch) {
+       while (*charset) {
+               if (*charset == ch) return ch;
+               charset++;
+       }
+
+       return 0;
+}
+
+inline b32 char_is_num(const char a) {
+       return ('0' <= a && a <= '9');
+}
+
+inline b32 char_is_alphanum(const char a) {
+       return char_is_alpha(a) || char_is_num(a);
+}
+
+inline b32 char_is_whitespace(const char a) {
+       return charset_contains(" \t\r\n", a);
+}
 
+inline b32 char_in_range(const char lo, const char hi, const char a) {
+       return lo <= a <= hi;
+}
+
+inline i64 chars_match(char* ptr1, char* ptr2) {
+       i64 len = 0;
+       while (*ptr2 != '\0' && *ptr1 == *ptr2) ptr1++, ptr2++, len++;
+       return *ptr2 == '\0' ? len : 0;
+}
 
 
 
@@ -87,7 +112,8 @@ i64 chars_match(char* ptr1, char* ptr2);
 #define BH_BIT(x)                                              (1 << (x))
 #define BH_MASK_SET(var, set, mask)    ((set) ? (var) |= (mask) : (var) &= ~(mask))
 
-
+#define fori(var, lo, hi)                              for (i64 var = (lo); var <= (hi); var++)
+#define forll(T, var, start, step)             for (T* var = (start); var != NULL; var = var->step)
 
 
 
@@ -163,6 +189,9 @@ BH_ALLOCATOR_PROC(bh_arena_allocator_proc);
 
 
 
+
+
+
 // SCRATCH ALLOCATOR
 typedef struct bh_scratch {
        bh_allocator backing;
@@ -181,64 +210,6 @@ BH_ALLOCATOR_PROC(bh_scratch_allocator_proc);
 
 
 
-//-------------------------------------------------------------------------------------
-// Better strings
-//-------------------------------------------------------------------------------------
-#ifndef BH_NO_STRING
-
-typedef struct bh__string {
-       u64 length;
-       u64 capacity;
-} bh__string;
-
-typedef char bh_string;
-
-#define bh__stringhead(x)              (((bh__string *)(x)) - 1)
-
-#define bh_string_new(x) _Generic((x), \
-       unsigned long: bh_string_new_cap, \
-       unsigned int: bh_string_new_cap, \
-       int: bh_string_new_cap, \
-       long: bh_string_new_cap, \
-       const char*: bh_string_new_str, \
-       char*: bh_string_new_str)(x)
-
-#define bh_string_append(str1, str2) _Generic((str2), \
-       bh_string*: bh_string_append_bh_string, \
-       char*: bh_string_append_cstr, \
-       const char*: bh_string_append_cstr)(str1, str2)
-
-#define bh_string_replace_at(dest, src, offset) _Generic((src), \
-       bh_string*: bh_string_replace_at_bh_string, \
-       char*: bh_string_replace_at_cstr, \
-       const char*: bh_string_replace_at_cstr)(dest, src, offset)
-
-#define bh_string_insert_at(dest, src, offset) _Generic((src), \
-       bh_string*: bh_string_insert_at_bh_string, \
-       char*: bh_string_insert_at_cstr, \
-       const char*: bh_string_insert_at_cstr)(dest, src, offset)
-
-bh_string bh_string_new_cap(unsigned long cap);
-bh_string bh_string_new_str(const char* cstr);
-b32 bh_string_delete(bh_string* str);
-b32 bh_string_ensure_capacity(bh_string* str, u64 cap);
-void bh_string_append_bh_string(bh_string* str1, bh_string* str2);
-void bh_string_append_cstr(bh_string* str1, const char* str2);
-void bh_string_replace_at_bh_string(bh_string* dest, bh_string* src, u64 offset);
-void bh_string_replace_at_cstr(bh_string* dest, const char* src, u64 offset);
-void bh_string_insert_at_bh_string(bh_string* dest, bh_string* src, u64 offset);
-void bh_string_insert_at_cstr(bh_string* dest, const char* src, u64 offset);
-void bh_string_trim_end(bh_string* str, const char* charset);
-void bh_string_trim_begin(bh_string* str, const char* charset);
-void bh_string_trim_end_space(bh_string* str);
-// TEMP
-void bh_string_print(bh_string* str);
-
-#endif
-
-
-
-
 
 
 
@@ -359,6 +330,8 @@ isize bh_fprintf(bh_file* f, char const *fmt, ...);
 isize bh_fprintf_va(bh_file* f, char const *fmt, va_list va);
 char* bh_bprintf(char const *fmt, ...);
 char* bh_bprintf_va(char const *fmt, va_list va);
+char* bh_aprintf(bh_allocator alloc, const char* fmt, ...);
+char* bh_aprintf_va(bh_allocator alloc, const char* fmt, va_list va);
 isize bh_snprintf(char *str, isize n, char const *fmt, ...);
 isize bh_snprintf_va(char *str, isize n, char const *fmt, va_list va);
 
@@ -483,6 +456,8 @@ typedef struct bh__arr {
 #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++)
+
 b32 bh__arr_grow(bh_allocator alloc, void** arr, i32 elemsize, i32 cap);
 b32 bh__arr_shrink(void** arr, i32 elemsize, i32 cap);
 b32 bh__arr_free(void **arr);
@@ -543,6 +518,7 @@ typedef struct bh__hash {
        #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))))
@@ -554,34 +530,41 @@ typedef struct bh__hash {
        #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)
 #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);
 
 #endif
 
-#ifdef BH_DEFINE
-#undef BH_DEFINE
-
-
-
-
 
 
 
 
 
+//-------------------------------------------------------------------------------
+// OTHER COMMON DATA STRUCTURES
+//-------------------------------------------------------------------------------
+#ifndef BH_NO_DATASTRUCTURES
 
 
 
@@ -598,6 +581,7 @@ b32 bh_hash_iter_next(bh_hash_iterator* it);
 
 
 
+#endif // BH_NO_DATASTRUCTURES
 
 
 
@@ -613,6 +597,8 @@ b32 bh_hash_iter_next(bh_hash_iterator* it);
 
 
 
+#ifdef BH_DEFINE
+#undef BH_DEFINE
 //-------------------------------------------------------------------------------------
 // IMPLEMENTATIONS
 //-------------------------------------------------------------------------------------
@@ -620,40 +606,15 @@ b32 bh_hash_iter_next(bh_hash_iterator* it);
 //-------------------------------------------------------------------------------------
 // CHAR FUNCTIONS
 //-------------------------------------------------------------------------------------
-b32 char_is_alpha(const char a) {
-       return ('a' <= a && a <= 'z') || ('A' <= a && a <= 'Z');
-}
-
-b32 char_is_num(const char a) {
-       return ('0' <= a && a <= '9');
-}
-
-b32 char_is_alphanum(const char a) {
-       return char_is_alpha(a) || char_is_num(a);
-}
-
-b32 char_is_whitespace(const char a) {
-       return charset_contains(" \t\r\n", a);
-}
-
-b32 char_in_range(const char lo, const char hi, const char a) {
-       return lo <= a <= hi;
-}
-
-char charset_contains(const char* charset, char ch) {
-       while (*charset) {
-               if (*charset == ch) return ch;
-               charset++;
-       }
+extern inline b32 char_is_alpha(const char a);
+extern inline b32 char_is_num(const char a);
+extern inline b32 char_is_alphanum(const char a);
+extern inline char charset_contains(const char* charset, char ch);
+extern inline b32 char_is_whitespace(const char a);
+extern inline b32 char_in_range(const char lo, const char hi, const char a);
+extern inline i64 chars_match(char* ptr1, char* ptr2);
 
-       return 0;
-}
 
-i64 chars_match(char* ptr1, char* ptr2) {
-       i64 len = 0;
-       while (*ptr2 != '\0' && *ptr1 == *ptr2) ptr1++, ptr2++, len++;
-       return *ptr2 == '\0' ? len : 0;
-}
 
 
 
@@ -664,8 +625,6 @@ i64 chars_match(char* ptr1, char* ptr2) {
 //-------------------------------------------------------------------------------------
 // CUSTOM ALLOCATORS IMPLEMENTATION
 //-------------------------------------------------------------------------------------
-
-
 ptr bh_alloc(bh_allocator a, isize size) {
        return bh_alloc_aligned(a, size, 16);
 }
@@ -689,7 +648,6 @@ void bh_free(bh_allocator a, ptr data) {
 
 
 // HEAP ALLOCATOR IMPLEMENTATION
-
 bh_allocator bh_heap_allocator(void) {
        return (bh_allocator) {
                .proc = bh_heap_allocator_proc,
@@ -866,140 +824,6 @@ BH_ALLOCATOR_PROC(bh_scratch_allocator_proc) {
 }
 
 
-//-------------------------------------------------------------------------------------
-// STRING IMPLEMENTATION (BROKEN)
-//-------------------------------------------------------------------------------------
-#ifndef BH_NO_STRING
-
-bh_string* bh_string_new_cap(unsigned long cap) {
-       bh__string* str;
-       str = (bh__string*) malloc(sizeof(*str) + sizeof(char) * cap + 1);
-       str[0] = 0;
-       return str + 1;
-}
-
-bh_string* bh_string_new_str(const char* cstr) {
-       const i32 len = strlen(cstr);
-       bh__string* str;
-       i32 i;
-
-       str = malloc(sizeof(*str) + sizeof(char) * len + 1);
-       char* data = (char*) (str + 1);
-       for (i = 0; i < len; i++) {
-               data[i] = cstr[i];
-       }
-
-       data[len] = 0; // Always null terminate the string
-
-       str->length = len;
-       str->capacity = len;
-       return str + 1;
-}
-
-b32 bh_string_delete(bh_string** str) {
-       bh__string* strptr = bh__stringhead(*str);
-       free(strptr);
-       str->length = 0;
-       str->capacity = 0;
-       return 1;
-}
-
-b32 bh_string_grow(bh_string** str, u64 cap) {
-       bh__string* strptr = bh__stringhead(*str);
-       if (strptr->capacity >= cap) return 1;
-
-       void* p;
-       p = realloc(strptr, sizeof(*strptr) + sizeof(char) * cap + 1);
-
-       strptr->capacity = cap;
-
-       return 1;
-}
-
-void bh_string_append_bh_string(bh_string** str1, bh_string** str2) {
-       if (!bh_string_ensure_capacity(str1, str1->length + str2->length)) return;
-
-       //TODO: Replace with custom memory management
-       memcpy(str1->data + str1->length, str2->data, str2->length);
-       str1->length += str2->length;
-}
-
-void bh_string_append_cstr(bh_string* str1, const char* str2) {
-       const i32 str2len = strlen(str2);
-       if (!bh_string_ensure_capacity(str1, str1->length + str2len)) return;
-
-       //TODO: Replace with custom memory management
-       memcpy(str1->data + str1->length, str2, str2len);
-       str1->length += str2len;
-}
-
-void bh_string_replace_at_bh_string(bh_string* dest, bh_string* src, u64 offset) {
-       if (offset > dest->length) return;
-       if (!bh_string_ensure_capacity(dest, offset + src->length)) return;
-
-       memcpy(dest->data + offset, src->data, src->length);
-       if (offset + src->length > dest->length)
-               dest->length = offset + src->length;
-}
-
-void bh_string_replace_at_cstr(bh_string* dest, const char* src, u64 offset) {
-       if (offset > dest->length) return;
-       const i32 srclen = strlen(src);
-       if (!bh_string_ensure_capacity(dest, offset + srclen)) return;
-
-       memcpy(dest->data + offset, src, srclen);
-       if (offset + srclen > dest->length)
-               dest->length = offset + srclen;
-}
-
-void bh_string_insert_at_bh_string(bh_string* dest, bh_string* src, u64 offset) {
-       if (!bh_string_ensure_capacity(dest, dest->length + src->length)) return;
-
-       memmove(dest->data + offset + src->length, dest->data + offset, dest->length + src->length - offset);
-       memcpy(dest->data + offset, src->data, src->length);
-       dest->length += src->length;
-}
-
-void bh_string_insert_at_cstr(bh_string* dest, const char* src, u64 offset) {
-       const i32 srclen = strlen(src);
-       if (!bh_string_ensure_capacity(dest, dest->length + srclen)) return;
-
-       // TODO: Use something better. This copies to a seperate buffer first
-       memmove(dest->data + offset + srclen, dest->data + offset, dest->length + srclen - offset);
-       memcpy(dest->data + offset, src, srclen);
-       dest->length += srclen;
-}
-
-
-void bh_string_trim_end(bh_string* str, const char* charset) {
-       while (charset_contains(charset, str->data[str->length - 1]))
-               str->length--;
-}
-
-void bh_string_trim_begin(bh_string* str, const char* charset) {
-       u32 off = 0, i;
-       while (charset_contains(charset, str->data[off])) off++;
-
-       if (off == 0) return;
-
-       for (i = 0; i < str->length - off; i++) {
-               str->data[i] = str->data[i + off];
-       }
-
-       str->length -= off;
-}
-
-void bh_string_trim_end_space(bh_string* str) {
-       bh_string_trim_end(str, " \t\n\r");
-}
-
-// TEMP
-void bh_string_print(bh_string* str) {
-       write(STDOUT_FILENO, str->data, str->length);
-}
-
-#endif // ifndef BH_NO_STRING
-
 
 
 
@@ -1258,9 +1082,9 @@ isize bh_fprintf(bh_file* f, char const *fmt, ...) {
 }
 
 isize bh_fprintf_va(bh_file* f, char const *fmt, va_list va) {
-       static char buf[4096];
-       isize len = bh_snprintf_va(buf, sizeof(buf), fmt, va);
-       bh_file_write(f, buf, len - 1);
+       static char buffer[4096];
+       isize len = bh_snprintf_va(buffer, sizeof(buffer), fmt, va);
+       bh_file_write(f, buffer, len - 1);
        return len;
 }
 
@@ -1279,6 +1103,24 @@ char* bh_bprintf_va(char const *fmt, va_list va) {
        return buffer;
 }
 
+char* bh_aprintf(bh_allocator alloc, const char* fmt, ...) {
+       char* res;
+       va_list va;
+       va_start(va, fmt);
+       res = bh_aprintf_va(alloc, fmt, va);
+       va_end(va);
+       return res;
+}
+
+char* bh_aprintf_va(bh_allocator alloc, const char* fmt, va_list va) {
+       static char buffer[4096];
+       isize len = bh_snprintf_va(buffer, sizeof(buffer), fmt, va);
+       char* res = bh_alloc(alloc, len);
+       memcpy(res, buffer, len);
+       res[len - 1] = 0;
+       return res;
+}
+
 isize bh_snprintf(char *str, isize n, char const *fmt, ...) {
        isize res;
        va_list va;
@@ -1751,6 +1593,16 @@ found_matching:
        (*(u64 *) arrptr)--;
 }
 
+void bh__hash_clear(bh__hash *table) {
+       for (i32 i = 0; i < table->hash_size; i++) {
+               if (table->arrs[i] != NULL) {
+                       // NOTE: Set length property to 0
+                       *((u64 *) table->arrs[i]) = 0;
+                       bh_arr_set_length(table->arrs[i], 0);
+               }
+       }
+}
+
 bh_hash_iterator bh__hash_iter_setup(bh__hash *table, i32 elemsize) {
        elemsize += (elemsize & 1);
 
index 6c6a19e8afef966e7d5398fa1b686aa3d441a51b..b1d0f50d8134a13811eecc87f5d0e90ccc41c544 100644 (file)
@@ -18,6 +18,7 @@ typedef enum OnyxMessageType {
        ONYX_MESSAGE_TYPE_FUNCTION_REDEFINITION,
        ONYX_MESSAGE_TYPE_BINOP_MISMATCH_TYPE,
        ONYX_MESSAGE_TYPE_ASSIGNMENT_TYPE_MISMATCH,
+       ONYX_MESSAGE_TYPE_EXPECTED_EXPRESSION,
 
        ONYX_MESSAGE_TYPE_COUNT,
 } OnyxMessageType;
index feebeddd595eb64205dd6584339b7018e8b5f927..7c0d6d90f01d5f1016997393324e1f3b2f9c9c0e 100644 (file)
@@ -22,8 +22,225 @@ typedef struct WasmFuncType {
 } WasmFuncType;
 
 
+typedef enum WasmInstructionType {
+       WI_UNREACHABLE                                  = 0x00,
+       WI_NOP                                                  = 0x01,
+
+       // 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,
+
+       // NOTE: Parametric instructions
+       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,
+
+       // 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_STORE_8                                  = 0x3A,
+       WI_I32_STORE_16                                 = 0x3B,
+       WI_I64_STORE_8                                  = 0x3C,
+       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_FROM_F32_S                               = 0xA8,
+       WI_I32_FROM_F32_U                               = 0xA9,
+       WI_I32_FROM_F64_S                               = 0xAA,
+       WI_I32_FROM_F64_U                               = 0xAB,
+
+       WI_I64_FROM_I32_S                               = 0xAC,
+       WI_I64_FROM_I32_U                               = 0xAD,
+       WI_I64_FROM_F32_S                               = 0xAE,
+       WI_I64_FROM_F32_U                               = 0xAF,
+       WI_I64_FROM_F64_S                               = 0xB0,
+       WI_I64_FROM_F64_U                               = 0xB1,
+
+       WI_F32_FROM_I32_S                               = 0xB2,
+       WI_F32_FROM_I32_U                               = 0xB3,
+       WI_F32_FROM_I64_S                               = 0xB4,
+       WI_F32_FROM_I64_U                               = 0xB5,
+       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_I32_REINTERPRET_F32                  = 0xBC,
+       WI_I64_REINTERPRET_F64                  = 0xBD,
+       WI_F32_REINTERPRET_I32                  = 0xBE,
+       WI_F64_REINTERPRET_I64                  = 0xBF,
+} WasmInstructionType;
+
+typedef union {
+       struct {
+               u32 i1, i2;
+       };
+       i64 l;
+       float f;
+       double d;
+       ptr p;
+} WasmInstructionData;
+
+typedef struct WasmInstruction {
+       WasmInstructionType type;
+       WasmInstructionData data;
+} WasmInstruction;
+
+
 typedef struct WasmFunc {
        i32 type_idx;
+       bh_arr(WasmInstruction) code;
 } WasmFunc;
 
 typedef enum WasmExportKind {
@@ -41,6 +258,9 @@ typedef struct WasmExport {
 typedef struct OnyxWasmModule {
        bh_allocator allocator;
 
+       // NOTE: Mapping to local indicies currently in scope.
+       bh_hash(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.
diff --git a/onyx b/onyx
index 06d26eb9bcc8f97ada3f63de7a387f4880be23ff..6effde6758ecb7c3e7c9778864efb32b9e3bbddb 100755 (executable)
Binary files a/onyx and b/onyx differ
index 3b3499fe2a9f94204e71094b6db7f8d638261d25..b03f1a58f37576a694c082ed6f63456da0dd0ddf 100644 (file)
@@ -3,20 +3,14 @@ export add :: proc (a i32, b i32) -> i32 {
        return a + b;
 }
 
-export foo :: proc () -> i32 {
+export foo :: proc (foo i32, bar i32) -> i32 {
        return 10 as i32;
 }
 
 export mul :: proc (a i32, b i32) -> i64 {
        // Typechecked
-       c: const = a - b;
-
-       // Don't love this syntax, but it's easy to parse so whatever
-       // Inferred type, but constant
-       // a and b are both i32, so i32 + i32 is i32 so d is i32
-       d: const = a + b;
-
-       e: i32 = 10 as i32;
+       c :: a - b;
+       d :: a + b;
 
        return (c * d) as i64;
 }
index 731688bb0dbac30c5e2fc25427b55c2af01b25e5..f986facaea23d942008770f622b2b7060078bd56 100644 (file)
@@ -29,7 +29,7 @@ int main(int argc, char *argv[]) {
 #if 0
        bh_printf("There are %d tokens (Allocated space for %d tokens)\n", bh_arr_length(token_arr), bh_arr_capacity(token_arr));
 
-       for (OnyxToken* it = token_arr; !bh_arr_end(token_arr, it); it++) {
+       bh_arr_each(OnyxToken, it, token_arr) {
                onyx_token_null_toggle(*it);
                bh_printf("%s (%s:%l:%l)\n", onyx_get_token_type_name(it->type), it->pos.filename, it->pos.line, it->pos.column);
                onyx_token_null_toggle(*it);
@@ -66,13 +66,9 @@ int main(int argc, char *argv[]) {
        // NOTE: Ensure type table made correctly
 
        bh_printf("Type map:\n");
-       bh_hash_iterator type_map_it = bh_hash_iter_setup(i32, wasm_mod.type_map);
-       while (bh_hash_iter_next(&type_map_it)) {
-               const char* key = bh_hash_iter_key(type_map_it);
-               i32 value = bh_hash_iter_value(i32, type_map_it);
-
+       bh_hash_each_start(i32, wasm_mod.type_map);
                bh_printf("%s -> %d\n", key, value);
-       }
+       bh_hash_each_end;
 
        bh_printf("Type list:\n");
        WasmFuncType** func_type = wasm_mod.functypes;
@@ -91,18 +87,14 @@ int main(int argc, char *argv[]) {
        // NOTE: Ensure the export table was built correctly
 
        bh_printf("Function types:\n");
-       for (WasmFunc* func_it = wasm_mod.funcs; !bh_arr_end(wasm_mod.funcs, func_it); func_it++) {
+       bh_arr_each(WasmFunc, func_it, wasm_mod.funcs) {
                bh_printf("%d\n", func_it->type_idx);
        }
 
        bh_printf("Exports:\n");
-       bh_hash_iterator export_it = bh_hash_iter_setup(WasmExport, wasm_mod.exports);
-       while (bh_hash_iter_next(&export_it)) {
-               const char* key = bh_hash_iter_key(export_it);
-               WasmExport value = bh_hash_iter_value(WasmExport, export_it);
-
+       bh_hash_each_start(WasmExport, wasm_mod.exports);
                bh_printf("%s: %d %d\n", key, value.kind, value.idx);
-       }
+       bh_hash_each_end;
 #endif
 
 
index a2e555120991a29fdb8cc983cfa09ffcc00b802d..a5f0c7d8e797076558e3958ca9eed63055170b2a 100644 (file)
@@ -11,6 +11,7 @@ static const char* msg_formats[] = {
        "redefinition of function '%s'",
        "mismatched types for binary operator, '%s', '%s'",
        "mismatched types on assignment, '%s', '%s'",
+       "expected expression, got '%s'",
 };
 
 void onyx_message_add(OnyxMessages* msgs, OnyxMessageType type, OnyxFilePos pos, ...) {
index 0fbfc2674344381fd6f2857db0a90b6f9241bce3..02454cef552240ba3133dae4c4b99e8eee26e6bd 100644 (file)
@@ -324,13 +324,6 @@ static b32 parse_symbol_statement(OnyxParser* parser, OnyxAstNode** ret) {
                        {
                                parser_next_token(parser);
                                OnyxTypeInfo* type = &builtin_types[ONYX_TYPE_INFO_KIND_UNKNOWN];
-                               u32 flags = ONYX_AST_FLAG_LVAL;
-
-                               // NOTE: var: const ...
-                               if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_CONST) {
-                                       parser_next_token(parser);
-                                       flags |= ONYX_AST_FLAG_CONST;
-                               }
 
                                // NOTE: var: type
                                if (parser->curr_token->type == TOKEN_TYPE_SYMBOL) {
@@ -340,16 +333,29 @@ static b32 parse_symbol_statement(OnyxParser* parser, OnyxAstNode** ret) {
                                OnyxAstNodeLocal* local = (OnyxAstNodeLocal*) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_LOCAL);
                                local->token = symbol;
                                local->type = type;
-                               local->flags |= flags;
+                               local->flags |= ONYX_AST_FLAG_LVAL;
 
                                insert_identifier(parser, (OnyxAstNode *) local, 1);
 
-                               if (parser->curr_token->type == TOKEN_TYPE_SYM_EQUALS) {
+                               if (parser->curr_token->type == TOKEN_TYPE_SYM_EQUALS || parser->curr_token->type == TOKEN_TYPE_SYM_COLON) {
+                                       if (parser->curr_token->type == TOKEN_TYPE_SYM_COLON) {
+                                               local->flags |= ONYX_AST_FLAG_CONST;
+                                       }
+
                                        OnyxAstNode* assignment = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_ASSIGNMENT);
                                        assignment->token = parser->curr_token;
                                        parser_next_token(parser);
 
                                        OnyxAstNode* expr = parse_expression(parser);
+                                       if (expr == NULL) {
+                                               onyx_token_null_toggle(*parser->curr_token);
+                                               onyx_message_add(parser->msgs,
+                                                               ONYX_MESSAGE_TYPE_EXPECTED_EXPRESSION,
+                                                               assignment->token->pos,
+                                                               parser->curr_token->token);
+                                               onyx_token_null_toggle(*parser->curr_token);
+                                               return 1;
+                                       }
                                        assignment->right = expr;
                                        assignment->left = (OnyxAstNode*) local;
 
index 11226d43420ac745c14435292a368afc1d78b896..0fcfa6a03f67b7821353aa2684d0b1a1c0ad0cfb 100644 (file)
@@ -69,7 +69,8 @@ static void process_function_definition(OnyxWasmModule* mod, OnyxAstNodeFuncDef*
        }
 
        WasmFunc wasm_func = {
-               .type_idx = type_idx
+               .type_idx = type_idx,
+               .code = NULL,
        };
        bh_arr_push(mod->funcs, wasm_func);
        i32 func_idx = mod->next_func_idx++;
@@ -85,6 +86,33 @@ static void process_function_definition(OnyxWasmModule* mod, OnyxAstNodeFuncDef*
 
                onyx_token_null_toggle(*fd->token);
        }
+
+       // If there is no body then don't process the code
+       if (fd->body == NULL) return;
+
+       // NOTE: Generate the local map
+       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++);
+               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);
+       }
+
+       bh_printf("\nLocals for function: %b\n", fd->token->token, fd->token->length);
+       bh_hash_each_start(i32, mod->local_map);
+               bh_printf("\t%s -> %d\n", key, value);
+       bh_hash_each_end;
+
+       // Generate code
+
+       // NOTE: Clear the local map on exit of generating this function
+       bh_hash_clear(mod->local_map);
 }
 
 OnyxWasmModule onyx_wasm_generate_module(bh_allocator alloc, OnyxAstNode* program) {
@@ -104,6 +132,7 @@ 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);