From: Brendan Hansen Date: Thu, 11 Jun 2020 14:02:52 +0000 (-0500) Subject: Lots of changes X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=f172adee24203c701cf5c08ad47bcb5169299c0a;p=onyx.git Lots of changes --- diff --git a/.gitignore b/.gitignore index cd217661..f9efa124 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ **/*.o *.o tags +test.c +test diff --git a/Makefile b/Makefile index c1561f1d..32e6043f 100644 --- 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 diff --git a/include/bh.h b/include/bh.h index 92461df0..dc8a93a3 100644 --- a/include/bh.h +++ b/include/bh.h @@ -9,22 +9,21 @@ #include #include #include // TODO: Replace with needed functions +#include #include //------------------------------------------------------------------------------------- // 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); diff --git a/include/onyxmsgs.h b/include/onyxmsgs.h index 6c6a19e8..b1d0f50d 100644 --- a/include/onyxmsgs.h +++ b/include/onyxmsgs.h @@ -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; diff --git a/include/onyxwasm.h b/include/onyxwasm.h index feebeddd..7c0d6d90 100644 --- a/include/onyxwasm.h +++ b/include/onyxwasm.h @@ -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 06d26eb9..6effde67 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/minimal.onyx b/progs/minimal.onyx index 3b3499fe..b03f1a58 100644 --- a/progs/minimal.onyx +++ b/progs/minimal.onyx @@ -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; } diff --git a/src/onyx.c b/src/onyx.c index 731688bb..f986faca 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -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 diff --git a/src/onyxmsgs.c b/src/onyxmsgs.c index a2e55512..a5f0c7d8 100644 --- a/src/onyxmsgs.c +++ b/src/onyxmsgs.c @@ -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, ...) { diff --git a/src/onyxparser.c b/src/onyxparser.c index 0fbfc267..02454cef 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -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; diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 11226d43..0fcfa6a0 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -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);