From c738217d89ea9736724711439b9825fea713c726 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Fri, 26 Jun 2020 11:00:48 -0500 Subject: [PATCH] Fixed all mixed tabs and spaces Everything is spaces now --- Makefile | 26 +- docs/new_hash_plan | 60 +- docs/parse_grammar | 44 +- docs/plan | 142 ++-- docs/thoughts | 36 +- include/bh.h | 1778 ++++++++++++++++++++--------------------- include/onyxlex.h | 122 +-- include/onyxmsgs.h | 34 +- include/onyxparser.h | 237 +++--- include/onyxsempass.h | 4 +- include/onyxwasm.h | 474 +++++------ misc/onyx.vim | 14 +- progs/minimal.onyx | 16 +- progs/mvp.onyx | 20 +- progs/test.onyx | 6 +- src/onyx.c | 90 +-- src/onyxlex.c | 426 +++++----- src/onyxmsgs.c | 70 +- src/onyxparser.c | 668 ++++++++-------- src/onyxtypecheck.c | 2 +- src/onyxutils.c | 244 +++--- src/onyxwasm.c | 1128 +++++++++++++------------- 22 files changed, 2821 insertions(+), 2820 deletions(-) diff --git a/Makefile b/Makefile index aa3056cc..a81309b8 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,13 @@ OBJ_FILES=\ - build/onyxlex.o \ - build/onyxparser.o \ - build/onyxsempass.o \ - build/onyxsymres.o \ - build/onyxtypecheck.o \ - build/onyxmsgs.o \ - build/onyxutils.o \ - build/onyxwasm.o \ - build/onyx.o + build/onyxlex.o \ + build/onyxparser.o \ + build/onyxsempass.o \ + build/onyxsymres.o \ + build/onyxtypecheck.o \ + build/onyxmsgs.o \ + build/onyxutils.o \ + build/onyxwasm.o \ + build/onyx.o CC=gcc INCLUDES=-I./include @@ -16,15 +16,15 @@ FLAGS=-g TARGET=./onyx build/%.o: src/%.c include/bh.h - $(CC) $(FLAGS) -c $< -o $@ $(INCLUDES) + $(CC) $(FLAGS) -c $< -o $@ $(INCLUDES) $(TARGET): $(OBJ_FILES) - $(CC) $(FLAGS) $(OBJ_FILES) -o $@ $(LIBS) + $(CC) $(FLAGS) $(OBJ_FILES) -o $@ $(LIBS) install: $(TARGET) - cp $(TARGET) /usr/bin/ + cp $(TARGET) /usr/bin/ clean: - rm -f $(OBJ_FILES) 2>&1 >/dev/null + rm -f $(OBJ_FILES) 2>&1 >/dev/null all: onyx diff --git a/docs/new_hash_plan b/docs/new_hash_plan index 117ae146..cf706249 100644 --- a/docs/new_hash_plan +++ b/docs/new_hash_plan @@ -1,50 +1,50 @@ The state of the hash implementation right now: - (allocator + 1021 ptrs = 8192 bytes (HUGE)) - +--------------------------------------------------------- -table ----> | allocator | ptr | ptr | ptr | ptr | ptr | ptr | ptr ... - +-------------||------------------------------------------ - \/ - +--------------+------------------------------------------------------ - | Array header | key (64-bytes) | value | key (64-bytes) | value | ... - +--------------+------------------------------------------------------ + (allocator + 1021 ptrs = 8192 bytes (HUGE)) + +--------------------------------------------------------- +table ----> | allocator | ptr | ptr | ptr | ptr | ptr | ptr | ptr ... + +-------------||------------------------------------------ + \/ + +--------------+------------------------------------------------------ + | Array header | key (64-bytes) | value | key (64-bytes) | value | ... + +--------------+------------------------------------------------------ There are a couple of issues with this implementation: * The table of pointers is absolutely huge. - It takes up about 2 pages of memory and we are randomly accessing it - so it will not be cache efficient. + It takes up about 2 pages of memory and we are randomly accessing it + so it will not be cache efficient. * The keys are always the same size. - They are normally way too large, but also they would cut off if you - needed a large key. + They are normally way too large, but also they would cut off if you + needed a large key. THIS WORKED VERY WELL! Attempt 1 to fix these issues: - (user defined number of ptrs) - +----------------------------------------------------------- -table ----> | allocator | hash size | ptr | ptr | ptr | ptr | ptr | ... - +-------------------------||-------------------------------- - \/ - +--------------+------------------------------------------------------------------------ - | Array header | length | value | key_length | key (null terminated) | v | kl | k | ... - +--------------+------------------------------------------------------------------------ + (user defined number of ptrs) + +----------------------------------------------------------- +table ----> | allocator | hash size | ptr | ptr | ptr | ptr | ptr | ... + +-------------------------||-------------------------------- + \/ + +--------------+------------------------------------------------------------------------ + | Array header | length | value | key_length | key (null terminated) | v | kl | k | ... + +--------------+------------------------------------------------------------------------ GOOD: * This implementation would allow for any size of key. - Initial thoughts: - - Alignment is going to be very important. - - Alignment will need to be by hand. - - Aligning to 8 bytes should be sufficient. - - The array would just be considered as a u8 array, since each element - wouldn't be the same size. - - Random access into the array would not be allowed for the same reason. - - Random access will not be needed however. + Initial thoughts: + - Alignment is going to be very important. + - Alignment will need to be by hand. + - Aligning to 8 bytes should be sufficient. + - The array would just be considered as a u8 array, since each element + wouldn't be the same size. + - Random access into the array would not be allowed for the same reason. + - Random access will not be needed however. * This implementation still allows for easy iterator traversal, which is - important for the immediate use case. + important for the immediate use case. BAD: * The fact that the number of pointers is user defined, the hashing algorithm could - be drastically slowed / crippled if they choose a bad number of pointers. + be drastically slowed / crippled if they choose a bad number of pointers. * This implementation still takes a very large number of allocations. diff --git a/docs/parse_grammar b/docs/parse_grammar index 909fe1c9..1a714f72 100644 --- a/docs/parse_grammar +++ b/docs/parse_grammar @@ -5,11 +5,11 @@ Goal: Design the language to have no ambiguity (so a greedy algorithm can work) SOURCE_FILE = TOP_LEVEL_STATEMENT ; SOURCE_FILE | ~ TOP_LEVEL_STATEMENT - = COMMENT -- Should comments not be passed to the parser? Depends if I need to look at them. Probably not - | USE_DECLARATION - | EXPORT_DECLARATION - | FOREIGN_DECLARATION - | TOP_LEVEL_DECLARATION + = COMMENT -- Should comments not be passed to the parser? Depends if I need to look at them. Probably not + | USE_DECLARATION + | EXPORT_DECLARATION + | FOREIGN_DECLARATION + | TOP_LEVEL_DECLARATION COMMENT = TOKEN_TYPE_COMMENT @@ -22,8 +22,8 @@ FOREIGN_DECLARATION = foreign TOKEN_TYPE_LITERAL_STRING TOKEN_TYPE_LITERAL_STRIN TOP_LEVEL_DECLARATION = TOKEN_TYPE_SYMBOL :: TOP_LEVEL_VALUE TOP_LEVEL_VALUE - = FUNCTION_DECLARATION - | STRUCT_DECLARATION + = FUNCTION_DECLARATION + | STRUCT_DECLARATION FUNCTION_DECLARATION = proc FUNCTION_TYPE BLOCK @@ -34,16 +34,16 @@ BLOCK = { STATEMENTS | --- STATEMENTS = STATEMENT ; STATEMENTS | } STATEMENT - = ASSIGNMENT_STATEMENT - | IF_STATEMENT - | FOR_STATEMENT - | RETURN_STATEMENT - | EXPRESSION + = ASSIGNMENT_STATEMENT + | IF_STATEMENT + | FOR_STATEMENT + | RETURN_STATEMENT + | EXPRESSION ASSIGNMENT_STATEMENT = TOKEN_TYPE_SYMBOL = EXPRESSION IF_STATEMENT - = if EXPRESSION BLOCK ELSE_IF_STATEMENT ELSE_STATEMENT + = if EXPRESSION BLOCK ELSE_IF_STATEMENT ELSE_STATEMENT ELSEIF_STATEMENT = elseif EXPRESSION BLOCK ELSEIF_STATEMENT | ~ @@ -56,15 +56,15 @@ RETURN_STATEMENT = return EXPRESSION -- Remove abiguity in implementation EXPRESSION - = EXPRESSION + EXPRESSION - | EXPRESSION - EXPRESSION - | EXPRESSION * EXPRESSION - | EXPRESSION / EXPRESSION - | EXPRESSION % EXPRESSION - | do BLOCK - | FUNCTION_CALL -- This could have some abiguity with just the symbol - | ( EXPRESSION ) - | TOKEN_TYPE_SYMBOL + = EXPRESSION + EXPRESSION + | EXPRESSION - EXPRESSION + | EXPRESSION * EXPRESSION + | EXPRESSION / EXPRESSION + | EXPRESSION % EXPRESSION + | do BLOCK + | FUNCTION_CALL -- This could have some abiguity with just the symbol + | ( EXPRESSION ) + | TOKEN_TYPE_SYMBOL FUNCTION_CALL = TOKEN_TYPE_SYMBOL ( EXPRESSION_LIST ) diff --git a/docs/plan b/docs/plan index bdc27508..109dcf6b 100644 --- a/docs/plan +++ b/docs/plan @@ -2,79 +2,79 @@ The ONYX Programming Language ----------------------------- WHAT: - ONYX is a low-ish level programming language designed for use with - Web-Assembly 32-bit (WASM). It features some advanced features such - as comptime code execution and JS literals for external functions. + ONYX is a low-ish level programming language designed for use with + Web-Assembly 32-bit (WASM). It features some advanced features such + as comptime code execution and JS literals for external functions. WHY: - ONYX was made to help me learn about compiler design. + ONYX was made to help me learn about compiler design. END GOAL: - ONYX will be used to make a simple-ish game for the browser that leverages - WASM and WebGL for a performant experience. Language design will reflect the - needs of the game programming. + ONYX will be used to make a simple-ish game for the browser that leverages + WASM and WebGL for a performant experience. Language design will reflect the + needs of the game programming. FEATURES: - - Strong type system - - functions (no anonymous functions) - - Structs and enums - - Control structures - if, for, switch - - pointers - - inferred typing - - Smart package loading - - defer - ? polymorphic functions + - Strong type system + - functions (no anonymous functions) + - Structs and enums + - Control structures + if, for, switch + - pointers + - inferred typing + - Smart package loading + - defer + ? polymorphic functions HOW: - Currently there is a multi-phase development process since implementing everything - at once would be overwhelming and unsatisfying. The current progress of each stage: - - Stage 1 (MVP): - [X] Can declare procedures - [X] Procedures have params and returns of the following types: - - i32, u32 - - i64, u64 - - f32, f64 - [X] Procedures have locals of the same set of types - [X] Locals are declared in the following way - local : (type) ((= or :) initial value); - - if : is used, the value is unmodifiable - if type is specified, that is assumed to be the correct type - if type is not specified, the type of initial value is used as the type - - [X] Five basic math operations are legal: - + - * / % - [X] Math operations are sign aware and only operate on operands of the same type - [X] All casts are explicit using this syntax: - X as T - - casts X to type T - - [X] Curly braces are required for all bodies of blocks - [X] Numeric literals are parsed - [X] Numeric literals have the minimum type detected + Currently there is a multi-phase development process since implementing everything + at once would be overwhelming and unsatisfying. The current progress of each stage: + + Stage 1 (MVP): + [X] Can declare procedures + [X] Procedures have params and returns of the following types: + - i32, u32 + - i64, u64 + - f32, f64 + [X] Procedures have locals of the same set of types + [X] Locals are declared in the following way + local : (type) ((= or :) initial value); + + if : is used, the value is unmodifiable + if type is specified, that is assumed to be the correct type + if type is not specified, the type of initial value is used as the type + + [X] Five basic math operations are legal: + + - * / % + [X] Math operations are sign aware and only operate on operands of the same type + [X] All casts are explicit using this syntax: + X as T + + casts X to type T + + [X] Curly braces are required for all bodies of blocks + [X] Numeric literals are parsed + [X] Numeric literals have the minimum type detected [X] Foreign imports (functions only) - [X] Comparison operators - [X] Proper boolean type - [X] Conditional branching works as expected - XX] Simple while loop is functioning as expected - [ ] break and continue semantics - [X] Function calling works for the builtin types - [X] Function return values are type checked - - Stage 2: - [X] Order of symbol declaration is irrelevant - Either: - make a graph of symbol dependencies and produce a schedule on the graph - that would allow for all symbols to be resolved - - OR - - Do as many passes on the parse tree as needed to resolve all symbols. - This could be slow but it would be easier than creating a graph - scheduling algorithm. + [X] Comparison operators + [X] Proper boolean type + [X] Conditional branching works as expected + XX] Simple while loop is functioning as expected + [ ] break and continue semantics + [X] Function calling works for the builtin types + [X] Function return values are type checked + + Stage 2: + [X] Order of symbol declaration is irrelevant + Either: + make a graph of symbol dependencies and produce a schedule on the graph + that would allow for all symbols to be resolved + + OR + + Do as many passes on the parse tree as needed to resolve all symbols. + This could be slow but it would be easier than creating a graph + scheduling algorithm. [X] Consequence of the above, recursion works @@ -90,15 +90,15 @@ HOW: [ ] Output 'drop' instruction for functions whose return value isn't used - [ ] Devise and implement a simple set of implicit type casting rules. - - Numeric literals always type cast to whatever type is needed (very flexible). + [ ] Devise and implement a simple set of implicit type casting rules. + - Numeric literals always type cast to whatever type is needed (very flexible). - [ ] Strings should work as pointers to data. - - Literals should be placed in data section with pointers to the start. - - Should strings be null-terminated or a length at the start of the string? + [ ] Strings should work as pointers to data. + - Literals should be placed in data section with pointers to the start. + - Should strings be null-terminated or a length at the start of the string? - [ ] Start work on evaluating compile time known values. - - An expression marked COMPTIME will be reduced to its value in the parse tree. + [ ] Start work on evaluating compile time known values. + - An expression marked COMPTIME will be reduced to its value in the parse tree. diff --git a/docs/thoughts b/docs/thoughts index 24dfa3cc..de164d11 100644 --- a/docs/thoughts +++ b/docs/thoughts @@ -1,26 +1,26 @@ Type checking at parse time: - Why couldn't this work? - * Every variable is of known type or the type must be known by immediate assignment - * This requires that functions are declared in a particular order like C - * This also requires immediate evaluation of external symbols (C #include style) - - Don't like this at all - - Want a proper module system <<<< + Why couldn't this work? + * Every variable is of known type or the type must be known by immediate assignment + * This requires that functions are declared in a particular order like C + * This also requires immediate evaluation of external symbols (C #include style) + - Don't like this at all + - Want a proper module system <<<< - /* foo.onyx */ - foo :: proc (a i32) -> f32 { - return a as f32; - } + /* foo.onyx */ + foo :: proc (a i32) -> f32 { + return a as f32; + } - /* main.onyx */ - use "foo"; + /* main.onyx */ + use "foo"; - export main :: proc () -> void { - a := 2.0f + foo(5); - } + export main :: proc () -> void { + a := 2.0f + foo(5); + } - foo(5) would have a left node of SYMBOL:foo - This will be resolved in a later stage between the parsing and semantic pass - Type checking and resolving would have to occur afterwards + foo(5) would have a left node of SYMBOL:foo + This will be resolved in a later stage between the parsing and semantic pass + Type checking and resolving would have to occur afterwards Creating an IR: diff --git a/include/bh.h b/include/bh.h index 20a9e9f0..f528ad26 100644 --- a/include/bh.h +++ b/include/bh.h @@ -52,38 +52,38 @@ typedef double f64; // Better character functions //------------------------------------------------------------------------------------- inline b32 char_is_alpha(const char a) { - return ('a' <= a && a <= 'z') || ('A' <= a && a <= 'Z'); + 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++; - } + while (*charset) { + if (*charset == ch) return ch; + charset++; + } - return 0; + return 0; } inline b32 char_is_num(const char a) { - return ('0' <= a && a <= '9'); + return ('0' <= a && a <= '9'); } inline b32 char_is_alphanum(const char a) { - return char_is_alpha(a) || char_is_num(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); + 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; + 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; + i64 len = 0; + while (*ptr2 != '\0' && *ptr1 == *ptr2) ptr1++, ptr2++, len++; + return *ptr2 == '\0' ? len : 0; } @@ -94,10 +94,10 @@ inline i64 chars_match(char* ptr1, char* ptr2) { //------------------------------------------------------------------------------------- // Better math functions //------------------------------------------------------------------------------------- -#define bh_max(a, b) ((a) > (b) ? (a) : (b)) -#define bh_min(a, b) ((a) < (b) ? (a) : (b)) -#define bh_clamp(v, a, b) (bh_min((b), bh_max((a), (v)))) -#define bh_abs(x) ((x) < 0 ? -(x) : (x)) +#define bh_max(a, b) ((a) > (b) ? (a) : (b)) +#define bh_min(a, b) ((a) < (b) ? (a) : (b)) +#define bh_clamp(v, a, b) (bh_min((b), bh_max((a), (v)))) +#define bh_abs(x) ((x) < 0 ? -(x) : (x)) @@ -121,21 +121,21 @@ u8* double_to_ieee754(f64 f, b32 reverse); //------------------------------------------------------------------------------------- // Helpful macros //------------------------------------------------------------------------------------- -#define bh_offset_of(Type, elem) ((isize)&(((Type)*) 0)->elem) -#define bh_align_of(Type) bh_offset_of(struct { char c; Type member; }, member) -#define bh_swap(Type, a, b) do { Type tmp = (a); (a) = (b); (b) = tmp; } while(0) +#define bh_offset_of(Type, elem) ((isize)&(((Type)*) 0)->elem) +#define bh_align_of(Type) bh_offset_of(struct { char c; Type member; }, member) +#define bh_swap(Type, a, b) do { Type tmp = (a); (a) = (b); (b) = tmp; } while(0) -#define bh_pointer_add(ptr, amm) ((void *)((u8 *) ptr + amm)) -#define BH_BIT(x) (1 << (x)) -#define BH_MASK_SET(var, set, mask) ((set) ? (var) |= (mask) : (var) &= ~(mask)) +#define bh_pointer_add(ptr, amm) ((void *)((u8 *) ptr + amm)) +#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) +#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) #ifdef BH_DEBUG - #define DEBUG_HERE __asm("int $3") + #define DEBUG_HERE __asm("int $3") #else - #define DEBUG_HERE + #define DEBUG_HERE #endif @@ -147,26 +147,26 @@ u8* double_to_ieee754(f64 f, b32 reverse); //------------------------------------------------------------------------------------- typedef enum bh_allocator_actions { - bh_allocator_action_alloc, - bh_allocator_action_free, - bh_allocator_action_resize, + bh_allocator_action_alloc, + bh_allocator_action_free, + bh_allocator_action_resize, } bh_allocator_actions; #define BH_ALLOCATOR_PROC(name) \ ptr name(ptr data, bh_allocator_actions action, \ - isize size, isize alignment, \ - void* prev_memory, \ - u64 flags) + isize size, isize alignment, \ + void* prev_memory, \ + u64 flags) typedef BH_ALLOCATOR_PROC(bh__allocator_proc); // NOTE: so bh__allocator_proc can be used instead of that type typedef struct bh_allocator { - bh__allocator_proc* proc; // Procedure that can handle bh_allocator_actions - ptr data; // Pointer to the other data for the allocator + bh__allocator_proc* proc; // Procedure that can handle bh_allocator_actions + ptr data; // Pointer to the other data for the allocator } bh_allocator; typedef enum bh_allocator_flags { - bh_allocator_flag_clear = 1 // Sets all memory to be 0 + bh_allocator_flag_clear = 1 // Sets all memory to be 0 } bh_allocator_flags; ptr bh_alloc(bh_allocator a, isize size); @@ -175,11 +175,11 @@ ptr bh_resize(bh_allocator a, ptr data, isize new_size); ptr bh_resize_aligned(bh_allocator a, ptr data, isize new_size, isize alignment); void bh_free(bh_allocator a, ptr data); -#define bh_alloc_item(allocator_, T) (T *) bh_alloc(allocator_, sizeof(T)) -#define bh_alloc_array(allocator_, T, n) (T *) bh_alloc(allocator_, sizeof(T) * (n)) +#define bh_alloc_item(allocator_, T) (T *) bh_alloc(allocator_, sizeof(T)) +#define bh_alloc_array(allocator_, T, n) (T *) bh_alloc(allocator_, sizeof(T) * (n)) // NOTE: This should get optimized out since alignment should be a power of two -#define bh__align(x, alignment) ((((x) / alignment) + 1) * alignment) +#define bh__align(x, alignment) ((((x) / alignment) + 1) * alignment) @@ -195,14 +195,14 @@ BH_ALLOCATOR_PROC(bh_heap_allocator_proc); // ARENA ALLOCATOR typedef struct bh_arena { - bh_allocator backing; - ptr first_arena, current_arena; - isize size, arena_size; // in bytes + bh_allocator backing; + ptr first_arena, current_arena; + isize size, arena_size; // in bytes } bh_arena; typedef struct bh__arena_internal { - ptr next_arena; - void* data; // Not actually a pointer, just used for the offset + ptr next_arena; + void* data; // Not actually a pointer, just used for the offset } bh__arena_internal; void bh_arena_init(bh_arena* alloc, bh_allocator backing, isize arena_size); @@ -217,8 +217,8 @@ BH_ALLOCATOR_PROC(bh_arena_allocator_proc); // SCRATCH ALLOCATOR typedef struct bh_scratch { - bh_allocator backing; - ptr memory, end, curr; + bh_allocator backing; + ptr memory, end, curr; } bh_scratch; void bh_scratch_init(bh_scratch* scratch, bh_allocator backing, isize scratch_size); @@ -245,44 +245,44 @@ BH_ALLOCATOR_PROC(bh_scratch_allocator_proc); #ifndef BH_NO_FILE typedef enum bh_file_error { - BH_FILE_ERROR_NONE, - BH_FILE_ERROR_INVALID, - BH_FILE_ERROR_BAD_FD, + BH_FILE_ERROR_NONE, + BH_FILE_ERROR_INVALID, + BH_FILE_ERROR_BAD_FD, } bh_file_error; typedef enum bh_file_mode { - BH_FILE_MODE_READ = 1 << 0, - BH_FILE_MODE_WRITE = 1 << 1, - BH_FILE_MODE_APPEND = 1 << 2, - BH_FILE_MODE_RW = 1 << 3, + BH_FILE_MODE_READ = 1 << 0, + BH_FILE_MODE_WRITE = 1 << 1, + BH_FILE_MODE_APPEND = 1 << 2, + BH_FILE_MODE_RW = 1 << 3, - BH_FILE_MODE_MODES = BH_FILE_MODE_READ | BH_FILE_MODE_WRITE | BH_FILE_MODE_APPEND | BH_FILE_MODE_RW + BH_FILE_MODE_MODES = BH_FILE_MODE_READ | BH_FILE_MODE_WRITE | BH_FILE_MODE_APPEND | BH_FILE_MODE_RW } bh_file_mode; typedef enum bh_file_whence { - BH_FILE_WHENCE_BEGIN = SEEK_SET, - BH_FILE_WHENCE_CURRENT = SEEK_CUR, - BH_FILE_WHENCE_END = SEEK_END, + BH_FILE_WHENCE_BEGIN = SEEK_SET, + BH_FILE_WHENCE_CURRENT = SEEK_CUR, + BH_FILE_WHENCE_END = SEEK_END, } bh_file_whence; typedef int bh_file_descriptor; typedef struct bh_file { - bh_file_descriptor fd; - char const* filename; + bh_file_descriptor fd; + char const* filename; } bh_file; typedef enum bh_file_standard { - BH_FILE_STANDARD_INPUT, - BH_FILE_STANDARD_OUTPUT, - BH_FILE_STANDARD_ERROR + BH_FILE_STANDARD_INPUT, + BH_FILE_STANDARD_OUTPUT, + BH_FILE_STANDARD_ERROR } bh_file_standard; typedef struct bh_file_contents { - bh_allocator allocator; - const char *filename; - isize length; - void* data; + bh_allocator allocator; + const char *filename; + isize length; + void* data; } bh_file_contents; bh_file_error bh_file_get_standard(bh_file* file, bh_file_standard stand); @@ -303,9 +303,9 @@ i32 bh_file_write(bh_file* file, void* buffer, isize buff_size); i64 bh_file_size(bh_file* file); #define bh_file_read_contents(allocator_, x) _Generic((x), \ - bh_file*: bh_file_read_contents_bh_file, \ - const char*: bh_file_read_contents_direct, \ - char*: bh_file_read_contents_direct)((allocator_), x) + bh_file*: bh_file_read_contents_bh_file, \ + const char*: bh_file_read_contents_direct, \ + char*: bh_file_read_contents_direct)((allocator_), x) bh_file_contents bh_file_read_contents_bh_file(bh_allocator alloc, bh_file* file); bh_file_contents bh_file_read_contents_direct(bh_allocator alloc, const char* filename); @@ -327,22 +327,22 @@ i32 bh_file_contents_free(bh_file_contents* contents); //------------------------------------------------------------------------------------- // Barebones implementation of printf. Does not support all format options // Currently supports: -// %c - chars -// %_(u)d - ints where _ is: -// nothing - decimal -// o - octal -// x - hexadecimal -// %_(u)l - longs where _ is: -// nothing - decimal -// o - octal -// x - hexadecimal -// %f - floating points -// %s - null terminated strings -// %p - pointers -// %% - literal % +// %c - chars +// %_(u)d - ints where _ is: +// nothing - decimal +// o - octal +// x - hexadecimal +// %_(u)l - longs where _ is: +// nothing - decimal +// o - octal +// x - hexadecimal +// %f - floating points +// %s - null terminated strings +// %p - pointers +// %% - literal % typedef struct bh__print_format { - u32 base; + u32 base; } bh__print_format; isize bh_printf(char const *fmt, ...); @@ -378,34 +378,34 @@ void* bh__debug_realloc(void* ptr, size_t size, const char* file, u64 line); #ifdef BH_DEFINE void* bh__debug_malloc(size_t size, const char* file, u64 line) { - void* p = malloc(size); - bh_printf("[DEBUG] %p = malloc(%d) at %s:%d\n", p, size, file, line); - return p; + void* p = malloc(size); + bh_printf("[DEBUG] %p = malloc(%d) at %s:%d\n", p, size, file, line); + return p; } void* bh__debug_aligned_alloc(size_t alignment, size_t size, const char* file, u64 line) { - void* p = aligned_alloc(alignment, size); - bh_printf("[DEBUG] %p = aligned_alloc(%d, %d) at %s:%d\n", p, alignment, size, file, line); - return p; + void* p = aligned_alloc(alignment, size); + bh_printf("[DEBUG] %p = aligned_alloc(%d, %d) at %s:%d\n", p, alignment, size, file, line); + return p; } void bh__debug_free(void* ptr, const char* file, u64 line) { - bh_printf("[DEBUG] free(%p) at %s:%d\n", ptr, file, line); - free(ptr); + bh_printf("[DEBUG] free(%p) at %s:%d\n", ptr, file, line); + free(ptr); } void* bh__debug_realloc(void* ptr, size_t size, const char* file, u64 line) { - void* p = realloc(ptr, size); - bh_printf("[DEBUG] %p = realloc(%p, %d) at %s:%d\n", p, ptr, size, file, line); - return p; + void* p = realloc(ptr, size); + bh_printf("[DEBUG] %p = realloc(%p, %d) at %s:%d\n", p, ptr, size, file, line); + return p; } #endif -#define malloc(size) (bh__debug_malloc(size, __FILE__, __LINE__)) -#define aligned_alloc(alignment, size) (bh__debug_aligned_alloc(alignment, size, __FILE__, __LINE__)) -#define free(ptr) (bh__debug_free(ptr, __FILE__, __LINE__)) -#define realloc(ptr, size) (bh__debug_realloc(ptr, size, __FILE__, __LINE__)) +#define malloc(size) (bh__debug_malloc(size, __FILE__, __LINE__)) +#define aligned_alloc(alignment, size) (bh__debug_aligned_alloc(alignment, size, __FILE__, __LINE__)) +#define free(ptr) (bh__debug_free(ptr, __FILE__, __LINE__)) +#define realloc(ptr, size) (bh__debug_realloc(ptr, size, __FILE__, __LINE__)) #endif @@ -429,13 +429,13 @@ void* bh__debug_realloc(void* ptr, size_t size, const char* file, u64 line) { //------------------------------------------------------------------------------------- typedef struct bh_buffer { - bh_allocator allocator; - i32 length, capacity; - u8* data; + bh_allocator allocator; + i32 length, capacity; + u8* data; } bh_buffer; #ifndef BH_BUFFER_GROW_FORMULA -#define BH_BUFFER_GROW_FORMULA(x) ((x) > 0 ? ((x) << 1) : 16) +#define BH_BUFFER_GROW_FORMULA(x) ((x) > 0 ? ((x) << 1) : 16) #endif void bh_buffer_init(bh_buffer* buffer, bh_allocator alloc, i32 length); @@ -465,54 +465,54 @@ void bh_buffer_write_byte(bh_buffer* buffer, u8 byte); #ifndef BH_NO_ARRAY typedef struct bh__arr { - bh_allocator allocator; - i32 length, capacity; + bh_allocator allocator; + i32 length, capacity; } 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_arr(T) T* +#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_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_allocator(arr) (arr ? bh__arrhead(arr)->allocator : bh_heap_allocator()) +#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_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_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_shrink(arr, cap) (bh__arr_shrink((void **) &(arr), sizeof(*(arr)), cap)) -#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_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) ( \ + 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) ( \ - bh__arr_grow(bh_arr_allocator(arr), (void **) &(arr), sizeof(*(arr)), bh_arr_length(arr) + n), \ - bh__arrhead(arr)->length += 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) ( \ - 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_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); @@ -541,64 +541,64 @@ void bh__arr_deleten(void **arr, i32 elemsize, i32 index, i32 numelems); #ifdef BH_DEFINE u64 bh__table_hash_function(const char* str, i32 len, i32 mod) { - u64 hash = 5381; - i32 c, l = 0; - if (len == 0) len = ((u32) 1 << 31) - 1; // TODO: Verify this is right + u64 hash = 5381; + i32 c, l = 0; + if (len == 0) len = ((u32) 1 << 31) - 1; // TODO: Verify this is right - while ((c = *str++) && l++ < len) { - hash = (hash << 5) + hash + c; - } + while ((c = *str++) && l++ < len) { + hash = (hash << 5) + hash + c; + } - return hash % mod; + return hash % mod; } #endif typedef struct bh_table_iterator { - ptr *tab, *endtab; - i32 elemsize, arrlen; - ptr entry; + ptr *tab, *endtab; + i32 elemsize, arrlen; + ptr entry; } bh_table_iterator; typedef struct bh__table { - bh_allocator allocator; - u64 table_size; // NOTE: u64 since padding will make it 8-bytes no matter what - ptr arrs[]; + bh_allocator allocator; + u64 table_size; // NOTE: u64 since padding will make it 8-bytes no matter what + ptr arrs[]; } bh__table; -#define bh_table(T) T* +#define bh_table(T) T* #ifdef BH_TABLE_SIZE_SAFE - #define bh_table_init(allocator_, tab, hs) bh__table_init(allocator_, (bh__table **)&(tab), hs) - #define bh_table_free(tab) bh__table_free((bh__table **)&(tab)) - #define bh_table_put(T, tab, key, value) (assert(sizeof(T) == sizeof(*(tab))), (*((T *) bh__table_put((bh__table *) tab, sizeof(T), key)) = (T) value)) - #define bh_table_has(T, tab, key) (assert(sizeof(T) == sizeof(*(tab))), (bh__table_has((bh__table *) tab, sizeof(T), key))) - #define bh_table_get(T, tab, key) (assert(sizeof(T) == sizeof(*(tab))), (*((T *) bh__table_get((bh__table *) tab, sizeof(T), key)))) - #define bh_table_delete(T, tab, key) (assert(sizeof(T) == sizeof(*(tab))), bh__table_delete((bh__table *) tab, sizeof(T), key)) - #define bh_table_clear(tab) (bh__table_clear((bh__table *) tab)) - - #define bh_table_iter_setup(T, tab) (assert(sizeof(T) == sizeof(*(tab))), bh__table_iter_setup((bh__table *) tab, sizeof(T))) - #define bh_table_iter_key(it) ((char *)(bh_pointer_add(it.entry, it.elemsize + sizeof(u16)))) - #define bh_table_iter_value(T, it) (*(T *)it.entry) + #define bh_table_init(allocator_, tab, hs) bh__table_init(allocator_, (bh__table **)&(tab), hs) + #define bh_table_free(tab) bh__table_free((bh__table **)&(tab)) + #define bh_table_put(T, tab, key, value) (assert(sizeof(T) == sizeof(*(tab))), (*((T *) bh__table_put((bh__table *) tab, sizeof(T), key)) = (T) value)) + #define bh_table_has(T, tab, key) (assert(sizeof(T) == sizeof(*(tab))), (bh__table_has((bh__table *) tab, sizeof(T), key))) + #define bh_table_get(T, tab, key) (assert(sizeof(T) == sizeof(*(tab))), (*((T *) bh__table_get((bh__table *) tab, sizeof(T), key)))) + #define bh_table_delete(T, tab, key) (assert(sizeof(T) == sizeof(*(tab))), bh__table_delete((bh__table *) tab, sizeof(T), key)) + #define bh_table_clear(tab) (bh__table_clear((bh__table *) tab)) + + #define bh_table_iter_setup(T, tab) (assert(sizeof(T) == sizeof(*(tab))), bh__table_iter_setup((bh__table *) tab, sizeof(T))) + #define bh_table_iter_key(it) ((char *)(bh_pointer_add(it.entry, it.elemsize + sizeof(u16)))) + #define bh_table_iter_value(T, it) (*(T *)it.entry) #else - #define bh_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_iter_value(T, it) (*(T *)it.entry) + #define bh_table_init(allocator_, tab, hs) bh__table_init(allocator_, (bh__table **)&(tab), hs) + #define bh_table_free(tab) bh__table_free((bh__table **)&(tab)) + #define bh_table_put(T, tab, key, value) (*((T *) bh__table_put((bh__table *) tab, sizeof(T), key)) = (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 #define bh_table_each_start(T, table) { \ - bh_table_iterator it = bh_table_iter_setup(T, (table)); \ - while (bh_table_iter_next(&it)) { \ - const char* key = bh_table_iter_key(it); \ - T value = bh_table_iter_value(T, it); -#define bh_table_each_end } } + bh_table_iterator it = bh_table_iter_setup(T, (table)); \ + while (bh_table_iter_next(&it)) { \ + const char* key = bh_table_iter_key(it); \ + T value = bh_table_iter_value(T, it); +#define bh_table_each_end } } b32 bh__table_init(bh_allocator allocator, bh__table **table, i32 table_size); b32 bh__table_free(bh__table **table); @@ -736,58 +736,58 @@ extern inline 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); + return bh_alloc_aligned(a, size, 16); } ptr bh_alloc_aligned(bh_allocator a, isize size, isize alignment) { - return a.proc(a.data, bh_allocator_action_alloc, size, alignment, NULL, 0); + return a.proc(a.data, bh_allocator_action_alloc, size, alignment, NULL, 0); } ptr bh_resize(bh_allocator a, ptr data, isize new_size) { - return bh_resize_aligned(a, data, new_size, 16); + return bh_resize_aligned(a, data, new_size, 16); } ptr bh_resize_aligned(bh_allocator a, ptr data, isize new_size, isize alignment) { - return a.proc(a.data, bh_allocator_action_resize, new_size, alignment, data, 0); + return a.proc(a.data, bh_allocator_action_resize, new_size, alignment, data, 0); } void bh_free(bh_allocator a, ptr data) { - if (data != NULL) a.proc(a.data, bh_allocator_action_free, 0, 0, data, 0); + if (data != NULL) a.proc(a.data, bh_allocator_action_free, 0, 0, data, 0); } // HEAP ALLOCATOR IMPLEMENTATION bh_allocator bh_heap_allocator(void) { - return (bh_allocator) { - .proc = bh_heap_allocator_proc, - .data = NULL - }; + return (bh_allocator) { + .proc = bh_heap_allocator_proc, + .data = NULL + }; } BH_ALLOCATOR_PROC(bh_heap_allocator_proc) { - ptr retval = NULL; + ptr retval = NULL; - switch (action) { - case bh_allocator_action_alloc: { - retval = aligned_alloc(alignment, size); + switch (action) { + case bh_allocator_action_alloc: { + retval = aligned_alloc(alignment, size); - if (flags & bh_allocator_flag_clear && retval != NULL) { - memset(retval, 0, size); - } - } break; + if (flags & bh_allocator_flag_clear && retval != NULL) { + memset(retval, 0, size); + } + } break; - case bh_allocator_action_resize: { - // TODO: Maybe replace with better custom function - retval = realloc(prev_memory, size); - } break; + case bh_allocator_action_resize: { + // TODO: Maybe replace with better custom function + retval = realloc(prev_memory, size); + } break; - case bh_allocator_action_free: { - free(prev_memory); - } break; - } + case bh_allocator_action_free: { + free(prev_memory); + } break; + } - return retval; + return retval; } @@ -798,83 +798,83 @@ BH_ALLOCATOR_PROC(bh_heap_allocator_proc) { // ARENA ALLOCATOR IMPLEMENTATION void bh_arena_init(bh_arena* alloc, bh_allocator backing, isize arena_size) { - arena_size = bh_max(arena_size, sizeof(ptr)); - ptr data = bh_alloc(backing, arena_size); + arena_size = bh_max(arena_size, sizeof(ptr)); + ptr data = bh_alloc(backing, arena_size); - alloc->backing = backing; - alloc->arena_size = arena_size; - alloc->size = sizeof(ptr); - alloc->first_arena = data; - alloc->current_arena = data; + alloc->backing = backing; + alloc->arena_size = arena_size; + alloc->size = sizeof(ptr); + alloc->first_arena = data; + alloc->current_arena = data; - ((bh__arena_internal *)(alloc->first_arena))->next_arena = NULL; + ((bh__arena_internal *)(alloc->first_arena))->next_arena = NULL; } void bh_arena_free(bh_arena* alloc) { - bh__arena_internal *walker = (bh__arena_internal *) alloc->first_arena; - bh__arena_internal *trailer = walker; - while (walker != NULL) { - walker = walker->next_arena; - bh_free(alloc->backing, trailer); - trailer = walker; - } + bh__arena_internal *walker = (bh__arena_internal *) alloc->first_arena; + bh__arena_internal *trailer = walker; + while (walker != NULL) { + walker = walker->next_arena; + bh_free(alloc->backing, trailer); + trailer = walker; + } - alloc->first_arena = NULL; - alloc->current_arena = NULL; - alloc->arena_size = 0; - alloc->size = 0; + alloc->first_arena = NULL; + alloc->current_arena = NULL; + alloc->arena_size = 0; + alloc->size = 0; } bh_allocator bh_arena_allocator(bh_arena* alloc) { - return (bh_allocator) { - .proc = bh_arena_allocator_proc, - .data = alloc, - }; + return (bh_allocator) { + .proc = bh_arena_allocator_proc, + .data = alloc, + }; } BH_ALLOCATOR_PROC(bh_arena_allocator_proc) { - bh_arena* alloc_arena = (bh_arena*) data; + bh_arena* alloc_arena = (bh_arena*) data; - ptr retval = NULL; + ptr retval = NULL; - switch (action) { - case bh_allocator_action_alloc: { + switch (action) { + case bh_allocator_action_alloc: { - // TODO: Do this better because right now bh__align is bad - // size = bh__align(size, alignment); - if (size > alloc_arena->arena_size - sizeof(ptr)) { - // Size too large for the arena - return NULL; - } + // TODO: Do this better because right now bh__align is bad + // size = bh__align(size, alignment); + if (size > alloc_arena->arena_size - sizeof(ptr)) { + // Size too large for the arena + return NULL; + } - if (alloc_arena->size + size >= alloc_arena->arena_size) { - alloc_arena->size = sizeof(ptr); - bh__arena_internal* new_arena = (bh__arena_internal *) bh_alloc(alloc_arena->backing, alloc_arena->arena_size); + if (alloc_arena->size + size >= alloc_arena->arena_size) { + alloc_arena->size = sizeof(ptr); + bh__arena_internal* new_arena = (bh__arena_internal *) bh_alloc(alloc_arena->backing, alloc_arena->arena_size); - if (new_arena == NULL) { - bh_printf_err("Arena Allocator: couldn't allocate new arena"); - return NULL; - } + if (new_arena == NULL) { + bh_printf_err("Arena Allocator: couldn't allocate new arena"); + return NULL; + } - new_arena->next_arena = NULL; - ((bh__arena_internal *)(alloc_arena->current_arena))->next_arena = new_arena; - alloc_arena->current_arena = new_arena; - } + new_arena->next_arena = NULL; + ((bh__arena_internal *)(alloc_arena->current_arena))->next_arena = new_arena; + alloc_arena->current_arena = new_arena; + } - retval = bh_pointer_add(alloc_arena->current_arena, alloc_arena->size); - alloc_arena->size += size; - } break; + retval = bh_pointer_add(alloc_arena->current_arena, alloc_arena->size); + alloc_arena->size += size; + } break; - case bh_allocator_action_resize: { - // Do nothing since this is a fixed allocator - } break; + case bh_allocator_action_resize: { + // Do nothing since this is a fixed allocator + } break; - case bh_allocator_action_free: { - // Do nothing since this allocator isn't made for freeing memory - } break; - } + case bh_allocator_action_free: { + // Do nothing since this allocator isn't made for freeing memory + } break; + } - return retval; + return retval; } @@ -882,69 +882,69 @@ BH_ALLOCATOR_PROC(bh_arena_allocator_proc) { // SCRATCH ALLOCATOR IMPLEMENTATION void bh_scratch_init(bh_scratch* scratch, bh_allocator backing, isize scratch_size) { - ptr memory = bh_alloc(backing, scratch_size); + ptr memory = bh_alloc(backing, scratch_size); - scratch->backing = backing; - scratch->memory = memory; - scratch->curr = memory; - scratch->end = memory + scratch_size; + scratch->backing = backing; + scratch->memory = memory; + scratch->curr = memory; + scratch->end = memory + scratch_size; } void bh_scratch_free(bh_scratch* scratch) { - bh_free(scratch->backing, scratch->memory); + bh_free(scratch->backing, scratch->memory); - scratch->memory = NULL; - scratch->curr = NULL; - scratch->end = NULL; + scratch->memory = NULL; + scratch->curr = NULL; + scratch->end = NULL; } bh_allocator bh_scratch_allocator(bh_scratch* scratch) { - return (bh_allocator) { - .proc = bh_scratch_allocator_proc, - .data = scratch, - }; + return (bh_allocator) { + .proc = bh_scratch_allocator_proc, + .data = scratch, + }; } BH_ALLOCATOR_PROC(bh_scratch_allocator_proc) { - bh_scratch* scratch = (bh_scratch*) data; - ptr retval = NULL; + bh_scratch* scratch = (bh_scratch*) data; + ptr retval = NULL; - switch (action) { - case bh_allocator_action_alloc: { - if (size > scratch->end - scratch->memory) { - return NULL; - } + switch (action) { + case bh_allocator_action_alloc: { + if (size > scratch->end - scratch->memory) { + return NULL; + } - retval = scratch->curr; - scratch->curr += size; + retval = scratch->curr; + scratch->curr += size; - if (scratch->curr >= scratch->end) { - scratch->curr = scratch->memory; - retval = scratch->curr; - } - } break; + if (scratch->curr >= scratch->end) { + scratch->curr = scratch->memory; + retval = scratch->curr; + } + } break; - case bh_allocator_action_free: break; + case bh_allocator_action_free: break; - case bh_allocator_action_resize: { - if (size > scratch->end - scratch->memory) { - return NULL; - } + case bh_allocator_action_resize: { + if (size > scratch->end - scratch->memory) { + return NULL; + } - retval = scratch->curr; - scratch->curr += size; + retval = scratch->curr; + scratch->curr += size; - if (scratch->curr >= scratch->end) { - scratch->curr = scratch->memory; - retval = scratch->curr; - } + if (scratch->curr >= scratch->end) { + scratch->curr = scratch->memory; + retval = scratch->curr; + } // HACK!!!!!: Using size instead of some kind of "old size" memcpy(retval, prev_memory, size); - } break; - } + } break; + } - return retval; + return retval; } @@ -954,54 +954,54 @@ BH_ALLOCATOR_PROC(bh_scratch_allocator_proc) { // CONVERSION FUNCTIONS IMPLEMENTATION //------------------------------------------------------------------------------------- u8* uint_to_uleb128(u64 n, i32* output_length) { - static u8 buffer[16]; + static u8 buffer[16]; - *output_length = 0; - u8* output = buffer; - u8 byte; - do { - byte = n & 0x7f; - n >>= 7; - if (n != 0) byte |= (1 << 7); - *output++ = byte; - (*output_length)++; - } while (n != 0); + *output_length = 0; + u8* output = buffer; + u8 byte; + do { + byte = n & 0x7f; + n >>= 7; + if (n != 0) byte |= (1 << 7); + *output++ = byte; + (*output_length)++; + } while (n != 0); - return buffer; + return buffer; } // Converts a signed integer to the signed LEB128 format u8* int_to_leb128(i64 n, i32* output_length) { - static u8 buffer[16]; + static u8 buffer[16]; - *output_length = 0; - u8* output = buffer; - b32 more = 1; + *output_length = 0; + u8* output = buffer; + b32 more = 1; - i32 size = 64; + i32 size = 64; - u8 byte; - do { - byte = n & 0x7f; - n >>= 7; + u8 byte; + do { + byte = n & 0x7f; + n >>= 7; - more = !(((n == 0) && (byte & 0x40) == 0) || ((n == -1) && (byte & 0x40) != 0)); - if (more) - byte |= 0x80; - *output++ = byte; - (*output_length)++; - } while (more); + more = !(((n == 0) && (byte & 0x40) == 0) || ((n == -1) && (byte & 0x40) != 0)); + if (more) + byte |= 0x80; + *output++ = byte; + (*output_length)++; + } while (more); - return buffer; + return buffer; } // NOTE: This assumes the underlying implementation of float on the host // system is already IEEE-754. This is safe to assume in most cases. u8* float_to_ieee754(f32 f, b32 reverse) { - static u8 buffer[4]; + static u8 buffer[4]; - u8* fmem = (u8*) &f; + u8* fmem = (u8*) &f; if (reverse) { buffer[0] = fmem[3]; buffer[1] = fmem[2]; @@ -1014,13 +1014,13 @@ u8* float_to_ieee754(f32 f, b32 reverse) { buffer[3] = fmem[3]; } - return buffer; + return buffer; } u8* double_to_ieee754(f64 f, b32 reverse) { - static u8 buffer[8]; + static u8 buffer[8]; - u8* fmem = (u8*) &f; + u8* fmem = (u8*) &f; if (reverse) { buffer[0] = fmem[7]; buffer[1] = fmem[6]; @@ -1041,7 +1041,7 @@ u8* double_to_ieee754(f64 f, b32 reverse) { buffer[7] = fmem[7]; } - return buffer; + return buffer; } @@ -1061,186 +1061,186 @@ u8* double_to_ieee754(f64 f, b32 reverse) { #ifndef BH_NO_FILE bh_file_error bh_file_get_standard(bh_file* file, bh_file_standard stand) { - i32 sd_fd = -1; - const char* filename = NULL; - - switch (stand) { - case BH_FILE_STANDARD_INPUT: - sd_fd = STDIN_FILENO; - filename = "stdin"; // These are constants in the data section so everything should be okay - break; - case BH_FILE_STANDARD_OUTPUT: - sd_fd = STDOUT_FILENO; - filename = "stdout"; - break; - case BH_FILE_STANDARD_ERROR: - sd_fd = STDERR_FILENO; - filename = "stderr"; - break; - default: - return BH_FILE_ERROR_BAD_FD; - } - - file->fd = sd_fd; - file->filename = filename; - - return BH_FILE_ERROR_NONE; + i32 sd_fd = -1; + const char* filename = NULL; + + switch (stand) { + case BH_FILE_STANDARD_INPUT: + sd_fd = STDIN_FILENO; + filename = "stdin"; // These are constants in the data section so everything should be okay + break; + case BH_FILE_STANDARD_OUTPUT: + sd_fd = STDOUT_FILENO; + filename = "stdout"; + break; + case BH_FILE_STANDARD_ERROR: + sd_fd = STDERR_FILENO; + filename = "stderr"; + break; + default: + return BH_FILE_ERROR_BAD_FD; + } + + file->fd = sd_fd; + file->filename = filename; + + return BH_FILE_ERROR_NONE; } bh_file_error bh_file_create(bh_file* file, const char* filename) { - // Need to do this to avoid compiler complaining about types - bh_file_mode write_rw = (bh_file_mode) (BH_FILE_MODE_WRITE | BH_FILE_MODE_RW); - return bh_file_open_mode(file, write_rw, filename); + // Need to do this to avoid compiler complaining about types + bh_file_mode write_rw = (bh_file_mode) (BH_FILE_MODE_WRITE | BH_FILE_MODE_RW); + return bh_file_open_mode(file, write_rw, filename); } bh_file_error bh_file_open(bh_file* file, const char* filename) { - return bh_file_open_mode(file, BH_FILE_MODE_READ, filename); + return bh_file_open_mode(file, BH_FILE_MODE_READ, filename); } bh_file_error bh_file_open_mode(bh_file* file, bh_file_mode mode, const char* filename) { - i32 os_mode = 0; + i32 os_mode = 0; - switch (mode & BH_FILE_MODE_MODES) { - case BH_FILE_MODE_READ: os_mode = O_RDONLY; break; - case BH_FILE_MODE_WRITE: os_mode = O_WRONLY | O_CREAT | O_TRUNC; break; - case BH_FILE_MODE_APPEND: os_mode = O_RDONLY | O_APPEND | O_CREAT; break; - case BH_FILE_MODE_READ | BH_FILE_MODE_RW: os_mode = O_RDWR; break; - case BH_FILE_MODE_WRITE | BH_FILE_MODE_RW: os_mode = O_RDWR | O_CREAT | O_TRUNC; break; - case BH_FILE_MODE_APPEND | BH_FILE_MODE_RW: os_mode = O_RDWR | O_APPEND | O_CREAT; break; - //default: // TODO Handle errors - } + switch (mode & BH_FILE_MODE_MODES) { + case BH_FILE_MODE_READ: os_mode = O_RDONLY; break; + case BH_FILE_MODE_WRITE: os_mode = O_WRONLY | O_CREAT | O_TRUNC; break; + case BH_FILE_MODE_APPEND: os_mode = O_RDONLY | O_APPEND | O_CREAT; break; + case BH_FILE_MODE_READ | BH_FILE_MODE_RW: os_mode = O_RDWR; break; + case BH_FILE_MODE_WRITE | BH_FILE_MODE_RW: os_mode = O_RDWR | O_CREAT | O_TRUNC; break; + case BH_FILE_MODE_APPEND | BH_FILE_MODE_RW: os_mode = O_RDWR | O_APPEND | O_CREAT; break; + //default: // TODO Handle errors + } - file->fd = open(filename, os_mode, - S_IRUSR | S_IWUSR | S_IROTH | S_IWOTH | S_IRGRP | S_IWGRP //+rw-rw-rw- - ); - if (file->fd < 0) { - return BH_FILE_ERROR_INVALID; - } + file->fd = open(filename, os_mode, + S_IRUSR | S_IWUSR | S_IROTH | S_IWOTH | S_IRGRP | S_IWGRP //+rw-rw-rw- + ); + if (file->fd < 0) { + return BH_FILE_ERROR_INVALID; + } - // TODO: Set this using some allocator - file->filename = filename; + // TODO: Set this using some allocator + file->filename = filename; - return BH_FILE_ERROR_NONE; + return BH_FILE_ERROR_NONE; } bh_file_error bh_file_new(bh_file* file, bh_file_descriptor fd, const char* filename) { - file->filename = filename; // This may be unsafe - file->fd = fd; - return BH_FILE_ERROR_NONE; + file->filename = filename; // This may be unsafe + file->fd = fd; + return BH_FILE_ERROR_NONE; } b32 bh_file_read_at(bh_file* file, i64 offset, void* buffer, isize buff_size, isize* bytes_read) { - isize res = pread(file->fd, buffer, buff_size, offset); - if (res < 0) return 0; - if (bytes_read) *bytes_read = res; - return 1; + isize res = pread(file->fd, buffer, buff_size, offset); + if (res < 0) return 0; + if (bytes_read) *bytes_read = res; + return 1; } b32 bh_file_write_at(bh_file* file, i64 offset, void const* buffer, isize buff_size, isize* bytes_wrote) { - isize res; - i64 current_offset = 0; - bh__file_seek_wrapper(file->fd, offset, BH_FILE_WHENCE_CURRENT, ¤t_offset); - if (current_offset == offset) { - // Standard in and out do like pwrite() - res = write(file->fd, buffer, buff_size); - } else { - res = pwrite(file->fd, buffer, buff_size, offset); - } - if (res < 0) return 0; - if (bytes_wrote) *bytes_wrote = res; + isize res; + i64 current_offset = 0; + bh__file_seek_wrapper(file->fd, offset, BH_FILE_WHENCE_CURRENT, ¤t_offset); + if (current_offset == offset) { + // Standard in and out do like pwrite() + res = write(file->fd, buffer, buff_size); + } else { + res = pwrite(file->fd, buffer, buff_size, offset); + } + if (res < 0) return 0; + if (bytes_wrote) *bytes_wrote = res; - return 1; + return 1; } static b32 bh__file_seek_wrapper(i32 fd, i64 offset, bh_file_whence whence, i64* new_offset) { - i64 res = lseek(fd, offset, whence); - if (res < 0) return 0; - if (new_offset) *new_offset = res; - return 1; + i64 res = lseek(fd, offset, whence); + if (res < 0) return 0; + if (new_offset) *new_offset = res; + return 1; } // Returns new offset i64 bh_file_seek_to(bh_file* file, i64 offset) { - i64 new_offset = -1; - bh__file_seek_wrapper(file->fd, offset, BH_FILE_WHENCE_BEGIN, &new_offset); - return new_offset; + i64 new_offset = -1; + bh__file_seek_wrapper(file->fd, offset, BH_FILE_WHENCE_BEGIN, &new_offset); + return new_offset; } i64 bh_file_seek_to_end(bh_file* file) { - i64 new_offset = -1; - bh__file_seek_wrapper(file->fd, 0, BH_FILE_WHENCE_END, &new_offset); - return new_offset; + i64 new_offset = -1; + bh__file_seek_wrapper(file->fd, 0, BH_FILE_WHENCE_END, &new_offset); + return new_offset; } i64 bh_file_skip(bh_file* file, i64 bytes) { - i64 new_offset = 0; - bh__file_seek_wrapper(file->fd, bytes, BH_FILE_WHENCE_CURRENT, &new_offset); - return new_offset; + i64 new_offset = 0; + bh__file_seek_wrapper(file->fd, bytes, BH_FILE_WHENCE_CURRENT, &new_offset); + return new_offset; } i64 bh_file_tell(bh_file* file) { - i64 new_offset = 0; - bh__file_seek_wrapper(file->fd, 0, BH_FILE_WHENCE_CURRENT, &new_offset); - return new_offset; + i64 new_offset = 0; + bh__file_seek_wrapper(file->fd, 0, BH_FILE_WHENCE_CURRENT, &new_offset); + return new_offset; } bh_file_error bh_file_close(bh_file* file) { - bh_file_error err = BH_FILE_ERROR_NONE; - i32 res = close(file->fd); - if (res < 0) - err = BH_FILE_ERROR_INVALID; + bh_file_error err = BH_FILE_ERROR_NONE; + i32 res = close(file->fd); + if (res < 0) + err = BH_FILE_ERROR_INVALID; - return err; + return err; } b32 bh_file_read(bh_file* file, void* buffer, isize buff_size) { - return bh_file_read_at(file, bh_file_tell(file), buffer, buff_size, NULL); + return bh_file_read_at(file, bh_file_tell(file), buffer, buff_size, NULL); } b32 bh_file_write(bh_file* file, void* buffer, isize buff_size) { - return bh_file_write_at(file, bh_file_tell(file), buffer, buff_size, NULL); + return bh_file_write_at(file, bh_file_tell(file), buffer, buff_size, NULL); } i64 bh_file_size(bh_file* file) { - i64 size = 0; - i64 prev = bh_file_tell(file); - bh_file_seek_to_end(file); - size = bh_file_tell(file); - bh_file_seek_to(file, prev); - return size; + i64 size = 0; + i64 prev = bh_file_tell(file); + bh_file_seek_to_end(file); + size = bh_file_tell(file); + bh_file_seek_to(file, prev); + return size; } bh_file_contents bh_file_read_contents_bh_file(bh_allocator alloc, bh_file* file) { - bh_file_contents fc = { - .allocator = alloc, - .filename = file->filename, - .length = 0, .data = NULL - }; + bh_file_contents fc = { + .allocator = alloc, + .filename = file->filename, + .length = 0, .data = NULL + }; - isize size = bh_file_size(file); - if (size <= 0) return fc; + isize size = bh_file_size(file); + if (size <= 0) return fc; - fc.data = bh_alloc(alloc, size + 1); - fc.length = size; - bh_file_read_at(file, 0, fc.data, fc.length, NULL); - ((u8*) fc.data)[fc.length] = '\0'; + fc.data = bh_alloc(alloc, size + 1); + fc.length = size; + bh_file_read_at(file, 0, fc.data, fc.length, NULL); + ((u8*) fc.data)[fc.length] = '\0'; - return fc; + return fc; } bh_file_contents bh_file_read_contents_direct(bh_allocator alloc, const char* filename) { - bh_file file; - bh_file_open(&file, filename); - bh_file_contents fc = bh_file_read_contents(alloc, &file); - bh_file_close(&file); - return fc; + bh_file file; + bh_file_open(&file, filename); + bh_file_contents fc = bh_file_read_contents(alloc, &file); + bh_file_close(&file); + return fc; } b32 bh_file_contents_free(bh_file_contents* contents) { - bh_free(contents->allocator, contents->data); - contents->length = 0; - return 1; + bh_free(contents->allocator, contents->data); + contents->length = 0; + return 1; } #endif // ifndef BH_NO_FILE @@ -1266,243 +1266,243 @@ b32 bh_file_contents_free(bh_file_contents* contents) { // ALTERNATE PRINTF IMPLEMENTATION //------------------------------------------------------------------------------------- isize bh_printf(char const *fmt, ...) { - isize res; - va_list va; - va_start(va, fmt); - res = bh_printf_va(fmt, va); - va_end(va); - return res; + isize res; + va_list va; + va_start(va, fmt); + res = bh_printf_va(fmt, va); + va_end(va); + return res; } isize bh_printf_va(char const *fmt, va_list va) { - bh_file file; - bh_file_get_standard(&file, BH_FILE_STANDARD_OUTPUT); - return bh_fprintf_va(&file, fmt, va); + bh_file file; + bh_file_get_standard(&file, BH_FILE_STANDARD_OUTPUT); + return bh_fprintf_va(&file, fmt, va); } isize bh_printf_err(char const *fmt, ...) { - isize res; - va_list va; - va_start(va, fmt); - res = bh_printf_err_va(fmt, va); - va_end(va); - return res; + isize res; + va_list va; + va_start(va, fmt); + res = bh_printf_err_va(fmt, va); + va_end(va); + return res; } isize bh_printf_err_va(char const *fmt, va_list va) { - bh_file file; - bh_file_get_standard(&file, BH_FILE_STANDARD_ERROR); - return bh_fprintf_va(&file, fmt, va); + bh_file file; + bh_file_get_standard(&file, BH_FILE_STANDARD_ERROR); + return bh_fprintf_va(&file, fmt, va); } isize bh_fprintf(bh_file* f, char const *fmt, ...) { - isize res; - va_list va; - va_start(va, fmt); - res = bh_fprintf_va(f, fmt, va); - va_end(va); - return res; + isize res; + va_list va; + va_start(va, fmt); + res = bh_fprintf_va(f, fmt, va); + va_end(va); + return res; } isize bh_fprintf_va(bh_file* f, char const *fmt, va_list va) { - static char buffer[4096]; - isize len = bh_snprintf_va(buffer, sizeof(buffer), fmt, va); - bh_file_write(f, buffer, len - 1); - return len; + static char buffer[4096]; + isize len = bh_snprintf_va(buffer, sizeof(buffer), fmt, va); + bh_file_write(f, buffer, len - 1); + return len; } char* bh_bprintf(char const *fmt, ...) { - char* res; - va_list va; - va_start(va, fmt); - res = bh_bprintf_va(fmt, va); - va_end(va); - return res; + char* res; + va_list va; + va_start(va, fmt); + res = bh_bprintf_va(fmt, va); + va_end(va); + return res; } char* bh_bprintf_va(char const *fmt, va_list va) { - static char buffer[4096]; - bh_snprintf_va(buffer, sizeof(buffer), fmt, va); - return buffer; + static char buffer[4096]; + bh_snprintf_va(buffer, sizeof(buffer), fmt, 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* 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; + 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; - va_start(va, fmt); - res = bh_snprintf_va(str, n, fmt, va); - va_end(va); - return res; + isize res; + va_list va; + va_start(va, fmt); + res = bh_snprintf_va(str, n, fmt, va); + va_end(va); + return res; } isize bh__print_string(char* dest, isize n, char* src) { - isize len = 0; - while (n-- && (*dest++ = *src++)) len++; - return len; + isize len = 0; + while (n-- && (*dest++ = *src++)) len++; + return len; } isize bh__printu64(char* str, isize n, bh__print_format format, u64 value) { - char buf[128]; - buf[127] = 0; - char* walker = buf + 127; - u32 base = format.base ? format.base : 10, tmp; - - while (value > 0) { - tmp = value % base; - if (tmp > 9) { - switch (tmp) { - case 10: tmp = 'a'; break; - case 11: tmp = 'b'; break; - case 12: tmp = 'c'; break; - case 13: tmp = 'd'; break; - case 14: tmp = 'e'; break; - case 15: tmp = 'f'; break; - } - } else { - tmp += '0'; - } - - *--walker = tmp; - value /= base; - } - - if (format.base == 16) { - *--walker = 'x'; - *--walker = '0'; - } - - return bh__print_string(str, n, walker); -} + char buf[128]; + buf[127] = 0; + char* walker = buf + 127; + u32 base = format.base ? format.base : 10, tmp; + + while (value > 0) { + tmp = value % base; + if (tmp > 9) { + switch (tmp) { + case 10: tmp = 'a'; break; + case 11: tmp = 'b'; break; + case 12: tmp = 'c'; break; + case 13: tmp = 'd'; break; + case 14: tmp = 'e'; break; + case 15: tmp = 'f'; break; + } + } else { + tmp += '0'; + } -isize bh__printi64(char* str, isize n, bh__print_format format, i64 value) { - char buf[128]; - buf[127] = 0; - char* walker = buf + 127; - u32 base = format.base ? format.base : 10, tmp; - - b32 negative = value < 0; - if (negative) value = -value; - - if (value == 0) { - *--walker = '0'; - } else { - while (value > 0) { - tmp = value % base; - if (tmp > 9) { - switch (tmp) { - case 10: tmp = 'a'; break; - case 11: tmp = 'b'; break; - case 12: tmp = 'c'; break; - case 13: tmp = 'd'; break; - case 14: tmp = 'e'; break; - case 15: tmp = 'f'; break; - } - } else { - tmp += '0'; - } - - *--walker = tmp; - value /= base; - } - } - - if (negative) { - *--walker = '-'; - } - - if (format.base == 16) { - *--walker = 'x'; - *--walker = '0'; - } - - return bh__print_string(str, n, walker); + *--walker = tmp; + value /= base; + } + + if (format.base == 16) { + *--walker = 'x'; + *--walker = '0'; + } + + return bh__print_string(str, n, walker); } -// TODO: This is very hacked together but for now it will work. -isize bh_snprintf_va(char *str, isize n, char const *fmt, va_list va) { - char const *text_start = str; - isize res; +isize bh__printi64(char* str, isize n, bh__print_format format, i64 value) { + char buf[128]; + buf[127] = 0; + char* walker = buf + 127; + u32 base = format.base ? format.base : 10, tmp; - while (*fmt) { - bh__print_format format = { 0 }; - isize len = 0; + b32 negative = value < 0; + if (negative) value = -value; - while (*fmt && *fmt != '%') { - *(str++) = *(fmt++); - } + if (value == 0) { + *--walker = '0'; + } else { + while (value > 0) { + tmp = value % base; + if (tmp > 9) { + switch (tmp) { + case 10: tmp = 'a'; break; + case 11: tmp = 'b'; break; + case 12: tmp = 'c'; break; + case 13: tmp = 'd'; break; + case 14: tmp = 'e'; break; + case 15: tmp = 'f'; break; + } + } else { + tmp += '0'; + } + + *--walker = tmp; + value /= base; + } + } - if (!*fmt) goto end_of_format; + if (negative) { + *--walker = '-'; + } - fmt++; + if (format.base == 16) { + *--walker = 'x'; + *--walker = '0'; + } - switch (*fmt++) { - case 'o': format.base = 8; break; - case 'x': format.base = 16; break; - default: fmt--; - } + return bh__print_string(str, n, walker); +} - switch (*fmt) { - case 'c': { - char c = (char) va_arg(va, int); - *(str++) = c; - } break; +// TODO: This is very hacked together but for now it will work. +isize bh_snprintf_va(char *str, isize n, char const *fmt, va_list va) { + char const *text_start = str; + isize res; - case 'd': { - i64 value = (i64) va_arg(va, int); - len = bh__printi64(str, n, format, value); - } break; + while (*fmt) { + bh__print_format format = { 0 }; + isize len = 0; - case 'l': { - i64 value = (i64) va_arg(va, long); - len = bh__printi64(str, n, format, value); - } break; + while (*fmt && *fmt != '%') { + *(str++) = *(fmt++); + } - case 'p': { - u64 value = (u64) va_arg(va, ptr); - format.base = 16; - len = bh__printu64(str, n, format, value); - } break; + if (!*fmt) goto end_of_format; - case 's': { - char* s = va_arg(va, char *); - len = bh__print_string(str, n, s); - } break; + fmt++; - case 'b': { // String with a length (not null terminated) - char* s = va_arg(va, char *); - i32 l = va_arg(va, int); - len = bh__print_string(str, bh_min(l, n), s); - } break; + switch (*fmt++) { + case 'o': format.base = 8; break; + case 'x': format.base = 16; break; + default: fmt--; + } - default: fmt--; - } + switch (*fmt) { + case 'c': { + char c = (char) va_arg(va, int); + *(str++) = c; + } break; + + case 'd': { + i64 value = (i64) va_arg(va, int); + len = bh__printi64(str, n, format, value); + } break; + + case 'l': { + i64 value = (i64) va_arg(va, long); + len = bh__printi64(str, n, format, value); + } break; + + case 'p': { + u64 value = (u64) va_arg(va, ptr); + format.base = 16; + len = bh__printu64(str, n, format, value); + } break; + + case 's': { + char* s = va_arg(va, char *); + len = bh__print_string(str, n, s); + } break; + + case 'b': { // String with a length (not null terminated) + char* s = va_arg(va, char *); + i32 l = va_arg(va, int); + len = bh__print_string(str, bh_min(l, n), s); + } break; + + default: fmt--; + } - fmt++; + fmt++; end_of_format: - str += len; - n -= len; - } + str += len; + n -= len; + } - return str - text_start + 1; + return str - text_start + 1; } @@ -1515,54 +1515,54 @@ end_of_format: #ifndef BH_NO_BUFFER void bh_buffer_init(bh_buffer* buffer, bh_allocator alloc, i32 init_size) { - buffer->allocator = alloc; - buffer->length = 0; - buffer->capacity = init_size; - buffer->data = bh_alloc(alloc, init_size); + buffer->allocator = alloc; + buffer->length = 0; + buffer->capacity = init_size; + buffer->data = bh_alloc(alloc, init_size); } void bh_buffer_free(bh_buffer* buffer) { - bh_free(buffer->allocator, buffer->data); - buffer->length = 0; - buffer->capacity = 0; + bh_free(buffer->allocator, buffer->data); + buffer->length = 0; + buffer->capacity = 0; } void bh_buffer_grow(bh_buffer* buffer, i32 length) { - if (buffer == NULL) return; + if (buffer == NULL) return; - if (buffer->capacity >= length) { - // NOTE: Already have enough room - return; - } + if (buffer->capacity >= length) { + // NOTE: Already have enough room + return; + } - i32 newcap = buffer->capacity; - while (newcap < length) newcap = BH_BUFFER_GROW_FORMULA(newcap); + i32 newcap = buffer->capacity; + while (newcap < length) newcap = BH_BUFFER_GROW_FORMULA(newcap); - ptr new_data = bh_resize(buffer->allocator, buffer->data, newcap); - if (new_data == NULL) return; + ptr new_data = bh_resize(buffer->allocator, buffer->data, newcap); + if (new_data == NULL) return; - buffer->capacity = newcap; - buffer->data = new_data; + buffer->capacity = newcap; + buffer->data = new_data; } void bh_buffer_append(bh_buffer* buffer, const void * data, i32 length) { - if (buffer == NULL) return; + if (buffer == NULL) return; - if (buffer->length + length > buffer->capacity) { - bh_buffer_grow(buffer, buffer->length + length); - } + if (buffer->length + length > buffer->capacity) { + bh_buffer_grow(buffer, buffer->length + length); + } - memcpy(buffer->data + buffer->length, data, length); - buffer->length += length; + memcpy(buffer->data + buffer->length, data, length); + buffer->length += length; } void bh_buffer_concat(bh_buffer* buffer, bh_buffer other) { - bh_buffer_append(buffer, other.data, other.length); + bh_buffer_append(buffer, other.data, other.length); } void bh_buffer_write_byte(bh_buffer* buffer, u8 byte) { - bh_buffer_grow(buffer, buffer->length + 1); - buffer->data[buffer->length++] = byte; + bh_buffer_grow(buffer, buffer->length + 1); + buffer->data[buffer->length++] = byte; } @@ -1596,113 +1596,113 @@ void bh_buffer_write_byte(bh_buffer* buffer, u8 byte) { #ifndef BH_NO_ARRAY b32 bh__arr_grow(bh_allocator alloc, void** arr, i32 elemsize, i32 cap) { - bh__arr* arrptr; + bh__arr* arrptr; - if (*arr == NULL) { - if (cap == 0 && elemsize == 0) return 1; + if (*arr == NULL) { + if (cap == 0 && elemsize == 0) return 1; - arrptr = (bh__arr *) bh_alloc(alloc, sizeof(*arrptr) + elemsize * cap); - if (arrptr == NULL) return 0; + arrptr = (bh__arr *) bh_alloc(alloc, sizeof(*arrptr) + elemsize * cap); + if (arrptr == NULL) return 0; - arrptr->allocator = alloc; - arrptr->capacity = cap; - arrptr->length = 0; + arrptr->allocator = alloc; + arrptr->capacity = cap; + arrptr->length = 0; - } else { - arrptr = bh__arrhead(*arr); + } else { + arrptr = bh__arrhead(*arr); - if (arrptr->capacity < cap) { - void* p; - i32 newcap = arrptr->capacity; - while (newcap < cap) newcap = BH_ARR_GROW_FORMULA(newcap); + if (arrptr->capacity < cap) { + void* p; + i32 newcap = arrptr->capacity; + while (newcap < cap) newcap = BH_ARR_GROW_FORMULA(newcap); - p = bh_resize(arrptr->allocator, arrptr, sizeof(*arrptr) + elemsize * newcap); + p = bh_resize(arrptr->allocator, arrptr, sizeof(*arrptr) + elemsize * newcap); - if (p) { - arrptr = (bh__arr *) p; - arrptr->capacity = newcap; - } else { - return 0; - } - } - } + if (p) { + arrptr = (bh__arr *) p; + arrptr->capacity = newcap; + } else { + return 0; + } + } + } - *arr = arrptr + 1; - return 1; + *arr = arrptr + 1; + return 1; } b32 bh__arr_shrink(void** arr, i32 elemsize, i32 cap) { - if (*arr == NULL) return 0; + if (*arr == NULL) return 0; - bh__arr* arrptr = bh__arrhead(*arr); - cap = bh_max(cap, arrptr->length); + bh__arr* arrptr = bh__arrhead(*arr); + cap = bh_max(cap, arrptr->length); - if (arrptr->capacity > cap) { - void* p = bh_resize(arrptr->allocator, arrptr, sizeof(*arrptr) + elemsize * cap); + if (arrptr->capacity > cap) { + void* p = bh_resize(arrptr->allocator, arrptr, sizeof(*arrptr) + elemsize * cap); - if (p) { - arrptr = (bh__arr *) p; - arrptr->capacity = cap; - } else { - return 0; - } - } + if (p) { + arrptr = (bh__arr *) p; + arrptr->capacity = cap; + } else { + return 0; + } + } - *arr = arrptr + 1; - return 1; + *arr = arrptr + 1; + return 1; } b32 bh__arr_free(void **arr) { if (*arr == NULL) return 0; - bh__arr* arrptr = bh__arrhead(*arr); - bh_free(arrptr->allocator, arrptr); - *arr = NULL; + bh__arr* arrptr = bh__arrhead(*arr); + bh_free(arrptr->allocator, arrptr); + *arr = NULL; } void* bh__arr_copy(bh_allocator alloc, void *arr, i32 elemsize) { - bh__arr* arrptr = bh__arrhead(arr); + bh__arr* arrptr = bh__arrhead(arr); - const i32 cap = arrptr->length; + const i32 cap = arrptr->length; - void* newarr = NULL; - bh__arr_grow(alloc, &newarr, elemsize, cap); - bh__arrhead(newarr)->length = cap; - bh__arrhead(newarr)->capacity = cap; - memcpy(newarr, arr, elemsize * arrptr->length); + void* newarr = NULL; + bh__arr_grow(alloc, &newarr, elemsize, cap); + bh__arrhead(newarr)->length = cap; + bh__arrhead(newarr)->capacity = cap; + memcpy(newarr, arr, elemsize * arrptr->length); - return newarr; + return newarr; } void bh__arr_deleten(void **arr, i32 elemsize, i32 index, i32 numelems) { - bh__arr* arrptr = bh__arrhead(*arr); + bh__arr* arrptr = bh__arrhead(*arr); - if (index >= arrptr->length) return; // Can't delete past the end of the array - if (numelems <= 0) return; // Can't delete nothing + if (index >= arrptr->length) return; // Can't delete past the end of the array + if (numelems <= 0) return; // Can't delete nothing - memmove( - (char *)(*arr) + elemsize * index, // Target - (char *)(*arr) + elemsize * (index + numelems), // Source - elemsize * (arrptr->length - (index + numelems))); // Length - arrptr->length -= numelems; + memmove( + (char *)(*arr) + elemsize * index, // Target + (char *)(*arr) + elemsize * (index + numelems), // Source + elemsize * (arrptr->length - (index + numelems))); // Length + arrptr->length -= numelems; } void bh__arr_insertn(void **arr, i32 elemsize, i32 index, i32 numelems) { - if (numelems) { - if (*arr == NULL) { - bh__arr_grow(bh_arr_allocator(arr), arr, elemsize, numelems); // Making a new array - return; - } - - bh__arr* arrptr = bh__arrhead(*arr); - if (!bh__arr_grow(bh_arr_allocator(arr), arr, elemsize, arrptr->length + numelems)) return; // Fail case - arrptr = bh__arrhead(*arr); - memmove( - (char *)(*arr) + elemsize * (index + numelems), - (char *)(*arr) + elemsize * index, - elemsize * (arrptr->length - index)); - arrptr->length += numelems; - } + if (numelems) { + if (*arr == NULL) { + bh__arr_grow(bh_arr_allocator(arr), arr, elemsize, numelems); // Making a new array + return; + } + + bh__arr* arrptr = bh__arrhead(*arr); + if (!bh__arr_grow(bh_arr_allocator(arr), arr, elemsize, arrptr->length + numelems)) return; // Fail case + arrptr = bh__arrhead(*arr); + memmove( + (char *)(*arr) + elemsize * (index + numelems), + (char *)(*arr) + elemsize * index, + elemsize * (arrptr->length - index)); + arrptr->length += numelems; + } } #endif // ifndef BH_NO_ARRAY @@ -1727,224 +1727,224 @@ void bh__arr_insertn(void **arr, i32 elemsize, i32 index, i32 numelems) { #ifndef BH_NO_TABLE b32 bh__table_init(bh_allocator allocator, bh__table **table, i32 table_size) { - *table = bh_alloc(allocator, sizeof(bh__table) + sizeof(ptr) * table_size); - if (*table == NULL) return 0; + *table = bh_alloc(allocator, sizeof(bh__table) + sizeof(ptr) * table_size); + if (*table == NULL) return 0; - (*table)->allocator = allocator; - (*table)->table_size = table_size; + (*table)->allocator = allocator; + (*table)->table_size = table_size; - for (i32 i = 0; i < table_size; i++) { - (*table)->arrs[i] = NULL; - } + for (i32 i = 0; i < table_size; i++) { + (*table)->arrs[i] = NULL; + } - return 1; + return 1; } b32 bh__table_free(bh__table **table) { if (*table == NULL) return 0; - for (i32 i = 0; i < (*table)->table_size; i++) { - if ((*table)->arrs[i] != NULL) { - bh_arr_free((*table)->arrs[i]); - } - } + for (i32 i = 0; i < (*table)->table_size; i++) { + if ((*table)->arrs[i] != NULL) { + bh_arr_free((*table)->arrs[i]); + } + } - bh_free((*table)->allocator, *table); - *table = NULL; + bh_free((*table)->allocator, *table); + *table = NULL; } // Assumes NULL terminated string for key ptr bh__table_put(bh__table *table, i32 elemsize, char *key) { - elemsize += (elemsize & 1); - - u64 index = bh__table_hash_function(key, 0, table->table_size); - u8 arr_was_new = 0; - - ptr arrptr = table->arrs[index]; - if (arrptr == NULL) { - arr_was_new = 1; - goto add_new_element; - } - u64 len = *(u64 *) arrptr; - arrptr = bh_pointer_add(arrptr, sizeof(u64)); - - u16 key_length = 0; - while (len--) { - arrptr = bh_pointer_add(arrptr, elemsize); - key_length = *(u16 *) arrptr; - arrptr = bh_pointer_add(arrptr, sizeof(u16)); - if (strncmp(key, (char *) arrptr, key_length) == 0) goto found_matching; - arrptr = bh_pointer_add(arrptr, key_length); - } + elemsize += (elemsize & 1); + + u64 index = bh__table_hash_function(key, 0, table->table_size); + u8 arr_was_new = 0; + + ptr arrptr = table->arrs[index]; + if (arrptr == NULL) { + arr_was_new = 1; + goto add_new_element; + } + u64 len = *(u64 *) arrptr; + arrptr = bh_pointer_add(arrptr, sizeof(u64)); + + u16 key_length = 0; + while (len--) { + arrptr = bh_pointer_add(arrptr, elemsize); + key_length = *(u16 *) arrptr; + arrptr = bh_pointer_add(arrptr, sizeof(u16)); + if (strncmp(key, (char *) arrptr, key_length) == 0) goto found_matching; + arrptr = bh_pointer_add(arrptr, key_length); + } add_new_element: - arrptr = table->arrs[index]; - i32 byte_len = bh_arr_length(arrptr); - if (byte_len == 0) byte_len = sizeof(u64); - key_length = strlen(key) + 1; - - // NOTE: Align to 16 bytes - if ((key_length + 2) % 16 != 0) { - key_length = ((((key_length + 2) >> 4) + 1) << 4) - 2; - } - - bh__arr_grow(table->allocator, &arrptr, 1, byte_len + elemsize + sizeof(u16) + key_length); - bh__arrhead(arrptr)->length = byte_len + elemsize + sizeof(u16) + key_length; - table->arrs[index] = arrptr; - - if (arr_was_new) { - *(u64 *) arrptr = 1; - } else { - (*(u64 *) arrptr)++; - } - - arrptr = bh_pointer_add(arrptr, byte_len + elemsize); - *(u16 *) arrptr = key_length; - arrptr = bh_pointer_add(arrptr, sizeof(u16)); - strncpy(arrptr, key, key_length); + arrptr = table->arrs[index]; + i32 byte_len = bh_arr_length(arrptr); + if (byte_len == 0) byte_len = sizeof(u64); + key_length = strlen(key) + 1; + + // NOTE: Align to 16 bytes + if ((key_length + 2) % 16 != 0) { + key_length = ((((key_length + 2) >> 4) + 1) << 4) - 2; + } + + bh__arr_grow(table->allocator, &arrptr, 1, byte_len + elemsize + sizeof(u16) + key_length); + bh__arrhead(arrptr)->length = byte_len + elemsize + sizeof(u16) + key_length; + table->arrs[index] = arrptr; + + if (arr_was_new) { + *(u64 *) arrptr = 1; + } else { + (*(u64 *) arrptr)++; + } + + arrptr = bh_pointer_add(arrptr, byte_len + elemsize); + *(u16 *) arrptr = key_length; + arrptr = bh_pointer_add(arrptr, sizeof(u16)); + strncpy(arrptr, key, key_length); found_matching: - return bh_pointer_add(arrptr, -(sizeof(u16) + elemsize)); + return bh_pointer_add(arrptr, -(sizeof(u16) + elemsize)); } b32 bh__table_has(bh__table *table, i32 elemsize, char *key) { - elemsize += (elemsize & 1); + elemsize += (elemsize & 1); - u64 index = bh__table_hash_function(key, 0, table->table_size); + u64 index = bh__table_hash_function(key, 0, table->table_size); - ptr arrptr = table->arrs[index]; - if (arrptr == NULL) return 0; + ptr arrptr = table->arrs[index]; + if (arrptr == NULL) return 0; - u64 len = *(u64 *) arrptr; - arrptr = bh_pointer_add(arrptr, sizeof(u64)); + u64 len = *(u64 *) arrptr; + arrptr = bh_pointer_add(arrptr, sizeof(u64)); - u16 key_length = 0; - while (len--) { - arrptr = bh_pointer_add(arrptr, elemsize); - key_length = *(u16 *) arrptr; - arrptr = bh_pointer_add(arrptr, sizeof(u16)); - if (strncmp(key, (char *) arrptr, key_length) == 0) return 1; - arrptr = bh_pointer_add(arrptr, key_length); - } + u16 key_length = 0; + while (len--) { + arrptr = bh_pointer_add(arrptr, elemsize); + key_length = *(u16 *) arrptr; + arrptr = bh_pointer_add(arrptr, sizeof(u16)); + if (strncmp(key, (char *) arrptr, key_length) == 0) return 1; + arrptr = bh_pointer_add(arrptr, key_length); + } - return 0; + return 0; } ptr bh__table_get(bh__table *table, i32 elemsize, char *key) { - elemsize += (elemsize & 1); + elemsize += (elemsize & 1); - u64 index = bh__table_hash_function(key, 0, table->table_size); + u64 index = bh__table_hash_function(key, 0, table->table_size); - ptr arrptr = table->arrs[index]; - if (arrptr == NULL) return 0; + ptr arrptr = table->arrs[index]; + if (arrptr == NULL) return 0; - u64 len = *(u64 *) arrptr; - arrptr = bh_pointer_add(arrptr, sizeof(u64)); + u64 len = *(u64 *) arrptr; + arrptr = bh_pointer_add(arrptr, sizeof(u64)); - u16 key_length = 0; - while (len--) { - arrptr = bh_pointer_add(arrptr, elemsize); - key_length = *(u16 *) arrptr; - arrptr = bh_pointer_add(arrptr, sizeof(u16)); - if (strncmp(key, (char *) arrptr, key_length) == 0) { - return bh_pointer_add(arrptr, -(sizeof(u16) + elemsize)); - } - arrptr = bh_pointer_add(arrptr, key_length); - } + u16 key_length = 0; + while (len--) { + arrptr = bh_pointer_add(arrptr, elemsize); + key_length = *(u16 *) arrptr; + arrptr = bh_pointer_add(arrptr, sizeof(u16)); + if (strncmp(key, (char *) arrptr, key_length) == 0) { + return bh_pointer_add(arrptr, -(sizeof(u16) + elemsize)); + } + arrptr = bh_pointer_add(arrptr, key_length); + } - return NULL; + return NULL; } void bh__table_delete(bh__table *table, i32 elemsize, char *key) { - elemsize += (elemsize & 1); + elemsize += (elemsize & 1); - u64 index = bh__table_hash_function(key, 0, table->table_size); + u64 index = bh__table_hash_function(key, 0, table->table_size); - ptr arrptr = table->arrs[index], walker; - if (arrptr == NULL) return; // Didn't exist - walker = arrptr; + ptr arrptr = table->arrs[index], walker; + if (arrptr == NULL) return; // Didn't exist + walker = arrptr; - i32 byte_offset = 8; - i32 delete_len = 0; + i32 byte_offset = 8; + i32 delete_len = 0; - u64 len = *(u64 *) walker; - walker = bh_pointer_add(walker, sizeof(u64)); + u64 len = *(u64 *) walker; + walker = bh_pointer_add(walker, sizeof(u64)); - u16 key_length = 0; - while (len--) { - walker = bh_pointer_add(walker, elemsize); - key_length = *(u16 *) walker; - walker = bh_pointer_add(walker, sizeof(u16)); - if (strncmp(key, (char *) walker, key_length) == 0) { - delete_len = elemsize + sizeof(u16) + key_length; - goto found_matching; - } - walker = bh_pointer_add(walker, key_length); - byte_offset += elemsize + sizeof(u16) + key_length; - } + u16 key_length = 0; + while (len--) { + walker = bh_pointer_add(walker, elemsize); + key_length = *(u16 *) walker; + walker = bh_pointer_add(walker, sizeof(u16)); + if (strncmp(key, (char *) walker, key_length) == 0) { + delete_len = elemsize + sizeof(u16) + key_length; + goto found_matching; + } + walker = bh_pointer_add(walker, key_length); + byte_offset += elemsize + sizeof(u16) + key_length; + } - // NOTE: Already didn't exist - return; + // NOTE: Already didn't exist + return; found_matching: - bh__arr_deleten((void **) &arrptr, 1, byte_offset, delete_len); - table->arrs[index] = arrptr; - (*(u64 *) arrptr)--; + bh__arr_deleten((void **) &arrptr, 1, byte_offset, delete_len); + table->arrs[index] = arrptr; + (*(u64 *) arrptr)--; } void bh__table_clear(bh__table *table) { - for (i32 i = 0; i < table->table_size; i++) { - if (table->arrs[i] != NULL) { - // NOTE: Set length property to 0 - *((u64 *) table->arrs[i]) = 0; - bh_arr_set_length(table->arrs[i], 0); - } - } + for (i32 i = 0; i < table->table_size; i++) { + if (table->arrs[i] != NULL) { + // NOTE: Set length property to 0 + *((u64 *) table->arrs[i]) = 0; + bh_arr_set_length(table->arrs[i], 0); + } + } } bh_table_iterator bh__table_iter_setup(bh__table *table, i32 elemsize) { - elemsize += (elemsize & 1); + elemsize += (elemsize & 1); - bh_table_iterator it = { - .tab = table->arrs, - .endtab = table->arrs + table->table_size, - .elemsize = elemsize, - .entry = NULL - }; - return it; + bh_table_iterator it = { + .tab = table->arrs, + .endtab = table->arrs + table->table_size, + .elemsize = elemsize, + .entry = NULL + }; + return it; } b32 bh_table_iter_next(bh_table_iterator* it) { - if (it->tab == NULL) return 0; + if (it->tab == NULL) return 0; - if (it->entry != NULL) { - it->arrlen--; - if (it->arrlen <= 0) { - it->tab++; - goto step_to_next; - } + if (it->entry != NULL) { + it->arrlen--; + if (it->arrlen <= 0) { + it->tab++; + goto step_to_next; + } - it->entry = bh_pointer_add(it->entry, it->elemsize); - it->entry = bh_pointer_add(it->entry, sizeof(u16) + (*(u16 *) it->entry)); - return 1; - } + it->entry = bh_pointer_add(it->entry, it->elemsize); + it->entry = bh_pointer_add(it->entry, sizeof(u16) + (*(u16 *) it->entry)); + return 1; + } step_to_next: - // Step forward to find next valid - while (*it->tab == NULL && it->tab != it->endtab) { - it->tab++; - } - - if (it->tab == it->endtab) return 0; - - it->entry = *it->tab; - it->arrlen = *(u64 *) it->entry; - it->entry = bh_pointer_add(it->entry, sizeof(u64)); - if (it->arrlen <= 0) { - it->tab++; - goto step_to_next; - } - return 1; + // Step forward to find next valid + while (*it->tab == NULL && it->tab != it->endtab) { + it->tab++; + } + + if (it->tab == it->endtab) return 0; + + it->entry = *it->tab; + it->arrlen = *(u64 *) it->entry; + it->entry = bh_pointer_add(it->entry, sizeof(u64)); + if (it->arrlen <= 0) { + it->tab++; + goto step_to_next; + } + return 1; } #endif // ifndef BH_NO_HASHTABLE diff --git a/include/onyxlex.h b/include/onyxlex.h index 6a2c7550..559a2030 100644 --- a/include/onyxlex.h +++ b/include/onyxlex.h @@ -4,86 +4,86 @@ #include "bh.h" typedef enum OnyxTokenType { - TOKEN_TYPE_UNKNOWN, - TOKEN_TYPE_END_STREAM, - - TOKEN_TYPE_COMMENT, - - TOKEN_TYPE_KEYWORD_STRUCT, - TOKEN_TYPE_KEYWORD_USE, - TOKEN_TYPE_KEYWORD_EXPORT, - TOKEN_TYPE_KEYWORD_IF, - TOKEN_TYPE_KEYWORD_ELSE, - TOKEN_TYPE_KEYWORD_ELSEIF, - TOKEN_TYPE_KEYWORD_RETURN, - TOKEN_TYPE_KEYWORD_FOREIGN, - TOKEN_TYPE_KEYWORD_PROC, - TOKEN_TYPE_KEYWORD_CAST, + TOKEN_TYPE_UNKNOWN, + TOKEN_TYPE_END_STREAM, + + TOKEN_TYPE_COMMENT, + + TOKEN_TYPE_KEYWORD_STRUCT, + TOKEN_TYPE_KEYWORD_USE, + TOKEN_TYPE_KEYWORD_EXPORT, + TOKEN_TYPE_KEYWORD_IF, + TOKEN_TYPE_KEYWORD_ELSE, + TOKEN_TYPE_KEYWORD_ELSEIF, + TOKEN_TYPE_KEYWORD_RETURN, + TOKEN_TYPE_KEYWORD_FOREIGN, + TOKEN_TYPE_KEYWORD_PROC, + TOKEN_TYPE_KEYWORD_CAST, TOKEN_TYPE_KEYWORD_WHILE, TOKEN_TYPE_KEYWORD_BREAK, TOKEN_TYPE_KEYWORD_CONTINUE, - TOKEN_TYPE_RIGHT_ARROW, - TOKEN_TYPE_LEFT_ARROW, - TOKEN_TYPE_OPEN_PAREN, - TOKEN_TYPE_CLOSE_PAREN, - TOKEN_TYPE_OPEN_BRACE, - TOKEN_TYPE_CLOSE_BRACE, - TOKEN_TYPE_OPEN_BRACKET, - TOKEN_TYPE_CLOSE_BRACKET, - - TOKEN_TYPE_SYM_PLUS, - TOKEN_TYPE_SYM_MINUS, - TOKEN_TYPE_SYM_STAR, - TOKEN_TYPE_SYM_PERCENT, - TOKEN_TYPE_SYM_DOT, - TOKEN_TYPE_SYM_FSLASH, - TOKEN_TYPE_SYM_BSLASH, - TOKEN_TYPE_SYM_COLON, - TOKEN_TYPE_SYM_SEMICOLON, - TOKEN_TYPE_SYM_COMMA, - TOKEN_TYPE_SYM_GREATER, - TOKEN_TYPE_SYM_GREATER_EQUAL, - TOKEN_TYPE_SYM_LESS, - TOKEN_TYPE_SYM_LESS_EQUAL, - TOKEN_TYPE_SYM_EQUAL_EQUAL, - TOKEN_TYPE_SYM_NOT_EQUAL, - TOKEN_TYPE_SYM_EQUALS, - TOKEN_TYPE_SYM_TILDE, - TOKEN_TYPE_SYM_BANG, - TOKEN_TYPE_SYM_CARET, - TOKEN_TYPE_SYM_AMPERSAND, - - TOKEN_TYPE_SYMBOL, - TOKEN_TYPE_LITERAL_STRING, - TOKEN_TYPE_LITERAL_NUMERIC, + TOKEN_TYPE_RIGHT_ARROW, + TOKEN_TYPE_LEFT_ARROW, + TOKEN_TYPE_OPEN_PAREN, + TOKEN_TYPE_CLOSE_PAREN, + TOKEN_TYPE_OPEN_BRACE, + TOKEN_TYPE_CLOSE_BRACE, + TOKEN_TYPE_OPEN_BRACKET, + TOKEN_TYPE_CLOSE_BRACKET, + + TOKEN_TYPE_SYM_PLUS, + TOKEN_TYPE_SYM_MINUS, + TOKEN_TYPE_SYM_STAR, + TOKEN_TYPE_SYM_PERCENT, + TOKEN_TYPE_SYM_DOT, + TOKEN_TYPE_SYM_FSLASH, + TOKEN_TYPE_SYM_BSLASH, + TOKEN_TYPE_SYM_COLON, + TOKEN_TYPE_SYM_SEMICOLON, + TOKEN_TYPE_SYM_COMMA, + TOKEN_TYPE_SYM_GREATER, + TOKEN_TYPE_SYM_GREATER_EQUAL, + TOKEN_TYPE_SYM_LESS, + TOKEN_TYPE_SYM_LESS_EQUAL, + TOKEN_TYPE_SYM_EQUAL_EQUAL, + TOKEN_TYPE_SYM_NOT_EQUAL, + TOKEN_TYPE_SYM_EQUALS, + TOKEN_TYPE_SYM_TILDE, + TOKEN_TYPE_SYM_BANG, + TOKEN_TYPE_SYM_CARET, + TOKEN_TYPE_SYM_AMPERSAND, + + TOKEN_TYPE_SYMBOL, + TOKEN_TYPE_LITERAL_STRING, + TOKEN_TYPE_LITERAL_NUMERIC, TOKEN_TYPE_LITERAL_BOOL_TRUE, TOKEN_TYPE_LITERAL_BOOL_FALSE, - TOKEN_TYPE_COUNT + TOKEN_TYPE_COUNT } OnyxTokenType; typedef struct OnyxFilePos { - const char* filename; - u64 line, column; + const char* filename; + u64 line, column; } OnyxFilePos; typedef struct OnyxToken { - OnyxTokenType type; - i32 length; - char* token; - OnyxFilePos pos; + OnyxTokenType type; + i32 length; + char* token; + OnyxFilePos pos; } OnyxToken; typedef struct OnyxTokenizer { - char *start, *curr, *end; + char *start, *curr, *end; - const char* filename; + const char* filename; - char* line_start; - u64 line_number; + char* line_start; + u64 line_number; - bh_arr(OnyxToken) tokens; + bh_arr(OnyxToken) tokens; } OnyxTokenizer; const char* onyx_get_token_type_name(OnyxTokenType tkn_type); diff --git a/include/onyxmsgs.h b/include/onyxmsgs.h index c2919ea9..ff268f45 100644 --- a/include/onyxmsgs.h +++ b/include/onyxmsgs.h @@ -10,16 +10,16 @@ typedef enum OnyxMessageType { ONYX_MESSAGE_TYPE_LITERAL, - ONYX_MESSAGE_TYPE_EXPECTED_TOKEN, - ONYX_MESSAGE_TYPE_UNEXPECTED_TOKEN, - ONYX_MESSAGE_TYPE_UNKNOWN_TYPE, - ONYX_MESSAGE_TYPE_NOT_LVAL, - ONYX_MESSAGE_TYPE_ASSIGN_CONST, - ONYX_MESSAGE_TYPE_UNKNOWN_SYMBOL, - 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_EXPECTED_TOKEN, + ONYX_MESSAGE_TYPE_UNEXPECTED_TOKEN, + ONYX_MESSAGE_TYPE_UNKNOWN_TYPE, + ONYX_MESSAGE_TYPE_NOT_LVAL, + ONYX_MESSAGE_TYPE_ASSIGN_CONST, + ONYX_MESSAGE_TYPE_UNKNOWN_SYMBOL, + 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_CALL_NON_FUNCTION, ONYX_MESSAGE_TYPE_FUNCTION_RETURN_MISMATCH, @@ -28,20 +28,20 @@ typedef enum OnyxMessageType { ONYX_MESSAGE_TYPE_UNRESOLVED_TYPE, ONYX_MESSAGE_TYPE_UNRESOLVED_SYMBOL, - ONYX_MESSAGE_TYPE_COUNT, + ONYX_MESSAGE_TYPE_COUNT, } OnyxMessageType; typedef struct OnyxMessage { - OnyxMessageType type; - OnyxFilePos pos; - struct OnyxMessage* next; - char text[ONYX_MSG_BUFFER_SIZE]; + OnyxMessageType type; + OnyxFilePos pos; + struct OnyxMessage* next; + char text[ONYX_MSG_BUFFER_SIZE]; } OnyxMessage; typedef struct OnyxMessages { - bh_allocator allocator; + bh_allocator allocator; - OnyxMessage* first; + OnyxMessage* first; } OnyxMessages; void onyx_message_add(OnyxMessages* msgs, OnyxMessageType type, OnyxFilePos pos, ...); diff --git a/include/onyxparser.h b/include/onyxparser.h index 1e237912..97bae85f 100644 --- a/include/onyxparser.h +++ b/include/onyxparser.h @@ -1,4 +1,5 @@ #ifndef ONYXPARSER_H + negate_node->operation = ONYX_UNARY_OP_NEGATE; #define ONYXPARSER_H #include "bh.h" @@ -22,73 +23,73 @@ typedef struct OnyxAstNodeCall OnyxAstNodeCall; typedef struct OnyxAstNodeFile OnyxAstNodeFile; typedef struct OnyxParser { - OnyxTokenizer *tokenizer; // NOTE: not used since all tokens are lexed before parsing starts - OnyxToken *prev_token; - OnyxToken *curr_token; + OnyxTokenizer *tokenizer; // NOTE: not used since all tokens are lexed before parsing starts + OnyxToken *prev_token; + OnyxToken *curr_token; // NOTE: Identifiers currently is only used to resolve type names // at parse time, since these are the only symbols we know. bh_table(OnyxAstNode *) identifiers; - OnyxMessages *msgs; + OnyxMessages *msgs; - bh_allocator allocator; + bh_allocator allocator; } OnyxParser; typedef enum OnyxAstNodeKind { - ONYX_AST_NODE_KIND_ERROR, - ONYX_AST_NODE_KIND_PROGRAM, + ONYX_AST_NODE_KIND_ERROR, + ONYX_AST_NODE_KIND_PROGRAM, - ONYX_AST_NODE_KIND_FUNCDEF, + ONYX_AST_NODE_KIND_FUNCDEF, ONYX_AST_NODE_KIND_FOREIGN, - ONYX_AST_NODE_KIND_BLOCK, - ONYX_AST_NODE_KIND_SCOPE, - ONYX_AST_NODE_KIND_LOCAL, + ONYX_AST_NODE_KIND_BLOCK, + ONYX_AST_NODE_KIND_SCOPE, + ONYX_AST_NODE_KIND_LOCAL, ONYX_AST_NODE_KIND_SYMBOL, ONYX_AST_NODE_KIND_UNARY_OP, ONYX_AST_NODE_KIND_BIN_OP, - ONYX_AST_NODE_KIND_TYPE, - ONYX_AST_NODE_KIND_LITERAL, - ONYX_AST_NODE_KIND_PARAM, + ONYX_AST_NODE_KIND_TYPE, + ONYX_AST_NODE_KIND_LITERAL, + ONYX_AST_NODE_KIND_PARAM, ONYX_AST_NODE_KIND_ARGUMENT, - ONYX_AST_NODE_KIND_CALL, - ONYX_AST_NODE_KIND_ASSIGNMENT, - ONYX_AST_NODE_KIND_RETURN, + ONYX_AST_NODE_KIND_CALL, + ONYX_AST_NODE_KIND_ASSIGNMENT, + ONYX_AST_NODE_KIND_RETURN, - ONYX_AST_NODE_KIND_IF, - ONYX_AST_NODE_KIND_WHILE, + ONYX_AST_NODE_KIND_IF, + ONYX_AST_NODE_KIND_WHILE, ONYX_AST_NODE_KIND_BREAK, ONYX_AST_NODE_KIND_CONTINUE, - ONYX_AST_NODE_KIND_COUNT + ONYX_AST_NODE_KIND_COUNT } OnyxAstNodeKind; typedef enum OnyxTypeInfoKind { - ONYX_TYPE_INFO_KIND_UNKNOWN, - ONYX_TYPE_INFO_KIND_VOID, - ONYX_TYPE_INFO_KIND_BOOL, + ONYX_TYPE_INFO_KIND_UNKNOWN, + ONYX_TYPE_INFO_KIND_VOID, + ONYX_TYPE_INFO_KIND_BOOL, - ONYX_TYPE_INFO_KIND_UINT32, - ONYX_TYPE_INFO_KIND_UINT64, + ONYX_TYPE_INFO_KIND_UINT32, + ONYX_TYPE_INFO_KIND_UINT64, - ONYX_TYPE_INFO_KIND_INT32, - ONYX_TYPE_INFO_KIND_INT64, + ONYX_TYPE_INFO_KIND_INT32, + ONYX_TYPE_INFO_KIND_INT64, - ONYX_TYPE_INFO_KIND_FLOAT32, - ONYX_TYPE_INFO_KIND_FLOAT64, - ONYX_TYPE_INFO_KIND_SOFT_FLOAT, // 64-bits of data but could be treated as 32-bit + ONYX_TYPE_INFO_KIND_FLOAT32, + ONYX_TYPE_INFO_KIND_FLOAT64, + ONYX_TYPE_INFO_KIND_SOFT_FLOAT, // 64-bits of data but could be treated as 32-bit } OnyxTypeInfoKind; typedef struct OnyxTypeInfo { - OnyxTypeInfoKind kind; - u32 size; // in bytes - const char* name; - u32 is_int : 1; - u32 is_unsigned : 1; - u32 is_float : 1; - u32 is_bool : 1; - u32 is_known : 1; + OnyxTypeInfoKind kind; + u32 size; // in bytes + const char* name; + u32 is_int : 1; + u32 is_unsigned : 1; + u32 is_float : 1; + u32 is_bool : 1; + u32 is_known : 1; } OnyxTypeInfo; extern OnyxTypeInfo builtin_types[]; @@ -96,11 +97,11 @@ extern OnyxTypeInfo builtin_types[]; // NOTE: Some of these flags will overlap since there are // only 32-bits of flags to play with typedef enum OnyxAstFlags { - // Top-level flags - ONYX_AST_FLAG_EXPORTED = BH_BIT(0), - ONYX_AST_FLAG_LVAL = BH_BIT(1), - ONYX_AST_FLAG_CONST = BH_BIT(2), - ONYX_AST_FLAG_COMPTIME = BH_BIT(3), + // Top-level flags + ONYX_AST_FLAG_EXPORTED = BH_BIT(0), + ONYX_AST_FLAG_LVAL = BH_BIT(1), + ONYX_AST_FLAG_CONST = BH_BIT(2), + ONYX_AST_FLAG_COMPTIME = BH_BIT(3), } OnyxAstFlags; typedef enum OnyxUnaryOp { @@ -116,12 +117,12 @@ typedef enum OnyxBinaryOp { 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_EQUAL, + ONYX_BINARY_OP_NOT_EQUAL, + ONYX_BINARY_OP_LESS, + ONYX_BINARY_OP_LESS_EQUAL, + ONYX_BINARY_OP_GREATER, + ONYX_BINARY_OP_GREATER_EQUAL, } OnyxBinaryOp; struct OnyxAstNodeBinOp { @@ -146,53 +147,53 @@ struct OnyxAstNodeUnaryOp { }; struct OnyxAstNodeNumLit { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; - OnyxTypeInfo *type; - OnyxAstNode *next; + OnyxAstNodeKind kind; + u32 flags; + OnyxToken *token; + OnyxTypeInfo *type; + OnyxAstNode *next; union { i32 i; i64 l; f32 f; f64 d; } value; }; struct OnyxAstNodeLocal { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; - OnyxTypeInfo *type; + OnyxAstNodeKind kind; + u32 flags; + OnyxToken *token; + OnyxTypeInfo *type; u64 data; // NOTE: Unused - OnyxAstNode *next; - OnyxAstNodeLocal *prev_local; + OnyxAstNode *next; + OnyxAstNodeLocal *prev_local; }; struct OnyxAstNodeParam { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; // NOTE: Symbol name i.e. 'a', 'b' - OnyxTypeInfo *type; + OnyxAstNodeKind kind; + u32 flags; + OnyxToken *token; // NOTE: Symbol name i.e. 'a', 'b' + OnyxTypeInfo *type; u64 data; // NOTE: UNUSED - OnyxAstNodeParam *next; - OnyxAstNodeLocal *prev_local; + OnyxAstNodeParam *next; + OnyxAstNodeLocal *prev_local; }; struct OnyxAstNodeScope { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; // NOTE: UNUSED - OnyxTypeInfo *type; // NOTE: UNUSED + OnyxAstNodeKind kind; + u32 flags; + OnyxToken *token; // NOTE: UNUSED + OnyxTypeInfo *type; // NOTE: UNUSED u64 data; // NOTE: UNUSED - OnyxAstNodeScope *prev_scope; - OnyxAstNodeLocal *last_local; + OnyxAstNodeScope *prev_scope; + OnyxAstNodeLocal *last_local; }; struct OnyxAstNodeBlock { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; - OnyxTypeInfo *return_type; + OnyxAstNodeKind kind; + u32 flags; + OnyxToken *token; + OnyxTypeInfo *return_type; u64 data; // NOTE: UNUSED - OnyxAstNode *next; - OnyxAstNode *body; - OnyxAstNodeScope *scope; + OnyxAstNode *next; + OnyxAstNode *body; + OnyxAstNodeScope *scope; }; struct OnyxAstNodeIf { @@ -218,38 +219,38 @@ struct OnyxAstNodeWhile { }; struct OnyxAstNodeFuncDef { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; // This will point to the symbol token to identify it - OnyxTypeInfo *return_type; + OnyxAstNodeKind kind; + u32 flags; + OnyxToken *token; // This will point to the symbol token to identify it + OnyxTypeInfo *return_type; u64 data; - OnyxAstNode *next; - OnyxAstNodeBlock *body; - OnyxAstNodeParam *params; + OnyxAstNode *next; + OnyxAstNodeBlock *body; + OnyxAstNodeParam *params; }; struct OnyxAstNodeForeign { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *mod_token; - OnyxTypeInfo *type; + OnyxAstNodeKind kind; + u32 flags; + OnyxToken *mod_token; + OnyxTypeInfo *type; u64 data; - OnyxAstNode *next; + OnyxAstNode *next; OnyxToken *name_token; - OnyxAstNode *import; + OnyxAstNode *import; }; struct OnyxAstNodeCall { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; - OnyxTypeInfo *type; // NOTE: The type that the function returns + OnyxAstNodeKind kind; + u32 flags; + OnyxToken *token; + OnyxTypeInfo *type; // NOTE: The type that the function returns u64 data; - OnyxAstNode *next; - OnyxAstNode *callee; // NOTE: Function definition node - OnyxAstNode *arguments; // NOTE: Expressions that form the actual param list - // They will be chained down using the "next" property - // unless this becomes used by something else + OnyxAstNode *next; + OnyxAstNode *callee; // NOTE: Function definition node + OnyxAstNode *arguments; // NOTE: Expressions that form the actual param list + // They will be chained down using the "next" property + // unless this becomes used by something else }; struct OnyxAstNodeFile { @@ -264,24 +265,24 @@ struct OnyxAstNodeFile { union OnyxAstNode { - // Generic node structure for capturing all binary ops and statements - struct { - OnyxAstNodeKind kind; - u32 flags; - OnyxToken *token; - OnyxTypeInfo *type; + // Generic node structure for capturing all binary ops and statements + struct { + OnyxAstNodeKind kind; + u32 flags; + OnyxToken *token; + OnyxTypeInfo *type; u64 data; - OnyxAstNode *next; - OnyxAstNode *left; - OnyxAstNode *right; - }; - - OnyxAstNodeBlock as_block; - OnyxAstNodeFuncDef as_funcdef; - OnyxAstNodeParam as_param; - OnyxAstNodeLocal as_local; - OnyxAstNodeScope as_scope; - OnyxAstNodeCall as_call; + OnyxAstNode *next; + OnyxAstNode *left; + OnyxAstNode *right; + }; + + OnyxAstNodeBlock as_block; + OnyxAstNodeFuncDef as_funcdef; + OnyxAstNodeParam as_param; + OnyxAstNodeLocal as_local; + OnyxAstNodeScope as_scope; + OnyxAstNodeCall as_call; OnyxAstNodeNumLit as_numlit; OnyxAstNodeBinOp as_binop; OnyxAstNodeUnaryOp as_unaryop; diff --git a/include/onyxsempass.h b/include/onyxsempass.h index 12d87920..2174c3f3 100644 --- a/include/onyxsempass.h +++ b/include/onyxsempass.h @@ -15,8 +15,8 @@ typedef struct SemPassSymbol { typedef struct OnyxSemPassState { // NOTE: Adding node_allocator in case we need // to make any more node in the tree - bh_allocator allocator, node_allocator; - OnyxMessages *msgs; + bh_allocator allocator, node_allocator; + OnyxMessages *msgs; // NOTE: Used in symbol resolution phase OnyxAstNodeScope* curr_scope; diff --git a/include/onyxwasm.h b/include/onyxwasm.h index adebd8bc..f73d1b1b 100644 --- a/include/onyxwasm.h +++ b/include/onyxwasm.h @@ -13,252 +13,252 @@ extern const WasmType WASM_TYPE_FLOAT32; extern const WasmType WASM_TYPE_FLOAT64; typedef struct WasmFuncType { - // NOTE: For now, WASM only allows for 1 return value. - // This may be lifted in the future. - i32 param_count; - WasmType return_type; - WasmType param_types[]; + // NOTE: For now, WASM only allows for 1 return value. + // This may be lifted in the future. + i32 param_count; + WasmType return_type; + WasmType param_types[]; } 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, + 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; + struct { + u32 i1, i2; + }; + i64 l; + float f; + double d; + ptr p; } WasmInstructionData; typedef struct WasmInstruction { - WasmInstructionType type; - WasmInstructionData data; + WasmInstructionType type; + WasmInstructionData data; } WasmInstruction; typedef struct WasmFuncLocals { - u8 i32_count; - u8 i64_count; - u8 f32_count; - u8 f64_count; + u8 i32_count; + u8 i64_count; + u8 f32_count; + u8 f64_count; } WasmFuncLocals; typedef struct WasmFunc { - i32 type_idx; - WasmFuncLocals locals; - bh_arr(WasmInstruction) code; + i32 type_idx; + WasmFuncLocals locals; + bh_arr(WasmInstruction) code; } WasmFunc; typedef enum WasmForeignKind { - WASM_FOREIGN_FUNCTION = 0x00, - WASM_FOREIGN_TABLE = 0x01, - WASM_FOREIGN_MEMORY = 0x02, - WASM_FOREIGN_GLOBAL = 0x03, + WASM_FOREIGN_FUNCTION = 0x00, + WASM_FOREIGN_TABLE = 0x01, + WASM_FOREIGN_MEMORY = 0x02, + WASM_FOREIGN_GLOBAL = 0x03, } WasmForeignKind; typedef struct WasmExport { - WasmForeignKind kind; - i32 idx; + WasmForeignKind kind; + i32 idx; } WasmExport; typedef struct WasmImport { @@ -268,28 +268,28 @@ typedef struct WasmImport { } WasmImport; typedef struct OnyxWasmModule { - bh_allocator allocator; + bh_allocator allocator; - // NOTE: Mapping from local ast node ptrs to indicies - bh_imap local_map; + // NOTE: Mapping from local ast node ptrs to indicies + bh_imap local_map; - // NOTE: Used internally as a map from strings that represent function types, - // 0x7f 0x7f : 0x7f ( (i32, i32) -> i32 ) - // to the function type index if it has been created. - bh_table(i32) type_map; - bh_arr(WasmFuncType*) functypes; // NOTE: This have to be pointers because the type is variadic in size + // NOTE: Used internally as a map from strings that represent function types, + // 0x7f 0x7f : 0x7f ( (i32, i32) -> i32 ) + // to the function type index if it has been created. + bh_table(i32) type_map; + bh_arr(WasmFuncType*) functypes; // NOTE: This have to be pointers because the type is variadic in size - bh_arr(WasmFunc) funcs; + bh_arr(WasmFunc) funcs; bh_imap func_map; // NOTE: Maps from ast node pointers to the function index - bh_table(WasmExport) exports; + bh_table(WasmExport) exports; bh_arr(WasmImport) imports; - i32 next_type_idx; - i32 next_func_idx; + i32 next_type_idx; + i32 next_func_idx; i32 next_import_func_idx; - i32 export_count; + i32 export_count; } OnyxWasmModule; OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc); diff --git a/misc/onyx.vim b/misc/onyx.vim index 4e85c159..725b61fa 100644 --- a/misc/onyx.vim +++ b/misc/onyx.vim @@ -4,7 +4,7 @@ " Last Change: 2020 June 20 if exists("b:current_syntax") - finish + finish endif let s:cpo_save = &cpo @@ -23,15 +23,15 @@ syn keyword onyxType f64 syn keyword onyxConstant true false -syn keyword onyxCommentStart contained TODO NOTE BUG HACK +syn keyword onyxCommentStart contained TODO NOTE BUG HACK syn region onyxComment start="//" end="$" keepend contains=onyxCommentStart -hi def link onyxKeyword Statement -hi def link onyxType Type -hi def link onyxComment Comment -hi def link onyxCommentStart Todo -hi def link onyxConstant Constant +hi def link onyxKeyword Statement +hi def link onyxType Type +hi def link onyxComment Comment +hi def link onyxCommentStart Todo +hi def link onyxConstant Constant let b:current_syntax = "onyx" let &cpo = s:cpo_save diff --git a/progs/minimal.onyx b/progs/minimal.onyx index 76197666..7fd39bb6 100644 --- a/progs/minimal.onyx +++ b/progs/minimal.onyx @@ -32,11 +32,11 @@ factorial :: proc (n i32) -> i32 { } foo :: proc -> i32 { - return 10; + return 10; } add :: proc (a i32, b i32) -> i32 { - return a + b; + return a + b; } // NOTE: There is a weird bug here if the else is used instead @@ -55,21 +55,21 @@ fib :: proc (n i32) -> i32 { } diff_square :: proc (a i32, b i32) -> i32 { - // Typechecked - c := a - b; // Mutable - d :: a + b; // Constant + // Typechecked + c := a - b; // Mutable + d :: a + b; // Constant { c := a * 2; d := (b + a) * 2; } - return c * d; + return c * d; } do_stuff :: proc -> i32 { - res := diff_square(4 + 5, 2 + 3); - res = res + foo(); + res := diff_square(4 + 5, 2 + 3); + res = res + foo(); return res * -1; } diff --git a/progs/mvp.onyx b/progs/mvp.onyx index dbef39d4..f75b65dd 100644 --- a/progs/mvp.onyx +++ b/progs/mvp.onyx @@ -1,21 +1,21 @@ foreign console { - log :: proc (data ptr, length i32) -> void ---; + log :: proc (data ptr, length i32) -> void ---; } export add :: proc (a i32, b i32) -> i32 { - return a + b; + return a + b; } export max :: proc (a i32, b i32) -> i32 { - // Curly braces are always required - if a > b { - return a; - } else { - return b; - } + // Curly braces are always required + if a > b { + return a; + } else { + return b; + } } export main :: proc () { - console.log(add(2, 3)); - console.log(max(5, 10)); + console.log(add(2, 3)); + console.log(max(5, 10)); } diff --git a/progs/test.onyx b/progs/test.onyx index c2630139..db4a5d46 100644 --- a/progs/test.onyx +++ b/progs/test.onyx @@ -32,11 +32,11 @@ export main :: proc { x : i32; y := 0; - while y < 10 { + while y < 5 { x = 0; - while x < 10 { - print_i32(x + y * 10); + while x < 5 { + print_i32((x + y * 5) % 10); x = x + 1; } diff --git a/src/onyx.c b/src/onyx.c index 3d8912ef..4dd19f35 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -87,28 +87,28 @@ void compile_opts_free(OnyxCompileOptions* opts) { OnyxAstNodeFile* parse_source_file(bh_file_contents* file_contents, CompilerState* compiler_state) { // NOTE: Maybe don't want to recreate the tokenizer and parser for every file - OnyxTokenizer tokenizer = onyx_tokenizer_create(compiler_state->token_alloc, file_contents); + OnyxTokenizer tokenizer = onyx_tokenizer_create(compiler_state->token_alloc, file_contents); bh_printf("Lexing %s\n", file_contents->filename); - onyx_lex_tokens(&tokenizer); + onyx_lex_tokens(&tokenizer); bh_printf("Parsing %s\n", file_contents->filename); - OnyxParser parser = onyx_parser_create(compiler_state->ast_alloc, &tokenizer, &compiler_state->msgs); - return onyx_parse(&parser); + OnyxParser parser = onyx_parser_create(compiler_state->ast_alloc, &tokenizer, &compiler_state->msgs); + return onyx_parse(&parser); } i32 onyx_compile(OnyxCompileOptions* opts, CompilerState* compiler_state) { - bh_arena_init(&compiler_state->msg_arena, opts->allocator, 4096); - compiler_state->msg_alloc = bh_arena_allocator(&compiler_state->msg_arena); + bh_arena_init(&compiler_state->msg_arena, opts->allocator, 4096); + compiler_state->msg_alloc = bh_arena_allocator(&compiler_state->msg_arena); onyx_message_create(compiler_state->msg_alloc, &compiler_state->msgs); compiler_state->token_alloc = opts->allocator; - // NOTE: Create the arena where AST nodes will exist - // Prevents nodes from being scattered across memory due to fragmentation - bh_arena_init(&compiler_state->ast_arena, opts->allocator, 16 * 1024 * 1024); // 16MB - compiler_state->ast_alloc = bh_arena_allocator(&compiler_state->ast_arena); + // NOTE: Create the arena where AST nodes will exist + // Prevents nodes from being scattered across memory due to fragmentation + bh_arena_init(&compiler_state->ast_arena, opts->allocator, 16 * 1024 * 1024); // 16MB + compiler_state->ast_alloc = bh_arena_allocator(&compiler_state->ast_arena); bh_arena_init(&compiler_state->sp_arena, opts->allocator, 16 * 1024); compiler_state->sp_alloc = bh_arena_allocator(&compiler_state->sp_arena); @@ -190,7 +190,7 @@ void compiler_state_free(CompilerState* cs) { int main(int argc, char *argv[]) { - bh_allocator alloc = bh_heap_allocator(); + bh_allocator alloc = bh_heap_allocator(); bh_scratch_init(&global_scratch, alloc, 16 * 1024); // NOTE: 16 KB global_scratch_allocator = bh_scratch_allocator(&global_scratch); @@ -238,51 +238,51 @@ int main(int argc, char *argv[]) { compiler_state_free(&compile_state); - return compiler_progress != ONYX_COMPILER_PROGRESS_SUCCESS; + return compiler_progress != ONYX_COMPILER_PROGRESS_SUCCESS; } // NOTE: Old bits of code that may be useful again at some point. #if 0 - bh_printf("There are %d tokens (Allocated space for %d tokens)\n", bh_arr_length(token_arr), bh_arr_capacity(token_arr)); + bh_printf("There are %d tokens (Allocated space for %d tokens)\n", bh_arr_length(token_arr), bh_arr_capacity(token_arr)); - 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); - } + 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); + } #endif #if 0 - // NOTE: Ensure type table made correctly - - bh_printf("Type map:\n"); - 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; - while (!bh_arr_end(wasm_mod.functypes, func_type)) { - for (int p = 0; p < (*func_type)->param_count; p++) { - bh_printf("%c ", (*func_type)->param_types[p]); - } - bh_printf("-> "); - bh_printf("%c\n", (*func_type)->return_type); - - func_type++; - } + // NOTE: Ensure type table made correctly + + bh_printf("Type map:\n"); + 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; + while (!bh_arr_end(wasm_mod.functypes, func_type)) { + for (int p = 0; p < (*func_type)->param_count; p++) { + bh_printf("%c ", (*func_type)->param_types[p]); + } + bh_printf("-> "); + bh_printf("%c\n", (*func_type)->return_type); + + func_type++; + } #endif #if 0 - // NOTE: Ensure the export table was built correctly + // NOTE: Ensure the export table was built correctly - bh_printf("Function types:\n"); - bh_arr_each(WasmFunc, func_it, wasm_mod.funcs) { - bh_printf("%d\n", func_it->type_idx); - } + bh_printf("Function types:\n"); + bh_arr_each(WasmFunc, func_it, wasm_mod.funcs) { + bh_printf("%d\n", func_it->type_idx); + } - bh_printf("Exports:\n"); - bh_hash_each_start(WasmExport, wasm_mod.exports); - bh_printf("%s: %d %d\n", key, value.kind, value.idx); - bh_hash_each_end; + bh_printf("Exports:\n"); + 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/onyxlex.c b/src/onyxlex.c index 925d3b03..95c543a4 100644 --- a/src/onyxlex.c +++ b/src/onyxlex.c @@ -2,278 +2,278 @@ #include "onyxlex.h" static const char* onyx_token_type_names[] = { - "TOKEN_TYPE_UNKNOWN", - "TOKEN_TYPE_END_STREAM", - - "TOKEN_TYPE_COMMENT", - - "struct", //"TOKEN_TYPE_KEYWORD_STRUCT", - "use", //"TOKEN_TYPE_KEYWORD_USE", - "export", //"TOKEN_TYPE_KEYWORD_EXPORT", - "if", //"TOKEN_TYPE_KEYWORD_IF", - "else", //"TOKEN_TYPE_KEYWORD_ELSE", - "elseif", //"TOKEN_TYPE_KEYWORD_ELSEIF", - "return", //"TOKEN_TYPE_KEYWORD_RETURN", - "foreign", //"TOKEN_TYPE_KEYWORD_FOREIGN", - "proc", //"TOKEN_TYPE_KEYWORD_PROC", - "as", //"TOKEN_TYPE_KEYWORD_CAST", + "TOKEN_TYPE_UNKNOWN", + "TOKEN_TYPE_END_STREAM", + + "TOKEN_TYPE_COMMENT", + + "struct", //"TOKEN_TYPE_KEYWORD_STRUCT", + "use", //"TOKEN_TYPE_KEYWORD_USE", + "export", //"TOKEN_TYPE_KEYWORD_EXPORT", + "if", //"TOKEN_TYPE_KEYWORD_IF", + "else", //"TOKEN_TYPE_KEYWORD_ELSE", + "elseif", //"TOKEN_TYPE_KEYWORD_ELSEIF", + "return", //"TOKEN_TYPE_KEYWORD_RETURN", + "foreign", //"TOKEN_TYPE_KEYWORD_FOREIGN", + "proc", //"TOKEN_TYPE_KEYWORD_PROC", + "as", //"TOKEN_TYPE_KEYWORD_CAST", "while", //"TOKEN_TYPE_KEYWORD_WHILE", "break", //"TOKEN_TYPE_KEYWORD_BREAK", "continue", //"TOKEN_TYPE_KEYWORD_CONTINUE, - "->", //"TOKEN_TYPE_RIGHT_ARROW", - "<-", //"TOKEN_TYPE_LEFT_ARROW", - "(", //"TOKEN_TYPE_OPEN_PAREN", - ")", //"TOKEN_TYPE_CLOSE_PAREN", - "{", //"TOKEN_TYPE_OPEN_BRACE", - "}", //"TOKEN_TYPE_CLOSE_BRACE", - "[", //"TOKEN_TYPE_OPEN_BRACKET", - "]", //"TOKEN_TYPE_CLOSE_BRACKET", - - "+", // "TOKEN_TYPE_SYM_PLUS", - "-", // "TOKEN_TYPE_SYM_MINUS", - "*", // "TOKEN_TYPE_SYM_STAR", - "%", // "TOKEN_TYPE_SYM_PERCENT", - ".", // "TOKEN_TYPE_SYM_DOT", - "/", // "TOKEN_TYPE_SYM_FSLASH", - "\\", // "TOKEN_TYPE_SYM_BSLASH", - ":", // "TOKEN_TYPE_SYM_COLON", - ";", // "TOKEN_TYPE_SYM_SEMICOLON", - ",", // "TOKEN_TYPE_SYM_COMMA", - ">", // "TOKEN_TYPE_SYM_GREATER", - ">=", // "TOKEN_TYPE_SYM_GREATER_EQUAL", - "<", // "TOKEN_TYPE_SYM_LESS", - "<=", // "TOKEN_TYPE_SYM_LESS_EQUAL", - "==", // "TOKEN_TYPE_SYM_EQUALS_EQUALS", + "->", //"TOKEN_TYPE_RIGHT_ARROW", + "<-", //"TOKEN_TYPE_LEFT_ARROW", + "(", //"TOKEN_TYPE_OPEN_PAREN", + ")", //"TOKEN_TYPE_CLOSE_PAREN", + "{", //"TOKEN_TYPE_OPEN_BRACE", + "}", //"TOKEN_TYPE_CLOSE_BRACE", + "[", //"TOKEN_TYPE_OPEN_BRACKET", + "]", //"TOKEN_TYPE_CLOSE_BRACKET", + + "+", // "TOKEN_TYPE_SYM_PLUS", + "-", // "TOKEN_TYPE_SYM_MINUS", + "*", // "TOKEN_TYPE_SYM_STAR", + "%", // "TOKEN_TYPE_SYM_PERCENT", + ".", // "TOKEN_TYPE_SYM_DOT", + "/", // "TOKEN_TYPE_SYM_FSLASH", + "\\", // "TOKEN_TYPE_SYM_BSLASH", + ":", // "TOKEN_TYPE_SYM_COLON", + ";", // "TOKEN_TYPE_SYM_SEMICOLON", + ",", // "TOKEN_TYPE_SYM_COMMA", + ">", // "TOKEN_TYPE_SYM_GREATER", + ">=", // "TOKEN_TYPE_SYM_GREATER_EQUAL", + "<", // "TOKEN_TYPE_SYM_LESS", + "<=", // "TOKEN_TYPE_SYM_LESS_EQUAL", + "==", // "TOKEN_TYPE_SYM_EQUALS_EQUALS", "!=", // "TOKEN_TYPE_SYM_NOT_EQUAL", - "=", // "TOKEN_TYPE_SYM_EQUALS", - "~", // "TOKEN_TYPE_SYM_TILDE", - "!", // "TOKEN_TYPE_SYM_BANG", - "^", // "TOKEN_TYPE_SYM_CARET", - "&", // "TOKEN_TYPE_SYM_AMPERSAND", - - "TOKEN_TYPE_SYMBOL", - "TOKEN_TYPE_LITERAL_STRING", - "TOKEN_TYPE_LITERAL_NUMERIC", + "=", // "TOKEN_TYPE_SYM_EQUALS", + "~", // "TOKEN_TYPE_SYM_TILDE", + "!", // "TOKEN_TYPE_SYM_BANG", + "^", // "TOKEN_TYPE_SYM_CARET", + "&", // "TOKEN_TYPE_SYM_AMPERSAND", + + "TOKEN_TYPE_SYMBOL", + "TOKEN_TYPE_LITERAL_STRING", + "TOKEN_TYPE_LITERAL_NUMERIC", "true", "false", - "TOKEN_TYPE_COUNT" + "TOKEN_TYPE_COUNT" }; #ifndef LITERAL_TOKEN #define LITERAL_TOKEN(token, word, token_type) \ - if (token_lit(tokenizer, &tk, token, word, token_type)) goto token_parsed; + if (token_lit(tokenizer, &tk, token, word, token_type)) goto token_parsed; #endif #ifndef INCREMENT_CURR_TOKEN #define INCREMENT_CURR_TOKEN(tkn) { \ - if (*(tkn)->curr == '\n') { \ - (tkn)->line_number++; \ - (tkn)->line_start = (tkn)->curr + 1; \ - } \ - (tkn)->curr++; \ + if (*(tkn)->curr == '\n') { \ + (tkn)->line_number++; \ + (tkn)->line_start = (tkn)->curr + 1; \ + } \ + (tkn)->curr++; \ } #endif static b32 token_lit(OnyxTokenizer* tokenizer, OnyxToken* tk, char* lit, b32 is_word, OnyxTokenType type) { - i64 len = chars_match(tokenizer->curr, lit); - if (len > 0) { + i64 len = chars_match(tokenizer->curr, lit); + if (len > 0) { if (is_word && char_is_alphanum(*(tokenizer->curr + len)) || charset_contains("_$", *(tokenizer->curr + len))) return 0; - tk->type = type; - tk->token = tokenizer->curr; - tk->length = len; - tk->pos.line = tokenizer->line_number; - tk->pos.column = (i32)(tokenizer->curr - tokenizer->line_start) + 1; + tk->type = type; + tk->token = tokenizer->curr; + tk->length = len; + tk->pos.line = tokenizer->line_number; + tk->pos.column = (i32)(tokenizer->curr - tokenizer->line_start) + 1; - tokenizer->curr += len; + tokenizer->curr += len; - return 1; - } - return 0; + return 1; + } + return 0; } const char* onyx_get_token_type_name(OnyxTokenType tkn_type) { - return onyx_token_type_names[tkn_type]; + return onyx_token_type_names[tkn_type]; } void onyx_token_null_toggle(OnyxToken tkn) { - static char backup = 0; - char tmp = tkn.token[tkn.length]; - tkn.token[tkn.length] = backup; - backup = tmp; + static char backup = 0; + char tmp = tkn.token[tkn.length]; + tkn.token[tkn.length] = backup; + backup = tmp; } OnyxToken* onyx_get_token(OnyxTokenizer* tokenizer) { - OnyxToken tk; - - // Skip whitespace - while (char_is_whitespace(*tokenizer->curr) && tokenizer->curr != tokenizer->end) - INCREMENT_CURR_TOKEN(tokenizer) - - tk.type = TOKEN_TYPE_UNKNOWN; - tk.token = tokenizer->curr; - tk.length = 1; - tk.pos.filename = tokenizer->filename; - tk.pos.line = tokenizer->line_number; - tk.pos.column = (i32)(tokenizer->curr - tokenizer->line_start) + 1; - - if (tokenizer->curr == tokenizer->end) { - tk.type = TOKEN_TYPE_END_STREAM; - goto token_parsed; - } - - // Comments - if (*tokenizer->curr == '/' && *(tokenizer->curr + 1) == '/') { - tokenizer->curr += 2; - tk.type = TOKEN_TYPE_COMMENT; - tk.token = tokenizer->curr; - - while (*tokenizer->curr != '\n') { - INCREMENT_CURR_TOKEN(tokenizer); - } - - tk.length = tokenizer->curr - tk.token - 2; - goto token_parsed; - } - - LITERAL_TOKEN("struct", 1, TOKEN_TYPE_KEYWORD_STRUCT); - LITERAL_TOKEN("export", 1, TOKEN_TYPE_KEYWORD_EXPORT); - LITERAL_TOKEN("use", 1, TOKEN_TYPE_KEYWORD_USE); - LITERAL_TOKEN("if", 1, TOKEN_TYPE_KEYWORD_IF); - LITERAL_TOKEN("elseif", 1, TOKEN_TYPE_KEYWORD_ELSEIF); - LITERAL_TOKEN("else", 1, TOKEN_TYPE_KEYWORD_ELSE); - LITERAL_TOKEN("foreign", 1, TOKEN_TYPE_KEYWORD_FOREIGN); - LITERAL_TOKEN("return", 1, TOKEN_TYPE_KEYWORD_RETURN); - LITERAL_TOKEN("proc", 1, TOKEN_TYPE_KEYWORD_PROC); - LITERAL_TOKEN("as", 1, TOKEN_TYPE_KEYWORD_CAST); + OnyxToken tk; + + // Skip whitespace + while (char_is_whitespace(*tokenizer->curr) && tokenizer->curr != tokenizer->end) + INCREMENT_CURR_TOKEN(tokenizer) + + tk.type = TOKEN_TYPE_UNKNOWN; + tk.token = tokenizer->curr; + tk.length = 1; + tk.pos.filename = tokenizer->filename; + tk.pos.line = tokenizer->line_number; + tk.pos.column = (i32)(tokenizer->curr - tokenizer->line_start) + 1; + + if (tokenizer->curr == tokenizer->end) { + tk.type = TOKEN_TYPE_END_STREAM; + goto token_parsed; + } + + // Comments + if (*tokenizer->curr == '/' && *(tokenizer->curr + 1) == '/') { + tokenizer->curr += 2; + tk.type = TOKEN_TYPE_COMMENT; + tk.token = tokenizer->curr; + + while (*tokenizer->curr != '\n') { + INCREMENT_CURR_TOKEN(tokenizer); + } + + tk.length = tokenizer->curr - tk.token - 2; + goto token_parsed; + } + + LITERAL_TOKEN("struct", 1, TOKEN_TYPE_KEYWORD_STRUCT); + LITERAL_TOKEN("export", 1, TOKEN_TYPE_KEYWORD_EXPORT); + LITERAL_TOKEN("use", 1, TOKEN_TYPE_KEYWORD_USE); + LITERAL_TOKEN("if", 1, TOKEN_TYPE_KEYWORD_IF); + LITERAL_TOKEN("elseif", 1, TOKEN_TYPE_KEYWORD_ELSEIF); + LITERAL_TOKEN("else", 1, TOKEN_TYPE_KEYWORD_ELSE); + LITERAL_TOKEN("foreign", 1, TOKEN_TYPE_KEYWORD_FOREIGN); + LITERAL_TOKEN("return", 1, TOKEN_TYPE_KEYWORD_RETURN); + LITERAL_TOKEN("proc", 1, TOKEN_TYPE_KEYWORD_PROC); + LITERAL_TOKEN("as", 1, TOKEN_TYPE_KEYWORD_CAST); LITERAL_TOKEN("while", 1, TOKEN_TYPE_KEYWORD_WHILE); LITERAL_TOKEN("break", 1, TOKEN_TYPE_KEYWORD_BREAK); LITERAL_TOKEN("continue", 1, TOKEN_TYPE_KEYWORD_CONTINUE); LITERAL_TOKEN("true", 1, TOKEN_TYPE_LITERAL_BOOL_TRUE); LITERAL_TOKEN("false", 1, TOKEN_TYPE_LITERAL_BOOL_FALSE); - LITERAL_TOKEN("->", 0, TOKEN_TYPE_RIGHT_ARROW); - LITERAL_TOKEN("<-", 0, TOKEN_TYPE_RIGHT_ARROW); - LITERAL_TOKEN("<=", 0, TOKEN_TYPE_SYM_LESS_EQUAL); - LITERAL_TOKEN(">=", 0, TOKEN_TYPE_SYM_GREATER_EQUAL); - LITERAL_TOKEN("==", 0, TOKEN_TYPE_SYM_EQUAL_EQUAL); - LITERAL_TOKEN("!=", 0, TOKEN_TYPE_SYM_NOT_EQUAL); - LITERAL_TOKEN("(", 0, TOKEN_TYPE_OPEN_PAREN); - LITERAL_TOKEN(")", 0, TOKEN_TYPE_CLOSE_PAREN); - LITERAL_TOKEN("{", 0, TOKEN_TYPE_OPEN_BRACE); - LITERAL_TOKEN("}", 0, TOKEN_TYPE_CLOSE_BRACE); - LITERAL_TOKEN("[", 0, TOKEN_TYPE_OPEN_BRACKET); - LITERAL_TOKEN("]", 0, TOKEN_TYPE_CLOSE_BRACKET); - LITERAL_TOKEN("+", 0, TOKEN_TYPE_SYM_PLUS); - LITERAL_TOKEN("-", 0, TOKEN_TYPE_SYM_MINUS); - LITERAL_TOKEN("*", 0, TOKEN_TYPE_SYM_STAR); - LITERAL_TOKEN(".", 0, TOKEN_TYPE_SYM_DOT); - LITERAL_TOKEN("%", 0, TOKEN_TYPE_SYM_PERCENT); - LITERAL_TOKEN("/", 0, TOKEN_TYPE_SYM_FSLASH); - LITERAL_TOKEN("\\", 0, TOKEN_TYPE_SYM_BSLASH); - LITERAL_TOKEN(":", 0, TOKEN_TYPE_SYM_COLON); - LITERAL_TOKEN(";", 0, TOKEN_TYPE_SYM_SEMICOLON); - LITERAL_TOKEN(",", 0, TOKEN_TYPE_SYM_COMMA); - LITERAL_TOKEN(">", 0, TOKEN_TYPE_SYM_GREATER); - LITERAL_TOKEN("<", 0, TOKEN_TYPE_SYM_LESS); - LITERAL_TOKEN("=", 0, TOKEN_TYPE_SYM_EQUALS); - LITERAL_TOKEN("~", 0, TOKEN_TYPE_SYM_TILDE); - LITERAL_TOKEN("!", 0, TOKEN_TYPE_SYM_BANG); - LITERAL_TOKEN("^", 0, TOKEN_TYPE_SYM_CARET); - LITERAL_TOKEN("&", 0, TOKEN_TYPE_SYM_AMPERSAND); - - // Symbols - if (char_is_alpha(*tk.token)) { - u64 len = 0; - while (char_is_alphanum(*tokenizer->curr) || charset_contains("_$", *tokenizer->curr)) { - len++; - INCREMENT_CURR_TOKEN(tokenizer); - } - - tk.length = len; - tk.type = TOKEN_TYPE_SYMBOL; - goto token_parsed; - } - - // String literal - if (*tk.token == '"') { - u64 len = 0; - u64 slash_count = 0; - - INCREMENT_CURR_TOKEN(tokenizer); - - while (!(*tokenizer->curr == '"' && slash_count == 0)) { - len++; - - if (*tokenizer->curr == '\\') { - slash_count += 1; - slash_count %= 2; - } else { - slash_count = 0; - } - - INCREMENT_CURR_TOKEN(tokenizer); - } - - INCREMENT_CURR_TOKEN(tokenizer); - - tk.token++; - tk.type = TOKEN_TYPE_LITERAL_STRING; - tk.length = len; - goto token_parsed; - } - - // Number literal - if (char_is_num(*tokenizer->curr)) { - u32 len = 1; - while (char_is_num(*(tokenizer->curr + 1)) || *(tokenizer->curr + 1) == '.') { - len++; - INCREMENT_CURR_TOKEN(tokenizer); - } + LITERAL_TOKEN("->", 0, TOKEN_TYPE_RIGHT_ARROW); + LITERAL_TOKEN("<-", 0, TOKEN_TYPE_RIGHT_ARROW); + LITERAL_TOKEN("<=", 0, TOKEN_TYPE_SYM_LESS_EQUAL); + LITERAL_TOKEN(">=", 0, TOKEN_TYPE_SYM_GREATER_EQUAL); + LITERAL_TOKEN("==", 0, TOKEN_TYPE_SYM_EQUAL_EQUAL); + LITERAL_TOKEN("!=", 0, TOKEN_TYPE_SYM_NOT_EQUAL); + LITERAL_TOKEN("(", 0, TOKEN_TYPE_OPEN_PAREN); + LITERAL_TOKEN(")", 0, TOKEN_TYPE_CLOSE_PAREN); + LITERAL_TOKEN("{", 0, TOKEN_TYPE_OPEN_BRACE); + LITERAL_TOKEN("}", 0, TOKEN_TYPE_CLOSE_BRACE); + LITERAL_TOKEN("[", 0, TOKEN_TYPE_OPEN_BRACKET); + LITERAL_TOKEN("]", 0, TOKEN_TYPE_CLOSE_BRACKET); + LITERAL_TOKEN("+", 0, TOKEN_TYPE_SYM_PLUS); + LITERAL_TOKEN("-", 0, TOKEN_TYPE_SYM_MINUS); + LITERAL_TOKEN("*", 0, TOKEN_TYPE_SYM_STAR); + LITERAL_TOKEN(".", 0, TOKEN_TYPE_SYM_DOT); + LITERAL_TOKEN("%", 0, TOKEN_TYPE_SYM_PERCENT); + LITERAL_TOKEN("/", 0, TOKEN_TYPE_SYM_FSLASH); + LITERAL_TOKEN("\\", 0, TOKEN_TYPE_SYM_BSLASH); + LITERAL_TOKEN(":", 0, TOKEN_TYPE_SYM_COLON); + LITERAL_TOKEN(";", 0, TOKEN_TYPE_SYM_SEMICOLON); + LITERAL_TOKEN(",", 0, TOKEN_TYPE_SYM_COMMA); + LITERAL_TOKEN(">", 0, TOKEN_TYPE_SYM_GREATER); + LITERAL_TOKEN("<", 0, TOKEN_TYPE_SYM_LESS); + LITERAL_TOKEN("=", 0, TOKEN_TYPE_SYM_EQUALS); + LITERAL_TOKEN("~", 0, TOKEN_TYPE_SYM_TILDE); + LITERAL_TOKEN("!", 0, TOKEN_TYPE_SYM_BANG); + LITERAL_TOKEN("^", 0, TOKEN_TYPE_SYM_CARET); + LITERAL_TOKEN("&", 0, TOKEN_TYPE_SYM_AMPERSAND); + + // Symbols + if (char_is_alpha(*tk.token)) { + u64 len = 0; + while (char_is_alphanum(*tokenizer->curr) || charset_contains("_$", *tokenizer->curr)) { + len++; + INCREMENT_CURR_TOKEN(tokenizer); + } + + tk.length = len; + tk.type = TOKEN_TYPE_SYMBOL; + goto token_parsed; + } + + // String literal + if (*tk.token == '"') { + u64 len = 0; + u64 slash_count = 0; + + INCREMENT_CURR_TOKEN(tokenizer); + + while (!(*tokenizer->curr == '"' && slash_count == 0)) { + len++; + + if (*tokenizer->curr == '\\') { + slash_count += 1; + slash_count %= 2; + } else { + slash_count = 0; + } + + INCREMENT_CURR_TOKEN(tokenizer); + } + + INCREMENT_CURR_TOKEN(tokenizer); + + tk.token++; + tk.type = TOKEN_TYPE_LITERAL_STRING; + tk.length = len; + goto token_parsed; + } + + // Number literal + if (char_is_num(*tokenizer->curr)) { + u32 len = 1; + while (char_is_num(*(tokenizer->curr + 1)) || *(tokenizer->curr + 1) == '.') { + len++; + INCREMENT_CURR_TOKEN(tokenizer); + } if (*(tokenizer->curr + 1) == 'f') { len++; INCREMENT_CURR_TOKEN(tokenizer); } - tk.type = TOKEN_TYPE_LITERAL_NUMERIC; - tk.length = len; - } + tk.type = TOKEN_TYPE_LITERAL_NUMERIC; + tk.length = len; + } - INCREMENT_CURR_TOKEN(tokenizer); + INCREMENT_CURR_TOKEN(tokenizer); token_parsed: - bh_arr_push(tokenizer->tokens, tk); + bh_arr_push(tokenizer->tokens, tk); - return &tokenizer->tokens[bh_arr_length(tokenizer->tokens) - 1]; + return &tokenizer->tokens[bh_arr_length(tokenizer->tokens) - 1]; } OnyxTokenizer onyx_tokenizer_create(bh_allocator allocator, bh_file_contents *fc) { - OnyxTokenizer tknizer = { - .start = fc->data, - .curr = fc->data, - .end = fc->data + fc->length, + OnyxTokenizer tknizer = { + .start = fc->data, + .curr = fc->data, + .end = fc->data + fc->length, - .filename = fc->filename, + .filename = fc->filename, - .line_number = 1, - .line_start = fc->data, - .tokens = NULL, - }; + .line_number = 1, + .line_start = fc->data, + .tokens = NULL, + }; - bh_arr_new(allocator, tknizer.tokens, 512); - return tknizer; + bh_arr_new(allocator, tknizer.tokens, 512); + return tknizer; } void onyx_tokenizer_free(OnyxTokenizer* tokenizer) { - bh_arr_free(tokenizer->tokens); + bh_arr_free(tokenizer->tokens); } void onyx_lex_tokens(OnyxTokenizer* tokenizer) { - OnyxToken* tk; - do { - tk = onyx_get_token(tokenizer); - } while (tk->type != TOKEN_TYPE_END_STREAM); + OnyxToken* tk; + do { + tk = onyx_get_token(tokenizer); + } while (tk->type != TOKEN_TYPE_END_STREAM); } diff --git a/src/onyxmsgs.c b/src/onyxmsgs.c index 3c6018a2..abffedd4 100644 --- a/src/onyxmsgs.c +++ b/src/onyxmsgs.c @@ -3,16 +3,16 @@ static const char* msg_formats[] = { "%s", - "expected token '%s', got '%s'", - "unexpected token '%s'", - "unknown type '%s'", - "expected lval '%b'", - "attempt to assign to constant '%b'", - "unknown symbol '%s'", - "redefinition of function '%s'", - "mismatched types for binary operator, '%s', '%s'", - "mismatched types on assignment, expected '%s', got '%s'", - "expected expression, got '%s'", + "expected token '%s', got '%s'", + "unexpected token '%s'", + "unknown type '%s'", + "expected lval '%b'", + "attempt to assign to constant '%b'", + "unknown symbol '%s'", + "redefinition of function '%s'", + "mismatched types for binary operator, '%s', '%s'", + "mismatched types on assignment, expected '%s', got '%s'", + "expected expression, got '%s'", "attempt to call non-function, '%b'", "returning '%s' from function that returns '%s'", @@ -23,41 +23,41 @@ static const char* msg_formats[] = { }; void onyx_message_add(OnyxMessages* msgs, OnyxMessageType type, OnyxFilePos pos, ...) { - OnyxMessage* msg = bh_alloc_item(msgs->allocator, OnyxMessage); - msg->type = type; - msg->pos = pos; + OnyxMessage* msg = bh_alloc_item(msgs->allocator, OnyxMessage); + msg->type = type; + msg->pos = pos; - va_list arg_list; - va_start(arg_list, pos); - bh_snprintf_va(msg->text, ONYX_MSG_BUFFER_SIZE, msg_formats[type], arg_list); - va_end(arg_list); + va_list arg_list; + va_start(arg_list, pos); + bh_snprintf_va(msg->text, ONYX_MSG_BUFFER_SIZE, msg_formats[type], arg_list); + va_end(arg_list); - OnyxMessage** walker = &msgs->first; - while (*walker && (*walker)->pos.line < pos.line) walker = &(*walker)->next; - while (*walker && (*walker)->pos.line == pos.line && (*walker)->pos.column < pos.column) walker = &(*walker)->next; + OnyxMessage** walker = &msgs->first; + while (*walker && (*walker)->pos.line < pos.line) walker = &(*walker)->next; + while (*walker && (*walker)->pos.line == pos.line && (*walker)->pos.column < pos.column) walker = &(*walker)->next; - msg->next = *walker; - *walker = msg; + msg->next = *walker; + *walker = msg; } void onyx_message_print(OnyxMessages* msgs) { - OnyxMessage* msg = msgs->first; - - while (msg) { - if (msg->pos.filename) { - bh_printf("(%s:%l:%l) %s\n", msg->pos.filename, msg->pos.line, msg->pos.column, msg->text); - } else { - bh_printf("(%l:%l) %s\n", msg->pos.line, msg->pos.column, msg->text); - } - msg = msg->next; - } + OnyxMessage* msg = msgs->first; + + while (msg) { + if (msg->pos.filename) { + bh_printf("(%s:%l:%l) %s\n", msg->pos.filename, msg->pos.line, msg->pos.column, msg->text); + } else { + bh_printf("(%l:%l) %s\n", msg->pos.line, msg->pos.column, msg->text); + } + msg = msg->next; + } } b32 onyx_message_has_errors(OnyxMessages* msgs) { - return msgs->first != NULL; + return msgs->first != NULL; } void onyx_message_create(bh_allocator allocator, OnyxMessages* msgs) { - msgs->allocator = allocator; - msgs->first = NULL; + msgs->allocator = allocator; + msgs->first = NULL; } diff --git a/src/onyxparser.c b/src/onyxparser.c index 8cf4a513..b0014149 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -4,51 +4,51 @@ #include "onyxutils.h" static const char* ast_node_names[] = { - "ERROR", - "PROGRAM", + "ERROR", + "PROGRAM", - "FUNCDEF", + "FUNCDEF", "FOREIGN", - "BLOCK", - "SCOPE", - "LOCAL", + "BLOCK", + "SCOPE", + "LOCAL", "SYMBOL", "UN_OP", "BIN_OP", - "TYPE", - "LITERAL", - "CAST", - "PARAM", + "TYPE", + "LITERAL", + "CAST", + "PARAM", "ARGUMENT", - "CALL", - "ASSIGN", - "RETURN", + "CALL", + "ASSIGN", + "RETURN", - "IF", - "WHILE", + "IF", + "WHILE", - "ONYX_AST_NODE_KIND_COUNT", + "ONYX_AST_NODE_KIND_COUNT", }; struct OnyxTypeInfo builtin_types[] = { - { ONYX_TYPE_INFO_KIND_UNKNOWN, 0, "unknown" }, - { ONYX_TYPE_INFO_KIND_VOID, 0, "void", 0, 0, 0, 0, 1 }, + { ONYX_TYPE_INFO_KIND_UNKNOWN, 0, "unknown" }, + { ONYX_TYPE_INFO_KIND_VOID, 0, "void", 0, 0, 0, 0, 1 }, - { ONYX_TYPE_INFO_KIND_BOOL, 1, "bool", 0, 1, 0, 1, 1 }, + { ONYX_TYPE_INFO_KIND_BOOL, 1, "bool", 0, 1, 0, 1, 1 }, - { ONYX_TYPE_INFO_KIND_UINT32, 4, "u32", 1, 1, 0, 0, 1 }, - { ONYX_TYPE_INFO_KIND_UINT64, 8, "u64", 1, 1, 0, 0, 1 }, + { ONYX_TYPE_INFO_KIND_UINT32, 4, "u32", 1, 1, 0, 0, 1 }, + { ONYX_TYPE_INFO_KIND_UINT64, 8, "u64", 1, 1, 0, 0, 1 }, - { ONYX_TYPE_INFO_KIND_INT32, 4, "i32", 1, 0, 0, 0, 1 }, - { ONYX_TYPE_INFO_KIND_INT64, 8, "i64", 1, 0, 0, 0, 1 }, + { ONYX_TYPE_INFO_KIND_INT32, 4, "i32", 1, 0, 0, 0, 1 }, + { ONYX_TYPE_INFO_KIND_INT64, 8, "i64", 1, 0, 0, 0, 1 }, - { ONYX_TYPE_INFO_KIND_FLOAT32, 4, "f32", 0, 0, 1, 0, 1 }, - { ONYX_TYPE_INFO_KIND_FLOAT64, 8, "f64", 0, 0, 1, 0, 1}, - { ONYX_TYPE_INFO_KIND_SOFT_FLOAT, 8, "sf64", 0, 0, 1, 0, 1 }, + { ONYX_TYPE_INFO_KIND_FLOAT32, 4, "f32", 0, 0, 1, 0, 1 }, + { ONYX_TYPE_INFO_KIND_FLOAT64, 8, "f64", 0, 0, 1, 0, 1}, + { ONYX_TYPE_INFO_KIND_SOFT_FLOAT, 8, "sf64", 0, 0, 1, 0, 1 }, - { 0xffffffff } // Sentinel + { 0xffffffff } // Sentinel }; static OnyxAstNode error_node = { { ONYX_AST_NODE_KIND_ERROR, 0, NULL, &builtin_types[0], 0, NULL, NULL, NULL } }; @@ -78,50 +78,50 @@ static OnyxAstNodeFuncDef* parse_function_definition(OnyxParser* parser); static OnyxAstNode* parse_top_level_statement(OnyxParser* parser); static void parser_next_token(OnyxParser* parser) { - parser->prev_token = parser->curr_token; - parser->curr_token++; - while (parser->curr_token->type == TOKEN_TYPE_COMMENT) parser->curr_token++; + parser->prev_token = parser->curr_token; + parser->curr_token++; + while (parser->curr_token->type == TOKEN_TYPE_COMMENT) parser->curr_token++; } static void parser_prev_token(OnyxParser* parser) { - // TODO: This is probably wrong - while (parser->prev_token->type == TOKEN_TYPE_COMMENT) parser->prev_token--; - parser->curr_token = parser->prev_token; - parser->prev_token--; + // TODO: This is probably wrong + while (parser->prev_token->type == TOKEN_TYPE_COMMENT) parser->prev_token--; + parser->curr_token = parser->prev_token; + parser->prev_token--; } static b32 is_terminating_token(OnyxTokenType token_type) { - switch (token_type) { + switch (token_type) { case TOKEN_TYPE_SYM_SEMICOLON: case TOKEN_TYPE_CLOSE_BRACE: case TOKEN_TYPE_OPEN_BRACE: case TOKEN_TYPE_END_STREAM: - return 1; + return 1; default: - return 0; - } + return 0; + } } static void find_token(OnyxParser* parser, OnyxTokenType token_type) { - while (parser->curr_token->type != token_type && !is_terminating_token(parser->curr_token->type)) { - parser_next_token(parser); - } + while (parser->curr_token->type != token_type && !is_terminating_token(parser->curr_token->type)) { + parser_next_token(parser); + } } // Advances to next token no matter what static OnyxToken* expect(OnyxParser* parser, OnyxTokenType token_type) { - OnyxToken* token = parser->curr_token; - parser_next_token(parser); + OnyxToken* token = parser->curr_token; + parser_next_token(parser); - if (token->type != token_type) { - onyx_message_add(parser->msgs, + if (token->type != token_type) { + onyx_message_add(parser->msgs, ONYX_MESSAGE_TYPE_EXPECTED_TOKEN, token->pos, onyx_get_token_type_name(token_type), onyx_get_token_type_name(token->type)); - return NULL; - } + return NULL; + } - return token; + return token; } static OnyxAstNodeNumLit* parse_numeric_literal(OnyxParser* parser) { @@ -164,15 +164,15 @@ static OnyxAstNodeNumLit* parse_numeric_literal(OnyxParser* parser) { static OnyxAstNode* parse_factor(OnyxParser* parser) { OnyxAstNode* retval = NULL; - switch (parser->curr_token->type) { - case TOKEN_TYPE_OPEN_PAREN: - { - parser_next_token(parser); - OnyxAstNode* expr = parse_expression(parser); - expect(parser, TOKEN_TYPE_CLOSE_PAREN); - retval = expr; + switch (parser->curr_token->type) { + case TOKEN_TYPE_OPEN_PAREN: + { + parser_next_token(parser); + OnyxAstNode* expr = parse_expression(parser); + expect(parser, TOKEN_TYPE_CLOSE_PAREN); + retval = expr; break; - } + } case TOKEN_TYPE_SYM_MINUS: { @@ -192,56 +192,56 @@ static OnyxAstNode* parse_factor(OnyxParser* parser) { break; } - case TOKEN_TYPE_SYMBOL: - { - OnyxToken* sym_token = expect(parser, TOKEN_TYPE_SYMBOL); - OnyxAstNode* sym_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_SYMBOL); + case TOKEN_TYPE_SYMBOL: + { + OnyxToken* sym_token = expect(parser, TOKEN_TYPE_SYMBOL); + OnyxAstNode* sym_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_SYMBOL); sym_node->token = sym_token; - if (parser->curr_token->type != TOKEN_TYPE_OPEN_PAREN) { - retval = sym_node; + if (parser->curr_token->type != TOKEN_TYPE_OPEN_PAREN) { + retval = sym_node; break; - } + } - // NOTE: Function call - OnyxAstNodeCall* call_node = (OnyxAstNodeCall *) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_CALL); + // NOTE: Function call + OnyxAstNodeCall* call_node = (OnyxAstNodeCall *) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_CALL); call_node->token = expect(parser, TOKEN_TYPE_OPEN_PAREN); - call_node->callee = sym_node; - // NOTE: Return type is stored on function definition's type - // This may have to change if we want multiple returns - call_node->type = sym_node->type; - - OnyxAstNode** prev = &call_node->arguments; - OnyxAstNode* curr = NULL; - while (parser->curr_token->type != TOKEN_TYPE_CLOSE_PAREN) { + call_node->callee = sym_node; + // NOTE: Return type is stored on function definition's type + // This may have to change if we want multiple returns + call_node->type = sym_node->type; + + OnyxAstNode** prev = &call_node->arguments; + OnyxAstNode* curr = NULL; + while (parser->curr_token->type != TOKEN_TYPE_CLOSE_PAREN) { curr = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_ARGUMENT); - curr->left = parse_expression(parser); + curr->left = parse_expression(parser); curr->type = curr->left->type; - if (curr != NULL && curr->kind != ONYX_AST_NODE_KIND_ERROR) { - *prev = curr; - prev = &curr->next; - } + if (curr != NULL && curr->kind != ONYX_AST_NODE_KIND_ERROR) { + *prev = curr; + prev = &curr->next; + } - if (parser->curr_token->type == TOKEN_TYPE_CLOSE_PAREN) - break; + if (parser->curr_token->type == TOKEN_TYPE_CLOSE_PAREN) + break; - if (parser->curr_token->type != TOKEN_TYPE_SYM_COMMA) { - onyx_message_add(parser->msgs, - ONYX_MESSAGE_TYPE_EXPECTED_TOKEN, - parser->curr_token->pos, - onyx_get_token_type_name(TOKEN_TYPE_SYM_COMMA), - onyx_get_token_type_name(parser->curr_token->type)); - return &error_node; - } + if (parser->curr_token->type != TOKEN_TYPE_SYM_COMMA) { + onyx_message_add(parser->msgs, + ONYX_MESSAGE_TYPE_EXPECTED_TOKEN, + parser->curr_token->pos, + onyx_get_token_type_name(TOKEN_TYPE_SYM_COMMA), + onyx_get_token_type_name(parser->curr_token->type)); + return &error_node; + } - parser_next_token(parser); - } - parser_next_token(parser); + parser_next_token(parser); + } + parser_next_token(parser); - retval = (OnyxAstNode *) call_node; + retval = (OnyxAstNode *) call_node; break; - } + } case TOKEN_TYPE_LITERAL_NUMERIC: retval = (OnyxAstNode *) parse_numeric_literal(parser); @@ -267,13 +267,13 @@ static OnyxAstNode* parse_factor(OnyxParser* parser) { break; } - default: - onyx_message_add(parser->msgs, - ONYX_MESSAGE_TYPE_UNEXPECTED_TOKEN, - parser->curr_token->pos, - onyx_get_token_type_name(parser->curr_token->type)); + default: + onyx_message_add(parser->msgs, + ONYX_MESSAGE_TYPE_UNEXPECTED_TOKEN, + parser->curr_token->pos, + onyx_get_token_type_name(parser->curr_token->type)); return NULL; - } + } if (parser->curr_token->type == TOKEN_TYPE_KEYWORD_CAST) { OnyxAstNodeUnaryOp* cast_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_UNARY_OP); @@ -312,7 +312,7 @@ static OnyxAstNode* parse_expression(OnyxParser* parser) { bh_arr_new(global_scratch_allocator, tree_stack, 4); bh_arr_set_length(tree_stack, 0); - OnyxAstNode* left = parse_factor(parser); + OnyxAstNode* left = parse_factor(parser); OnyxAstNode* right; OnyxAstNode* root = left; @@ -371,7 +371,7 @@ static OnyxAstNode* parse_expression(OnyxParser* parser) { } expression_done: - return root; + return root; } static OnyxAstNodeIf* parse_if_stmt(OnyxParser* parser) { @@ -430,64 +430,64 @@ static OnyxAstNodeWhile* parse_while_stmt(OnyxParser* parser) { // Returns 1 if the symbol was consumed. Returns 0 otherwise // ret is set to the statement to insert static b32 parse_symbol_statement(OnyxParser* parser, OnyxAstNode** ret) { - if (parser->curr_token->type != TOKEN_TYPE_SYMBOL) return 0; - OnyxToken* symbol = expect(parser, TOKEN_TYPE_SYMBOL); - - switch (parser->curr_token->type) { - // NOTE: Declaration - case TOKEN_TYPE_SYM_COLON: - { - parser_next_token(parser); - OnyxTypeInfo* type = &builtin_types[ONYX_TYPE_INFO_KIND_UNKNOWN]; - - // NOTE: var: type - if (parser->curr_token->type == TOKEN_TYPE_SYMBOL) { - type = parse_type(parser); - } - - OnyxAstNodeLocal* local = (OnyxAstNodeLocal*) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_LOCAL); - local->token = symbol; - local->type = type; - local->flags |= ONYX_AST_FLAG_LVAL; // NOTE: DELETE + if (parser->curr_token->type != TOKEN_TYPE_SYMBOL) return 0; + OnyxToken* symbol = expect(parser, TOKEN_TYPE_SYMBOL); + + switch (parser->curr_token->type) { + // NOTE: Declaration + case TOKEN_TYPE_SYM_COLON: + { + parser_next_token(parser); + OnyxTypeInfo* type = &builtin_types[ONYX_TYPE_INFO_KIND_UNKNOWN]; + + // NOTE: var: type + if (parser->curr_token->type == TOKEN_TYPE_SYMBOL) { + type = parse_type(parser); + } + + OnyxAstNodeLocal* local = (OnyxAstNodeLocal*) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_LOCAL); + local->token = symbol; + local->type = type; + local->flags |= ONYX_AST_FLAG_LVAL; // NOTE: DELETE *ret = (OnyxAstNode *) local; - 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; - } + 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); + OnyxAstNode* assignment = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_ASSIGNMENT); local->next = 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->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; OnyxAstNode* left_symbol = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_SYMBOL); left_symbol->token = symbol; - assignment->left = left_symbol; - } - return 1; - } - - // NOTE: Assignment - case TOKEN_TYPE_SYM_EQUALS: - { + assignment->left = left_symbol; + } + return 1; + } + + // NOTE: Assignment + case TOKEN_TYPE_SYM_EQUALS: + { OnyxAstNode* assignment = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_ASSIGNMENT); assignment->token = parser->curr_token; - parser_next_token(parser); + parser_next_token(parser); - OnyxAstNode* lval = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_SYMBOL); + OnyxAstNode* lval = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_SYMBOL); lval->token = symbol; OnyxAstNode* rval = parse_expression(parser); @@ -495,64 +495,64 @@ static b32 parse_symbol_statement(OnyxParser* parser, OnyxAstNode** ret) { assignment->left = lval; *ret = assignment; return 1; - } + } - default: - parser_prev_token(parser); - } + default: + parser_prev_token(parser); + } - return 0; + return 0; } static OnyxAstNode* parse_return_statement(OnyxParser* parser) { - OnyxAstNode* return_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_RETURN); - return_node->token = expect(parser, TOKEN_TYPE_KEYWORD_RETURN); + OnyxAstNode* return_node = onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_RETURN); + return_node->token = expect(parser, TOKEN_TYPE_KEYWORD_RETURN); - OnyxAstNode* expr = NULL; + OnyxAstNode* expr = NULL; - if (parser->curr_token->type != TOKEN_TYPE_SYM_SEMICOLON) { - expr = parse_expression(parser); + if (parser->curr_token->type != TOKEN_TYPE_SYM_SEMICOLON) { + expr = parse_expression(parser); - if (expr == NULL || expr == &error_node) { - return &error_node; - } else { - return_node->left = expr; - } - } + if (expr == NULL || expr == &error_node) { + return &error_node; + } else { + return_node->left = expr; + } + } - return return_node; + return return_node; } static OnyxAstNode* parse_statement(OnyxParser* parser) { b32 needs_semicolon = 1; OnyxAstNode* retval = NULL; - switch (parser->curr_token->type) { - case TOKEN_TYPE_KEYWORD_RETURN: - retval = parse_return_statement(parser); + switch (parser->curr_token->type) { + case TOKEN_TYPE_KEYWORD_RETURN: + retval = parse_return_statement(parser); break; - case TOKEN_TYPE_OPEN_BRACE: + case TOKEN_TYPE_OPEN_BRACE: needs_semicolon = 0; - retval = (OnyxAstNode *) parse_block(parser); + retval = (OnyxAstNode *) parse_block(parser); break; - case TOKEN_TYPE_SYMBOL: + case TOKEN_TYPE_SYMBOL: if (parse_symbol_statement(parser, &retval)) break; // fallthrough - case TOKEN_TYPE_OPEN_PAREN: - case TOKEN_TYPE_SYM_PLUS: - case TOKEN_TYPE_SYM_MINUS: - case TOKEN_TYPE_SYM_BANG: - case TOKEN_TYPE_LITERAL_NUMERIC: - case TOKEN_TYPE_LITERAL_STRING: - retval = parse_expression(parser); + case TOKEN_TYPE_OPEN_PAREN: + case TOKEN_TYPE_SYM_PLUS: + case TOKEN_TYPE_SYM_MINUS: + case TOKEN_TYPE_SYM_BANG: + case TOKEN_TYPE_LITERAL_NUMERIC: + case TOKEN_TYPE_LITERAL_STRING: + retval = parse_expression(parser); break; - case TOKEN_TYPE_KEYWORD_IF: + case TOKEN_TYPE_KEYWORD_IF: needs_semicolon = 0; - retval = (OnyxAstNode *) parse_if_stmt(parser); + retval = (OnyxAstNode *) parse_if_stmt(parser); break; case TOKEN_TYPE_KEYWORD_WHILE: @@ -570,139 +570,139 @@ static OnyxAstNode* parse_statement(OnyxParser* parser) { retval->token = expect(parser, TOKEN_TYPE_KEYWORD_CONTINUE); break; - default: + default: break; - } + } if (needs_semicolon) { - if (parser->curr_token->type != TOKEN_TYPE_SYM_SEMICOLON) { - onyx_message_add(parser->msgs, - ONYX_MESSAGE_TYPE_EXPECTED_TOKEN, - parser->curr_token->pos, - onyx_get_token_type_name(TOKEN_TYPE_SYM_SEMICOLON), - onyx_get_token_type_name(parser->curr_token->type)); - - find_token(parser, TOKEN_TYPE_SYM_SEMICOLON); - } - parser_next_token(parser); + if (parser->curr_token->type != TOKEN_TYPE_SYM_SEMICOLON) { + onyx_message_add(parser->msgs, + ONYX_MESSAGE_TYPE_EXPECTED_TOKEN, + parser->curr_token->pos, + onyx_get_token_type_name(TOKEN_TYPE_SYM_SEMICOLON), + onyx_get_token_type_name(parser->curr_token->type)); + + find_token(parser, TOKEN_TYPE_SYM_SEMICOLON); + } + parser_next_token(parser); } return retval; } static OnyxAstNodeBlock* parse_block(OnyxParser* parser) { - OnyxAstNodeBlock* block = (OnyxAstNodeBlock *) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_BLOCK); + OnyxAstNodeBlock* block = (OnyxAstNodeBlock *) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_BLOCK); OnyxAstNodeScope* scope = (OnyxAstNodeScope *) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_SCOPE); block->scope = scope; - // --- is for an empty block - if (parser->curr_token->type == TOKEN_TYPE_SYM_MINUS) { - expect(parser, TOKEN_TYPE_SYM_MINUS); - expect(parser, TOKEN_TYPE_SYM_MINUS); - expect(parser, TOKEN_TYPE_SYM_MINUS); - return block; - } + // --- is for an empty block + if (parser->curr_token->type == TOKEN_TYPE_SYM_MINUS) { + expect(parser, TOKEN_TYPE_SYM_MINUS); + expect(parser, TOKEN_TYPE_SYM_MINUS); + expect(parser, TOKEN_TYPE_SYM_MINUS); + return block; + } - expect(parser, TOKEN_TYPE_OPEN_BRACE); + expect(parser, TOKEN_TYPE_OPEN_BRACE); - OnyxAstNode** next = &block->body; - OnyxAstNode* stmt = NULL; - while (parser->curr_token->type != TOKEN_TYPE_CLOSE_BRACE) { - stmt = parse_statement(parser); + OnyxAstNode** next = &block->body; + OnyxAstNode* stmt = NULL; + while (parser->curr_token->type != TOKEN_TYPE_CLOSE_BRACE) { + stmt = parse_statement(parser); - if (stmt != NULL && stmt->kind != ONYX_AST_NODE_KIND_ERROR) { - *next = stmt; + if (stmt != NULL && stmt->kind != ONYX_AST_NODE_KIND_ERROR) { + *next = stmt; while (stmt->next != NULL) stmt = stmt->next; - next = &stmt->next; - } - } + next = &stmt->next; + } + } - expect(parser, TOKEN_TYPE_CLOSE_BRACE); + expect(parser, TOKEN_TYPE_CLOSE_BRACE); - return block; + return block; } static OnyxTypeInfo* parse_type(OnyxParser* parser) { - OnyxTypeInfo* type_info = &builtin_types[ONYX_TYPE_INFO_KIND_UNKNOWN]; + OnyxTypeInfo* type_info = &builtin_types[ONYX_TYPE_INFO_KIND_UNKNOWN]; - OnyxToken* symbol = expect(parser, TOKEN_TYPE_SYMBOL); - if (symbol == NULL) return type_info; + OnyxToken* symbol = expect(parser, TOKEN_TYPE_SYMBOL); + if (symbol == NULL) return type_info; - onyx_token_null_toggle(*symbol); + onyx_token_null_toggle(*symbol); - if (!bh_table_has(OnyxAstNode*, parser->identifiers, symbol->token)) { - onyx_message_add(parser->msgs, ONYX_MESSAGE_TYPE_UNKNOWN_TYPE, symbol->pos, symbol->token); - } else { - OnyxAstNode* type_info_node = bh_table_get(OnyxAstNode*, parser->identifiers, symbol->token); + if (!bh_table_has(OnyxAstNode*, parser->identifiers, symbol->token)) { + onyx_message_add(parser->msgs, ONYX_MESSAGE_TYPE_UNKNOWN_TYPE, symbol->pos, symbol->token); + } else { + OnyxAstNode* type_info_node = bh_table_get(OnyxAstNode*, parser->identifiers, symbol->token); - if (type_info_node->kind == ONYX_AST_NODE_KIND_TYPE) { - type_info = type_info_node->type; - } - } + if (type_info_node->kind == ONYX_AST_NODE_KIND_TYPE) { + type_info = type_info_node->type; + } + } - onyx_token_null_toggle(*symbol); - return type_info; + onyx_token_null_toggle(*symbol); + return type_info; } static OnyxAstNodeParam* parse_function_params(OnyxParser* parser) { if (parser->curr_token->type != TOKEN_TYPE_OPEN_PAREN) return NULL; - expect(parser, TOKEN_TYPE_OPEN_PAREN); + expect(parser, TOKEN_TYPE_OPEN_PAREN); - if (parser->curr_token->type == TOKEN_TYPE_CLOSE_PAREN) { - parser_next_token(parser); - return NULL; - } + if (parser->curr_token->type == TOKEN_TYPE_CLOSE_PAREN) { + parser_next_token(parser); + return NULL; + } - OnyxAstNodeParam* first_param = NULL; - OnyxAstNodeParam* curr_param = NULL; - OnyxAstNodeParam* trailer = NULL; + OnyxAstNodeParam* first_param = NULL; + OnyxAstNodeParam* curr_param = NULL; + OnyxAstNodeParam* trailer = NULL; - OnyxToken* symbol; - while (parser->curr_token->type != TOKEN_TYPE_CLOSE_PAREN) { - if (parser->curr_token->type == TOKEN_TYPE_SYM_COMMA) parser_next_token(parser); + OnyxToken* symbol; + while (parser->curr_token->type != TOKEN_TYPE_CLOSE_PAREN) { + if (parser->curr_token->type == TOKEN_TYPE_SYM_COMMA) parser_next_token(parser); - symbol = expect(parser, TOKEN_TYPE_SYMBOL); + symbol = expect(parser, TOKEN_TYPE_SYMBOL); - curr_param = (OnyxAstNodeParam *) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_PARAM); - curr_param->token = symbol; - curr_param->type = parse_type(parser); + curr_param = (OnyxAstNodeParam *) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_PARAM); + curr_param->token = symbol; + curr_param->type = parse_type(parser); curr_param->flags |= ONYX_AST_FLAG_CONST; - if (first_param == NULL) first_param = curr_param; + if (first_param == NULL) first_param = curr_param; - curr_param->next = NULL; - if (trailer) trailer->next = curr_param; + curr_param->next = NULL; + if (trailer) trailer->next = curr_param; - trailer = curr_param; - } + trailer = curr_param; + } - parser_next_token(parser); // Skip the ) - return first_param; + parser_next_token(parser); // Skip the ) + return first_param; } static OnyxAstNodeFuncDef* parse_function_definition(OnyxParser* parser) { - expect(parser, TOKEN_TYPE_KEYWORD_PROC); + expect(parser, TOKEN_TYPE_KEYWORD_PROC); - OnyxAstNodeFuncDef* func_def = (OnyxAstNodeFuncDef *) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_FUNCDEF); + OnyxAstNodeFuncDef* func_def = (OnyxAstNodeFuncDef *) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_FUNCDEF); - OnyxAstNodeParam* params = parse_function_params(parser); - func_def->params = params; + OnyxAstNodeParam* params = parse_function_params(parser); + func_def->params = params; - if (parser->curr_token->type == TOKEN_TYPE_RIGHT_ARROW) { - expect(parser, TOKEN_TYPE_RIGHT_ARROW); + if (parser->curr_token->type == TOKEN_TYPE_RIGHT_ARROW) { + expect(parser, TOKEN_TYPE_RIGHT_ARROW); - OnyxTypeInfo* return_type = parse_type(parser); - func_def->return_type = return_type; - } else { - func_def->return_type = &builtin_types[ONYX_TYPE_INFO_KIND_VOID]; - } + OnyxTypeInfo* return_type = parse_type(parser); + func_def->return_type = return_type; + } else { + func_def->return_type = &builtin_types[ONYX_TYPE_INFO_KIND_VOID]; + } - func_def->body = parse_block(parser); + func_def->body = parse_block(parser); - return func_def; + return func_def; } static OnyxAstNode* parse_top_level_symbol(OnyxParser* parser) { @@ -732,35 +732,35 @@ static OnyxAstNode* parse_top_level_symbol(OnyxParser* parser) { } static OnyxAstNode* parse_top_level_statement(OnyxParser* parser) { - switch (parser->curr_token->type) { - case TOKEN_TYPE_KEYWORD_USE: - assert(0); - break; - - case TOKEN_TYPE_KEYWORD_EXPORT: - { - expect(parser, TOKEN_TYPE_KEYWORD_EXPORT); - if (parser->curr_token->type != TOKEN_TYPE_SYMBOL) { - onyx_message_add(parser->msgs, - ONYX_MESSAGE_TYPE_EXPECTED_TOKEN, - parser->curr_token->pos, - onyx_get_token_type_name(TOKEN_TYPE_SYMBOL), - onyx_get_token_type_name(parser->curr_token->type)); - break; - } - - OnyxAstNode* top_level_decl = parse_top_level_statement(parser); - top_level_decl->flags |= ONYX_AST_FLAG_EXPORTED; - return top_level_decl; - } - - case TOKEN_TYPE_SYMBOL: - { - OnyxToken* symbol = parser->curr_token; - parser_next_token(parser); - - expect(parser, TOKEN_TYPE_SYM_COLON); - expect(parser, TOKEN_TYPE_SYM_COLON); + switch (parser->curr_token->type) { + case TOKEN_TYPE_KEYWORD_USE: + assert(0); + break; + + case TOKEN_TYPE_KEYWORD_EXPORT: + { + expect(parser, TOKEN_TYPE_KEYWORD_EXPORT); + if (parser->curr_token->type != TOKEN_TYPE_SYMBOL) { + onyx_message_add(parser->msgs, + ONYX_MESSAGE_TYPE_EXPECTED_TOKEN, + parser->curr_token->pos, + onyx_get_token_type_name(TOKEN_TYPE_SYMBOL), + onyx_get_token_type_name(parser->curr_token->type)); + break; + } + + OnyxAstNode* top_level_decl = parse_top_level_statement(parser); + top_level_decl->flags |= ONYX_AST_FLAG_EXPORTED; + return top_level_decl; + } + + case TOKEN_TYPE_SYMBOL: + { + OnyxToken* symbol = parser->curr_token; + parser_next_token(parser); + + expect(parser, TOKEN_TYPE_SYM_COLON); + expect(parser, TOKEN_TYPE_SYM_COLON); OnyxAstNode* node = parse_top_level_symbol(parser); if (node->kind == ONYX_AST_NODE_KIND_FUNCDEF) { @@ -774,13 +774,13 @@ static OnyxAstNode* parse_top_level_statement(OnyxParser* parser) { } return node; - } + } - default: break; - } + default: break; + } - parser_next_token(parser); - return NULL; + parser_next_token(parser); + return NULL; } @@ -788,66 +788,66 @@ static OnyxAstNode* parse_top_level_statement(OnyxParser* parser) { const char* onyx_ast_node_kind_string(OnyxAstNodeKind kind) { - return ast_node_names[kind]; + return ast_node_names[kind]; } // NOTE: This returns a void* so I don't need to cast it everytime I use it void* onyx_ast_node_new(bh_allocator alloc, OnyxAstNodeKind kind) {\ - OnyxAstNode* node = bh_alloc_item(alloc, OnyxAstNode); - node->kind = kind; - node->flags = 0; - node->token = NULL; - node->type = NULL; + OnyxAstNode* node = bh_alloc_item(alloc, OnyxAstNode); + node->kind = kind; + node->flags = 0; + node->token = NULL; + node->type = NULL; node->data = 0; - node->next = NULL; - node->left = NULL; - node->right = NULL; + node->next = NULL; + node->left = NULL; + node->right = NULL; - return node; + return node; } OnyxParser onyx_parser_create(bh_allocator alloc, OnyxTokenizer *tokenizer, OnyxMessages* msgs) { - OnyxParser parser; + OnyxParser parser; - bh_table_init(bh_heap_allocator(), parser.identifiers, 61); + bh_table_init(bh_heap_allocator(), parser.identifiers, 61); - OnyxTypeInfo* it = &builtin_types[0]; - while (it->kind != 0xffffffff) { - OnyxAstNode* tmp = onyx_ast_node_new(alloc, ONYX_AST_NODE_KIND_TYPE); - tmp->type = it; - bh_table_put(OnyxAstNode*, parser.identifiers, (char *)it->name, tmp); - it++; - } + OnyxTypeInfo* it = &builtin_types[0]; + while (it->kind != 0xffffffff) { + OnyxAstNode* tmp = onyx_ast_node_new(alloc, ONYX_AST_NODE_KIND_TYPE); + tmp->type = it; + bh_table_put(OnyxAstNode*, parser.identifiers, (char *)it->name, tmp); + it++; + } - parser.allocator = alloc; - parser.tokenizer = tokenizer; - parser.curr_token = tokenizer->tokens; - parser.prev_token = NULL; - parser.msgs = msgs; + parser.allocator = alloc; + parser.tokenizer = tokenizer; + parser.curr_token = tokenizer->tokens; + parser.prev_token = NULL; + parser.msgs = msgs; - return parser; + return parser; } void onyx_parser_free(OnyxParser* parser) { - bh_table_free(parser->identifiers); + bh_table_free(parser->identifiers); } OnyxAstNodeFile* onyx_parse(OnyxParser *parser) { - OnyxAstNodeFile* program = (OnyxAstNodeFile *) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_PROGRAM); + OnyxAstNodeFile* program = (OnyxAstNodeFile *) onyx_ast_node_new(parser->allocator, ONYX_AST_NODE_KIND_PROGRAM); - OnyxAstNode** prev_stmt = &program->contents; - OnyxAstNode* curr_stmt = NULL; - while (parser->curr_token->type != TOKEN_TYPE_END_STREAM) { - curr_stmt = parse_top_level_statement(parser); + OnyxAstNode** prev_stmt = &program->contents; + OnyxAstNode* curr_stmt = NULL; + while (parser->curr_token->type != TOKEN_TYPE_END_STREAM) { + curr_stmt = parse_top_level_statement(parser); - // Building a linked list of statements down the "next" chain - if (curr_stmt != NULL && curr_stmt != &error_node) { - *prev_stmt = curr_stmt; + // Building a linked list of statements down the "next" chain + if (curr_stmt != NULL && curr_stmt != &error_node) { + *prev_stmt = curr_stmt; while (curr_stmt->next != NULL) curr_stmt = curr_stmt->next; - prev_stmt = &curr_stmt->next; - } - } + prev_stmt = &curr_stmt->next; + } + } - return program; + return program; } diff --git a/src/onyxtypecheck.c b/src/onyxtypecheck.c index a1846c2f..ad23ea67 100644 --- a/src/onyxtypecheck.c +++ b/src/onyxtypecheck.c @@ -253,7 +253,7 @@ static void typecheck_expression(OnyxSemPassState* state, OnyxAstNode* expr) { static void typecheck_statement(OnyxSemPassState* state, OnyxAstNode* stmt) { switch (stmt->kind) { case ONYX_AST_NODE_KIND_ASSIGNMENT: typecheck_assignment(state, stmt); break; - case ONYX_AST_NODE_KIND_RETURN: typecheck_return(state, stmt); break; + case ONYX_AST_NODE_KIND_RETURN: typecheck_return(state, stmt); break; case ONYX_AST_NODE_KIND_IF: typecheck_if(state, &stmt->as_if); break; case ONYX_AST_NODE_KIND_WHILE: typecheck_while(state, &stmt->as_while); break; case ONYX_AST_NODE_KIND_CALL: typecheck_call(state, &stmt->as_call); break; diff --git a/src/onyxutils.c b/src/onyxutils.c index 2964b344..404e1d79 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -8,91 +8,91 @@ bh_allocator global_scratch_allocator; #define print_indent { if (indent > 0) bh_printf("\n"); for (int i = 0; i < indent; i++) bh_printf(" "); } void onyx_ast_print(OnyxAstNode* node, i32 indent) { - if (node == NULL) return; + if (node == NULL) return; - print_indent; - bh_printf("(%d) %s ", node->flags, onyx_ast_node_kind_string(node->kind)); + print_indent; + bh_printf("(%d) %s ", node->flags, onyx_ast_node_kind_string(node->kind)); - switch (node->kind) { - case ONYX_AST_NODE_KIND_PROGRAM: { - if (node->next) - onyx_ast_print(node->next, indent + 1); + switch (node->kind) { + case ONYX_AST_NODE_KIND_PROGRAM: { + if (node->next) + onyx_ast_print(node->next, indent + 1); - break; - } + break; + } - case ONYX_AST_NODE_KIND_FUNCDEF: { + case ONYX_AST_NODE_KIND_FUNCDEF: { if (node->token) bh_printf("(%b) ", node->token->token, node->token->length); - OnyxAstNodeFuncDef* fd = &node->as_funcdef; - - print_indent; - bh_printf("Params "); - if (fd->params) - onyx_ast_print((OnyxAstNode *) fd->params, 0); - - print_indent; - bh_printf("Returns %s", fd->return_type->name); - - print_indent; - bh_printf("Body"); - if (fd->body) - onyx_ast_print((OnyxAstNode *) fd->body, indent + 1); - - if (fd->next) - onyx_ast_print((OnyxAstNode *) fd->next, indent); - - break; - } - - case ONYX_AST_NODE_KIND_PARAM: { - OnyxAstNodeParam* param = &node->as_param; - bh_printf("%b %s", param->token->token, param->token->length, param->type->name); - if (param->next && indent == 0) { - bh_printf(", "); - onyx_ast_print((OnyxAstNode *) param->next, 0); - } - - break; - } - - case ONYX_AST_NODE_KIND_BLOCK: { - OnyxAstNodeBlock* block = &node->as_block; - if (block->scope) { - onyx_ast_print((OnyxAstNode *) block->scope, indent + 1); - } - - if (block->body) { - onyx_ast_print((OnyxAstNode *) block->body, indent + 1); - } - - if (block->next) { - onyx_ast_print(block->next, indent); - } - - break; - } - - case ONYX_AST_NODE_KIND_SCOPE: { - OnyxAstNodeScope* scope = &node->as_scope; - if (scope->last_local) { - onyx_ast_print((OnyxAstNode *) scope->last_local, 0); - } - - break; - } - - case ONYX_AST_NODE_KIND_LOCAL: { - OnyxAstNodeLocal* local = &node->as_local; - bh_printf("%b %s", local->token->token, local->token->length, local->type->name); - if (local->prev_local && indent == 0) { - bh_printf(", "); - onyx_ast_print((OnyxAstNode *) local->prev_local, 0); - } else if (local->next && indent != 0) { + OnyxAstNodeFuncDef* fd = &node->as_funcdef; + + print_indent; + bh_printf("Params "); + if (fd->params) + onyx_ast_print((OnyxAstNode *) fd->params, 0); + + print_indent; + bh_printf("Returns %s", fd->return_type->name); + + print_indent; + bh_printf("Body"); + if (fd->body) + onyx_ast_print((OnyxAstNode *) fd->body, indent + 1); + + if (fd->next) + onyx_ast_print((OnyxAstNode *) fd->next, indent); + + break; + } + + case ONYX_AST_NODE_KIND_PARAM: { + OnyxAstNodeParam* param = &node->as_param; + bh_printf("%b %s", param->token->token, param->token->length, param->type->name); + if (param->next && indent == 0) { + bh_printf(", "); + onyx_ast_print((OnyxAstNode *) param->next, 0); + } + + break; + } + + case ONYX_AST_NODE_KIND_BLOCK: { + OnyxAstNodeBlock* block = &node->as_block; + if (block->scope) { + onyx_ast_print((OnyxAstNode *) block->scope, indent + 1); + } + + if (block->body) { + onyx_ast_print((OnyxAstNode *) block->body, indent + 1); + } + + if (block->next) { + onyx_ast_print(block->next, indent); + } + + break; + } + + case ONYX_AST_NODE_KIND_SCOPE: { + OnyxAstNodeScope* scope = &node->as_scope; + if (scope->last_local) { + onyx_ast_print((OnyxAstNode *) scope->last_local, 0); + } + + break; + } + + case ONYX_AST_NODE_KIND_LOCAL: { + OnyxAstNodeLocal* local = &node->as_local; + bh_printf("%b %s", local->token->token, local->token->length, local->type->name); + if (local->prev_local && indent == 0) { + bh_printf(", "); + onyx_ast_print((OnyxAstNode *) local->prev_local, 0); + } else if (local->next && indent != 0) { onyx_ast_print(local->next, indent); } - break; - } + break; + } case ONYX_AST_NODE_KIND_SYMBOL: { bh_printf("%b", node->token->token, node->token->length); @@ -102,33 +102,33 @@ void onyx_ast_print(OnyxAstNode* node, i32 indent) { break; } - case ONYX_AST_NODE_KIND_RETURN: { - if (node->left) { - onyx_ast_print(node->left, indent + 1); - } - - break; - } - - case ONYX_AST_NODE_KIND_LITERAL: { - bh_printf("(%s) %b", node->type->name, node->token->token, node->token->length); - if (node->next) { - onyx_ast_print(node->next, indent); - } - break; - } - - case ONYX_AST_NODE_KIND_CAST: { - bh_printf("to %s ", node->type->name); - onyx_ast_print(node->left, indent + 1); - if (node->next) { - onyx_ast_print(node->next, indent); - } - break; - } - - case ONYX_AST_NODE_KIND_CALL: { - OnyxAstNodeCall* call = &node->as_call; + case ONYX_AST_NODE_KIND_RETURN: { + if (node->left) { + onyx_ast_print(node->left, indent + 1); + } + + break; + } + + case ONYX_AST_NODE_KIND_LITERAL: { + bh_printf("(%s) %b", node->type->name, node->token->token, node->token->length); + if (node->next) { + onyx_ast_print(node->next, indent); + } + break; + } + + case ONYX_AST_NODE_KIND_CAST: { + bh_printf("to %s ", node->type->name); + onyx_ast_print(node->left, indent + 1); + if (node->next) { + onyx_ast_print(node->next, indent); + } + break; + } + + case ONYX_AST_NODE_KIND_CALL: { + OnyxAstNodeCall* call = &node->as_call; if (call->callee) { if (call->callee->kind == ONYX_AST_NODE_KIND_FUNCDEF) { bh_printf("function: %b", call->callee->token->token, call->callee->token->length); @@ -136,12 +136,12 @@ void onyx_ast_print(OnyxAstNode* node, i32 indent) { onyx_ast_print(call->callee, indent + 1); } } - onyx_ast_print(call->arguments, indent + 1); - if (call->next) { - onyx_ast_print(call->next, indent); - } - break; - } + onyx_ast_print(call->arguments, indent + 1); + if (call->next) { + onyx_ast_print(call->next, indent); + } + break; + } case ONYX_AST_NODE_KIND_FOREIGN: { OnyxAstNodeForeign* foreign = &node->as_foreign; @@ -153,9 +153,9 @@ void onyx_ast_print(OnyxAstNode* node, i32 indent) { onyx_ast_print(foreign->import, indent + 1); } - if (foreign->next) { - onyx_ast_print(foreign->next, indent); - } + if (foreign->next) { + onyx_ast_print(foreign->next, indent); + } break; } @@ -182,13 +182,13 @@ void onyx_ast_print(OnyxAstNode* node, i32 indent) { break; } - default: { - onyx_ast_print(node->left, indent + 1); - onyx_ast_print(node->right, indent + 1); - if (node->next) { - onyx_ast_print(node->next, indent); - } - break; - } - } + default: { + onyx_ast_print(node->left, indent + 1); + onyx_ast_print(node->right, indent + 1); + if (node->next) { + onyx_ast_print(node->next, indent); + } + break; + } + } } diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 02941609..eec71c03 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -18,194 +18,194 @@ const WasmType WASM_TYPE_VOID = '\0'; #endif static const char* wi_string(WasmInstructionType wit) { - switch (wit) { - case WI_UNREACHABLE: return "WI_UNREACHABLE"; - case WI_NOP: return "WI_NOP"; - case WI_BLOCK_START: return "WI_BLOCK_START"; - case WI_BLOCK_END: return "WI_BLOCK_END"; - case WI_LOOP_START: return "WI_LOOP_START"; - case WI_IF_START: return "WI_IF_START"; - case WI_ELSE: return "WI_ELSE"; - case WI_JUMP: return "WI_JUMP"; - case WI_COND_JUMP: return "WI_COND_JUMP"; - case WI_JUMP_TABLE: return "WI_JUMP_TABLE"; - case WI_RETURN: return "WI_RETURN"; - case WI_CALL: return "WI_CALL"; - case WI_CALL_INDIRECT: return "WI_CALL_INDIRECT"; - case WI_DROP: return "WI_DROP"; - case WI_SELECT: return "WI_SELECT"; - case WI_LOCAL_GET: return "WI_LOCAL_GET"; - case WI_LOCAL_SET: return "WI_LOCAL_SET"; - case WI_LOCAL_TEE: return "WI_LOCAL_TEE"; - case WI_GLOBAL_GET: return "WI_GLOBAL_GET"; - case WI_GLOBAL_SET: return "WI_GLOBAL_SET"; - case WI_I32_LOAD: return "WI_I32_LOAD"; - case WI_I64_LOAD: return "WI_I64_LOAD"; - case WI_F32_LOAD: return "WI_F32_LOAD"; - case WI_F64_LOAD: return "WI_F64_LOAD"; - case WI_I32_LOAD_8_S: return "WI_I32_LOAD_8_S"; - case WI_I32_LOAD_8_U: return "WI_I32_LOAD_8_U"; - case WI_I32_LOAD_16_S: return "WI_I32_LOAD_16_S"; - case WI_I32_LOAD_16_U: return "WI_I32_LOAD_16_U"; - case WI_I64_LOAD_8_S: return "WI_I64_LOAD_8_S"; - case WI_I64_LOAD_8_U: return "WI_I64_LOAD_8_U"; - case WI_I64_LOAD_16_S: return "WI_I64_LOAD_16_S"; - case WI_I64_LOAD_16_U: return "WI_I64_LOAD_16_U"; - case WI_I64_LOAD_32_S: return "WI_I64_LOAD_32_S"; - case WI_I64_LOAD_32_U: return "WI_I64_LOAD_32_U"; - case WI_I32_STORE: return "WI_I32_STORE"; - case WI_I64_STORE: return "WI_I64_STORE"; - case WI_F32_STORE: return "WI_F32_STORE"; - case WI_F64_STORE: return "WI_F64_STORE"; - case WI_I32_STORE_8: return "WI_I32_STORE_8"; - case WI_I32_STORE_16: return "WI_I32_STORE_16"; - case WI_I64_STORE_8: return "WI_I64_STORE_8"; - case WI_I64_STORE_16: return "WI_I64_STORE_16"; - case WI_I64_STORE_32: return "WI_I64_STORE_32"; - case WI_MEMORY_SIZE: return "WI_MEMORY_SIZE"; - case WI_MEMORY_GROW: return "WI_MEMORY_GROW"; - case WI_I32_CONST: return "WI_I32_CONST"; - case WI_I64_CONST: return "WI_I64_CONST"; - case WI_F32_CONST: return "WI_F32_CONST"; - case WI_F64_CONST: return "WI_F64_CONST"; - case WI_I32_EQZ: return "WI_I32_EQZ"; - case WI_I32_EQ: return "WI_I32_EQ"; - case WI_I32_NE: return "WI_I32_NE"; - case WI_I32_LT_S: return "WI_I32_LT_S"; - case WI_I32_LT_U: return "WI_I32_LT_U"; - case WI_I32_GT_S: return "WI_I32_GT_S"; - case WI_I32_GT_U: return "WI_I32_GT_U"; - case WI_I32_LE_S: return "WI_I32_LE_S"; - case WI_I32_LE_U: return "WI_I32_LE_U"; - case WI_I32_GE_S: return "WI_I32_GE_S"; - case WI_I32_GE_U: return "WI_I32_GE_U"; - case WI_I64_EQZ: return "WI_I64_EQZ"; - case WI_I64_EQ: return "WI_I64_EQ"; - case WI_I64_NE: return "WI_I64_NE"; - case WI_I64_LT_S: return "WI_I64_LT_S"; - case WI_I64_LT_U: return "WI_I64_LT_U"; - case WI_I64_GT_S: return "WI_I64_GT_S"; - case WI_I64_GT_U: return "WI_I64_GT_U"; - case WI_I64_LE_S: return "WI_I64_LE_S"; - case WI_I64_LE_U: return "WI_I64_LE_U"; - case WI_I64_GE_S: return "WI_I64_GE_S"; - case WI_I64_GE_U: return "WI_I64_GE_U"; - case WI_F32_EQ: return "WI_F32_EQ"; - case WI_F32_NE: return "WI_F32_NE"; - case WI_F32_LT: return "WI_F32_LT"; - case WI_F32_GT: return "WI_F32_GT"; - case WI_F32_LE: return "WI_F32_LE"; - case WI_F32_GE: return "WI_F32_GE"; - case WI_F64_EQ: return "WI_F64_EQ"; - case WI_F64_NE: return "WI_F64_NE"; - case WI_F64_LT: return "WI_F64_LT"; - case WI_F64_GT: return "WI_F64_GT"; - case WI_F64_LE: return "WI_F64_LE"; - case WI_F64_GE: return "WI_F64_GE"; - case WI_I32_CLZ: return "WI_I32_CLZ"; - case WI_I32_CTZ: return "WI_I32_CTZ"; - case WI_I32_POPCNT: return "WI_I32_POPCNT"; - case WI_I32_ADD: return "WI_I32_ADD"; - case WI_I32_SUB: return "WI_I32_SUB"; - case WI_I32_MUL: return "WI_I32_MUL"; - case WI_I32_DIV_S: return "WI_I32_DIV_S"; - case WI_I32_DIV_U: return "WI_I32_DIV_U"; - case WI_I32_REM_S: return "WI_I32_REM_S"; - case WI_I32_REM_U: return "WI_I32_REM_U"; - case WI_I32_AND: return "WI_I32_AND"; - case WI_I32_OR: return "WI_I32_OR"; - case WI_I32_XOR: return "WI_I32_XOR"; - case WI_I32_SHL: return "WI_I32_SHL"; - case WI_I32_SHR_S: return "WI_I32_SHR_S"; - case WI_I32_SHR_U: return "WI_I32_SHR_U"; - case WI_I32_ROTL: return "WI_I32_ROTL"; - case WI_I32_ROTR: return "WI_I32_ROTR"; - case WI_I64_CLZ: return "WI_I64_CLZ"; - case WI_I64_CTZ: return "WI_I64_CTZ"; - case WI_I64_POPCNT: return "WI_I64_POPCNT"; - case WI_I64_ADD: return "WI_I64_ADD"; - case WI_I64_SUB: return "WI_I64_SUB"; - case WI_I64_MUL: return "WI_I64_MUL"; - case WI_I64_DIV_S: return "WI_I64_DIV_S"; - case WI_I64_DIV_U: return "WI_I64_DIV_U"; - case WI_I64_REM_S: return "WI_I64_REM_S"; - case WI_I64_REM_U: return "WI_I64_REM_U"; - case WI_I64_AND: return "WI_I64_AND"; - case WI_I64_OR: return "WI_I64_OR"; - case WI_I64_XOR: return "WI_I64_XOR"; - case WI_I64_SHL: return "WI_I64_SHL"; - case WI_I64_SHR_S: return "WI_I64_SHR_S"; - case WI_I64_SHR_U: return "WI_I64_SHR_U"; - case WI_I64_ROTL: return "WI_I64_ROTL"; - case WI_I64_ROTR: return "WI_I64_ROTR"; - case WI_F32_ABS: return "WI_F32_ABS"; - case WI_F32_NEG: return "WI_F32_NEG"; - case WI_F32_CEIL: return "WI_F32_CEIL"; - case WI_F32_FLOOR: return "WI_F32_FLOOR"; - case WI_F32_TRUNC: return "WI_F32_TRUNC"; - case WI_F32_NEAREST: return "WI_F32_NEAREST"; - case WI_F32_SQRT: return "WI_F32_SQRT"; - case WI_F32_ADD: return "WI_F32_ADD"; - case WI_F32_SUB: return "WI_F32_SUB"; - case WI_F32_MUL: return "WI_F32_MUL"; - case WI_F32_DIV: return "WI_F32_DIV"; - case WI_F32_MIN: return "WI_F32_MIN"; - case WI_F32_MAX: return "WI_F32_MAX"; - case WI_F32_COPYSIGN: return "WI_F32_COPYSIGN"; - case WI_F64_ABS: return "WI_F64_ABS"; - case WI_F64_NEG: return "WI_F64_NEG"; - case WI_F64_CEIL: return "WI_F64_CEIL"; - case WI_F64_FLOOR: return "WI_F64_FLOOR"; - case WI_F64_TRUNC: return "WI_F64_TRUNC"; - case WI_F64_NEAREST: return "WI_F64_NEAREST"; - case WI_F64_SQRT: return "WI_F64_SQRT"; - case WI_F64_ADD: return "WI_F64_ADD"; - case WI_F64_SUB: return "WI_F64_SUB"; - case WI_F64_MUL: return "WI_F64_MUL"; - case WI_F64_DIV: return "WI_F64_DIV"; - case WI_F64_MIN: return "WI_F64_MIN"; - case WI_F64_MAX: return "WI_F64_MAX"; - case WI_F64_COPYSIGN: return "WI_F64_COPYSIGN"; - case WI_I32_FROM_I64: return "WI_I32_FROM_I64"; - case WI_I32_FROM_F32_S: return "WI_I32_FROM_F32_S"; - case WI_I32_FROM_F32_U: return "WI_I32_FROM_F32_U"; - case WI_I32_FROM_F64_S: return "WI_I32_FROM_F64_S"; - case WI_I32_FROM_F64_U: return "WI_I32_FROM_F64_U"; - case WI_I64_FROM_I32_S: return "WI_I64_FROM_I32_S"; - case WI_I64_FROM_I32_U: return "WI_I64_FROM_I32_U"; - case WI_I64_FROM_F32_S: return "WI_I64_FROM_F32_S"; - case WI_I64_FROM_F32_U: return "WI_I64_FROM_F32_U"; - case WI_I64_FROM_F64_S: return "WI_I64_FROM_F64_S"; - case WI_I64_FROM_F64_U: return "WI_I64_FROM_F64_U"; - case WI_F32_FROM_I32_S: return "WI_F32_FROM_I32_S"; - case WI_F32_FROM_I32_U: return "WI_F32_FROM_I32_U"; - case WI_F32_FROM_I64_S: return "WI_F32_FROM_I64_S"; - case WI_F32_FROM_I64_U: return "WI_F32_FROM_I64_U"; - case WI_F32_FROM_F64: return "WI_F32_FROM_F64"; - case WI_F64_FROM_I32_S: return "WI_F64_FROM_I32_S"; - case WI_F64_FROM_I32_U: return "WI_F64_FROM_I32_U"; - case WI_F64_FROM_I64_S: return "WI_F64_FROM_I64_S"; - case WI_F64_FROM_I64_U: return "WI_F64_FROM_I64_U"; - case WI_F64_FROM_F32: return "WI_F64_FROM_F32"; - case WI_I32_REINTERPRET_F32: return "WI_I32_REINTERPRET_F32"; - case WI_I64_REINTERPRET_F64: return "WI_I64_REINTERPRET_F64"; - case WI_F32_REINTERPRET_I32: return "WI_F32_REINTERPRET_I32"; - case WI_F64_REINTERPRET_I64: return "WI_F64_REINTERPRET_I64"; - } + switch (wit) { + case WI_UNREACHABLE: return "WI_UNREACHABLE"; + case WI_NOP: return "WI_NOP"; + case WI_BLOCK_START: return "WI_BLOCK_START"; + case WI_BLOCK_END: return "WI_BLOCK_END"; + case WI_LOOP_START: return "WI_LOOP_START"; + case WI_IF_START: return "WI_IF_START"; + case WI_ELSE: return "WI_ELSE"; + case WI_JUMP: return "WI_JUMP"; + case WI_COND_JUMP: return "WI_COND_JUMP"; + case WI_JUMP_TABLE: return "WI_JUMP_TABLE"; + case WI_RETURN: return "WI_RETURN"; + case WI_CALL: return "WI_CALL"; + case WI_CALL_INDIRECT: return "WI_CALL_INDIRECT"; + case WI_DROP: return "WI_DROP"; + case WI_SELECT: return "WI_SELECT"; + case WI_LOCAL_GET: return "WI_LOCAL_GET"; + case WI_LOCAL_SET: return "WI_LOCAL_SET"; + case WI_LOCAL_TEE: return "WI_LOCAL_TEE"; + case WI_GLOBAL_GET: return "WI_GLOBAL_GET"; + case WI_GLOBAL_SET: return "WI_GLOBAL_SET"; + case WI_I32_LOAD: return "WI_I32_LOAD"; + case WI_I64_LOAD: return "WI_I64_LOAD"; + case WI_F32_LOAD: return "WI_F32_LOAD"; + case WI_F64_LOAD: return "WI_F64_LOAD"; + case WI_I32_LOAD_8_S: return "WI_I32_LOAD_8_S"; + case WI_I32_LOAD_8_U: return "WI_I32_LOAD_8_U"; + case WI_I32_LOAD_16_S: return "WI_I32_LOAD_16_S"; + case WI_I32_LOAD_16_U: return "WI_I32_LOAD_16_U"; + case WI_I64_LOAD_8_S: return "WI_I64_LOAD_8_S"; + case WI_I64_LOAD_8_U: return "WI_I64_LOAD_8_U"; + case WI_I64_LOAD_16_S: return "WI_I64_LOAD_16_S"; + case WI_I64_LOAD_16_U: return "WI_I64_LOAD_16_U"; + case WI_I64_LOAD_32_S: return "WI_I64_LOAD_32_S"; + case WI_I64_LOAD_32_U: return "WI_I64_LOAD_32_U"; + case WI_I32_STORE: return "WI_I32_STORE"; + case WI_I64_STORE: return "WI_I64_STORE"; + case WI_F32_STORE: return "WI_F32_STORE"; + case WI_F64_STORE: return "WI_F64_STORE"; + case WI_I32_STORE_8: return "WI_I32_STORE_8"; + case WI_I32_STORE_16: return "WI_I32_STORE_16"; + case WI_I64_STORE_8: return "WI_I64_STORE_8"; + case WI_I64_STORE_16: return "WI_I64_STORE_16"; + case WI_I64_STORE_32: return "WI_I64_STORE_32"; + case WI_MEMORY_SIZE: return "WI_MEMORY_SIZE"; + case WI_MEMORY_GROW: return "WI_MEMORY_GROW"; + case WI_I32_CONST: return "WI_I32_CONST"; + case WI_I64_CONST: return "WI_I64_CONST"; + case WI_F32_CONST: return "WI_F32_CONST"; + case WI_F64_CONST: return "WI_F64_CONST"; + case WI_I32_EQZ: return "WI_I32_EQZ"; + case WI_I32_EQ: return "WI_I32_EQ"; + case WI_I32_NE: return "WI_I32_NE"; + case WI_I32_LT_S: return "WI_I32_LT_S"; + case WI_I32_LT_U: return "WI_I32_LT_U"; + case WI_I32_GT_S: return "WI_I32_GT_S"; + case WI_I32_GT_U: return "WI_I32_GT_U"; + case WI_I32_LE_S: return "WI_I32_LE_S"; + case WI_I32_LE_U: return "WI_I32_LE_U"; + case WI_I32_GE_S: return "WI_I32_GE_S"; + case WI_I32_GE_U: return "WI_I32_GE_U"; + case WI_I64_EQZ: return "WI_I64_EQZ"; + case WI_I64_EQ: return "WI_I64_EQ"; + case WI_I64_NE: return "WI_I64_NE"; + case WI_I64_LT_S: return "WI_I64_LT_S"; + case WI_I64_LT_U: return "WI_I64_LT_U"; + case WI_I64_GT_S: return "WI_I64_GT_S"; + case WI_I64_GT_U: return "WI_I64_GT_U"; + case WI_I64_LE_S: return "WI_I64_LE_S"; + case WI_I64_LE_U: return "WI_I64_LE_U"; + case WI_I64_GE_S: return "WI_I64_GE_S"; + case WI_I64_GE_U: return "WI_I64_GE_U"; + case WI_F32_EQ: return "WI_F32_EQ"; + case WI_F32_NE: return "WI_F32_NE"; + case WI_F32_LT: return "WI_F32_LT"; + case WI_F32_GT: return "WI_F32_GT"; + case WI_F32_LE: return "WI_F32_LE"; + case WI_F32_GE: return "WI_F32_GE"; + case WI_F64_EQ: return "WI_F64_EQ"; + case WI_F64_NE: return "WI_F64_NE"; + case WI_F64_LT: return "WI_F64_LT"; + case WI_F64_GT: return "WI_F64_GT"; + case WI_F64_LE: return "WI_F64_LE"; + case WI_F64_GE: return "WI_F64_GE"; + case WI_I32_CLZ: return "WI_I32_CLZ"; + case WI_I32_CTZ: return "WI_I32_CTZ"; + case WI_I32_POPCNT: return "WI_I32_POPCNT"; + case WI_I32_ADD: return "WI_I32_ADD"; + case WI_I32_SUB: return "WI_I32_SUB"; + case WI_I32_MUL: return "WI_I32_MUL"; + case WI_I32_DIV_S: return "WI_I32_DIV_S"; + case WI_I32_DIV_U: return "WI_I32_DIV_U"; + case WI_I32_REM_S: return "WI_I32_REM_S"; + case WI_I32_REM_U: return "WI_I32_REM_U"; + case WI_I32_AND: return "WI_I32_AND"; + case WI_I32_OR: return "WI_I32_OR"; + case WI_I32_XOR: return "WI_I32_XOR"; + case WI_I32_SHL: return "WI_I32_SHL"; + case WI_I32_SHR_S: return "WI_I32_SHR_S"; + case WI_I32_SHR_U: return "WI_I32_SHR_U"; + case WI_I32_ROTL: return "WI_I32_ROTL"; + case WI_I32_ROTR: return "WI_I32_ROTR"; + case WI_I64_CLZ: return "WI_I64_CLZ"; + case WI_I64_CTZ: return "WI_I64_CTZ"; + case WI_I64_POPCNT: return "WI_I64_POPCNT"; + case WI_I64_ADD: return "WI_I64_ADD"; + case WI_I64_SUB: return "WI_I64_SUB"; + case WI_I64_MUL: return "WI_I64_MUL"; + case WI_I64_DIV_S: return "WI_I64_DIV_S"; + case WI_I64_DIV_U: return "WI_I64_DIV_U"; + case WI_I64_REM_S: return "WI_I64_REM_S"; + case WI_I64_REM_U: return "WI_I64_REM_U"; + case WI_I64_AND: return "WI_I64_AND"; + case WI_I64_OR: return "WI_I64_OR"; + case WI_I64_XOR: return "WI_I64_XOR"; + case WI_I64_SHL: return "WI_I64_SHL"; + case WI_I64_SHR_S: return "WI_I64_SHR_S"; + case WI_I64_SHR_U: return "WI_I64_SHR_U"; + case WI_I64_ROTL: return "WI_I64_ROTL"; + case WI_I64_ROTR: return "WI_I64_ROTR"; + case WI_F32_ABS: return "WI_F32_ABS"; + case WI_F32_NEG: return "WI_F32_NEG"; + case WI_F32_CEIL: return "WI_F32_CEIL"; + case WI_F32_FLOOR: return "WI_F32_FLOOR"; + case WI_F32_TRUNC: return "WI_F32_TRUNC"; + case WI_F32_NEAREST: return "WI_F32_NEAREST"; + case WI_F32_SQRT: return "WI_F32_SQRT"; + case WI_F32_ADD: return "WI_F32_ADD"; + case WI_F32_SUB: return "WI_F32_SUB"; + case WI_F32_MUL: return "WI_F32_MUL"; + case WI_F32_DIV: return "WI_F32_DIV"; + case WI_F32_MIN: return "WI_F32_MIN"; + case WI_F32_MAX: return "WI_F32_MAX"; + case WI_F32_COPYSIGN: return "WI_F32_COPYSIGN"; + case WI_F64_ABS: return "WI_F64_ABS"; + case WI_F64_NEG: return "WI_F64_NEG"; + case WI_F64_CEIL: return "WI_F64_CEIL"; + case WI_F64_FLOOR: return "WI_F64_FLOOR"; + case WI_F64_TRUNC: return "WI_F64_TRUNC"; + case WI_F64_NEAREST: return "WI_F64_NEAREST"; + case WI_F64_SQRT: return "WI_F64_SQRT"; + case WI_F64_ADD: return "WI_F64_ADD"; + case WI_F64_SUB: return "WI_F64_SUB"; + case WI_F64_MUL: return "WI_F64_MUL"; + case WI_F64_DIV: return "WI_F64_DIV"; + case WI_F64_MIN: return "WI_F64_MIN"; + case WI_F64_MAX: return "WI_F64_MAX"; + case WI_F64_COPYSIGN: return "WI_F64_COPYSIGN"; + case WI_I32_FROM_I64: return "WI_I32_FROM_I64"; + case WI_I32_FROM_F32_S: return "WI_I32_FROM_F32_S"; + case WI_I32_FROM_F32_U: return "WI_I32_FROM_F32_U"; + case WI_I32_FROM_F64_S: return "WI_I32_FROM_F64_S"; + case WI_I32_FROM_F64_U: return "WI_I32_FROM_F64_U"; + case WI_I64_FROM_I32_S: return "WI_I64_FROM_I32_S"; + case WI_I64_FROM_I32_U: return "WI_I64_FROM_I32_U"; + case WI_I64_FROM_F32_S: return "WI_I64_FROM_F32_S"; + case WI_I64_FROM_F32_U: return "WI_I64_FROM_F32_U"; + case WI_I64_FROM_F64_S: return "WI_I64_FROM_F64_S"; + case WI_I64_FROM_F64_U: return "WI_I64_FROM_F64_U"; + case WI_F32_FROM_I32_S: return "WI_F32_FROM_I32_S"; + case WI_F32_FROM_I32_U: return "WI_F32_FROM_I32_U"; + case WI_F32_FROM_I64_S: return "WI_F32_FROM_I64_S"; + case WI_F32_FROM_I64_U: return "WI_F32_FROM_I64_U"; + case WI_F32_FROM_F64: return "WI_F32_FROM_F64"; + case WI_F64_FROM_I32_S: return "WI_F64_FROM_I32_S"; + case WI_F64_FROM_I32_U: return "WI_F64_FROM_I32_U"; + case WI_F64_FROM_I64_S: return "WI_F64_FROM_I64_S"; + case WI_F64_FROM_I64_U: return "WI_F64_FROM_I64_U"; + case WI_F64_FROM_F32: return "WI_F64_FROM_F32"; + case WI_I32_REINTERPRET_F32: return "WI_I32_REINTERPRET_F32"; + case WI_I64_REINTERPRET_F64: return "WI_I64_REINTERPRET_F64"; + case WI_F32_REINTERPRET_I32: return "WI_F32_REINTERPRET_I32"; + case WI_F64_REINTERPRET_I64: return "WI_F64_REINTERPRET_I64"; + } } static WasmType onyx_type_to_wasm_type(OnyxTypeInfo* type) { - if (type->is_bool) return WASM_TYPE_INT32; - else if (type->is_int) { - if (type->size == 4) return WASM_TYPE_INT32; - if (type->size == 8) return WASM_TYPE_INT64; - } - else if (type->is_float) { - if (type->size == 4) return WASM_TYPE_FLOAT32; - if (type->size == 8) return WASM_TYPE_FLOAT64; - } - - return WASM_TYPE_VOID; + if (type->is_bool) return WASM_TYPE_INT32; + else if (type->is_int) { + if (type->size == 4) return WASM_TYPE_INT32; + if (type->size == 8) return WASM_TYPE_INT64; + } + else if (type->is_float) { + if (type->size == 4) return WASM_TYPE_FLOAT32; + if (type->size == 8) return WASM_TYPE_FLOAT64; + } + + return WASM_TYPE_VOID; } static void compile_function_body(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNodeFuncDef* fd); @@ -222,47 +222,47 @@ static void compile_cast(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNodeUnaryOp static void compile_return(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNode* ret); static void compile_function_body(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNodeFuncDef* fd) { - if (fd->body == NULL) return; + if (fd->body == NULL) return; - forll (OnyxAstNode, stmt, fd->body->body, next) { - compile_statement(mod, func, stmt); - } + forll (OnyxAstNode, stmt, fd->body->body, next) { + compile_statement(mod, func, stmt); + } - bh_arr_push(func->code, ((WasmInstruction){ WI_BLOCK_END, 0x00 })); + bh_arr_push(func->code, ((WasmInstruction){ WI_BLOCK_END, 0x00 })); } static void compile_block(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNodeBlock* block) { - bh_arr_push(func->code, ((WasmInstruction){ WI_BLOCK_START, 0x40 })); + bh_arr_push(func->code, ((WasmInstruction){ WI_BLOCK_START, 0x40 })); - forll (OnyxAstNode, stmt, block->body, next) { - compile_statement(mod, func, stmt); - } + forll (OnyxAstNode, stmt, block->body, next) { + compile_statement(mod, func, stmt); + } - bh_arr_push(func->code, ((WasmInstruction){ WI_BLOCK_END, 0x00 })); + bh_arr_push(func->code, ((WasmInstruction){ WI_BLOCK_END, 0x00 })); } static void compile_statement(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNode* stmt) { - switch (stmt->kind) { - case ONYX_AST_NODE_KIND_SCOPE: break; - case ONYX_AST_NODE_KIND_RETURN: compile_return(mod, func, stmt); break; - case ONYX_AST_NODE_KIND_ASSIGNMENT: compile_assignment(mod, func, stmt); break; + switch (stmt->kind) { + case ONYX_AST_NODE_KIND_SCOPE: break; + case ONYX_AST_NODE_KIND_RETURN: compile_return(mod, func, stmt); break; + 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_CALL: compile_expression(mod, func, stmt); break; case ONYX_AST_NODE_KIND_BLOCK: compile_block(mod, func, (OnyxAstNodeBlock *) stmt); break; - default: break; - } + default: break; + } } static void compile_assign_lval(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNode* lval) { - if (lval->kind == ONYX_AST_NODE_KIND_LOCAL || lval->kind == ONYX_AST_NODE_KIND_PARAM) { - i32 localidx = (i32) bh_imap_get(&mod->local_map, (u64) lval); + if (lval->kind == ONYX_AST_NODE_KIND_LOCAL || lval->kind == ONYX_AST_NODE_KIND_PARAM) { + i32 localidx = (i32) bh_imap_get(&mod->local_map, (u64) lval); - bh_arr_push(func->code, ((WasmInstruction){ WI_LOCAL_SET, localidx })); - } else { - assert(("Invalid lval", 0)); - } + bh_arr_push(func->code, ((WasmInstruction){ WI_LOCAL_SET, localidx })); + } else { + assert(("Invalid lval", 0)); + } } static void compile_if(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNodeIf* if_node) { @@ -308,9 +308,9 @@ 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 })); - forll (OnyxAstNode, stmt, while_node->body->body, next) { - compile_statement(mod, func, stmt); - } + forll (OnyxAstNode, stmt, while_node->body->body, next) { + compile_statement(mod, func, stmt); + } bh_arr_push(func->code, ((WasmInstruction){ WI_JUMP, 0x00 })); @@ -319,8 +319,8 @@ static void compile_while(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNodeWhile* } static void compile_assignment(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNode* assign) { - compile_expression(mod, func, assign->right); - compile_assign_lval(mod, func, assign->left); + compile_expression(mod, func, assign->right); + compile_assign_lval(mod, func, assign->left); } // NOTE: These need to be in the same order as @@ -417,7 +417,7 @@ static void compile_unaryop(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNodeUnar } static void compile_expression(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNode* expr) { - switch (expr->kind) { + switch (expr->kind) { case ONYX_AST_NODE_KIND_BIN_OP: compile_binop(mod, func, &expr->as_binop); break; @@ -426,17 +426,17 @@ static void compile_expression(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNode* compile_unaryop(mod, func, &expr->as_unaryop); break; - case ONYX_AST_NODE_KIND_LOCAL: - case ONYX_AST_NODE_KIND_PARAM: - { - i32 localidx = (i32) bh_imap_get(&mod->local_map, (u64) expr); + case ONYX_AST_NODE_KIND_LOCAL: + case ONYX_AST_NODE_KIND_PARAM: + { + i32 localidx = (i32) bh_imap_get(&mod->local_map, (u64) expr); - bh_arr_push(func->code, ((WasmInstruction){ WI_LOCAL_GET, localidx })); - break; - } + bh_arr_push(func->code, ((WasmInstruction){ WI_LOCAL_GET, localidx })); + break; + } - case ONYX_AST_NODE_KIND_LITERAL: - { + case ONYX_AST_NODE_KIND_LITERAL: + { OnyxAstNodeNumLit* lit = &expr->as_numlit; WasmType lit_type = onyx_type_to_wasm_type(lit->type); WasmInstruction instr = { WI_NOP, 0 }; @@ -455,121 +455,121 @@ static void compile_expression(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNode* instr.data.d = lit->value.d; } - bh_arr_push(func->code, instr); - break; - } + bh_arr_push(func->code, instr); + break; + } - case ONYX_AST_NODE_KIND_BLOCK: compile_block(mod, func, (OnyxAstNodeBlock *) expr); break; + case ONYX_AST_NODE_KIND_BLOCK: compile_block(mod, func, (OnyxAstNodeBlock *) expr); break; - case ONYX_AST_NODE_KIND_CALL: - { - OnyxAstNodeCall* call = &expr->as_call; - forll (OnyxAstNode, arg, call->arguments, next) { - compile_expression(mod, func, arg->left); - } + case ONYX_AST_NODE_KIND_CALL: + { + OnyxAstNodeCall* call = &expr->as_call; + forll (OnyxAstNode, arg, call->arguments, next) { + compile_expression(mod, func, arg->left); + } i32 func_idx = (i32) bh_imap_get(&mod->func_map, (u64) call->callee); bh_arr_push(func->code, ((WasmInstruction){ WI_CALL, func_idx })); - break; - } + break; + } - default: - DEBUG_HERE; - bh_printf("Unhandled case: %d\n", expr->kind); - assert(0); - } + default: + DEBUG_HERE; + bh_printf("Unhandled case: %d\n", expr->kind); + assert(0); + } } static const WasmInstructionType cast_map[][6] = { - // I32 U32 I64 U64 F32 F64 - /* I32 */ { WI_NOP, WI_NOP, WI_I64_FROM_I32_S, WI_I64_FROM_I32_S, WI_F32_FROM_I32_S, WI_F64_FROM_I32_S }, - /* U32 */ { WI_NOP, WI_NOP, WI_I64_FROM_I32_U, WI_I64_FROM_I32_U, WI_F32_FROM_I32_U, WI_F64_FROM_I32_U }, - /* I64 */ { WI_I32_FROM_I64, WI_I32_FROM_I64, WI_NOP, WI_NOP, WI_F32_FROM_I64_S, WI_F64_FROM_I64_S }, - /* U64 */ { WI_I32_FROM_I64, WI_I32_FROM_I64, WI_NOP, WI_NOP, WI_F32_FROM_I64_U, WI_F64_FROM_I64_U }, - /* F32 */ { WI_I32_FROM_F32_S, WI_I32_FROM_F32_U, WI_I64_FROM_F32_S, WI_I64_FROM_F32_U, WI_NOP, WI_F64_FROM_F32 }, - /* F64 */ { WI_I32_FROM_F64_S, WI_I32_FROM_F64_U, WI_I64_FROM_F64_S, WI_I64_FROM_F64_U, WI_F32_FROM_F64, WI_NOP, }, + // I32 U32 I64 U64 F32 F64 + /* I32 */ { WI_NOP, WI_NOP, WI_I64_FROM_I32_S, WI_I64_FROM_I32_S, WI_F32_FROM_I32_S, WI_F64_FROM_I32_S }, + /* U32 */ { WI_NOP, WI_NOP, WI_I64_FROM_I32_U, WI_I64_FROM_I32_U, WI_F32_FROM_I32_U, WI_F64_FROM_I32_U }, + /* I64 */ { WI_I32_FROM_I64, WI_I32_FROM_I64, WI_NOP, WI_NOP, WI_F32_FROM_I64_S, WI_F64_FROM_I64_S }, + /* U64 */ { WI_I32_FROM_I64, WI_I32_FROM_I64, WI_NOP, WI_NOP, WI_F32_FROM_I64_U, WI_F64_FROM_I64_U }, + /* F32 */ { WI_I32_FROM_F32_S, WI_I32_FROM_F32_U, WI_I64_FROM_F32_S, WI_I64_FROM_F32_U, WI_NOP, WI_F64_FROM_F32 }, + /* F64 */ { WI_I32_FROM_F64_S, WI_I32_FROM_F64_U, WI_I64_FROM_F64_S, WI_I64_FROM_F64_U, WI_F32_FROM_F64, WI_NOP, }, }; static void compile_cast(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNodeUnaryOp* cast) { - compile_expression(mod, func, cast->left); - - OnyxTypeInfo* from = cast->left->type; - OnyxTypeInfo* to = cast->type; - - i32 fromidx = 0, toidx = 0; - if (from->is_int) { - if (from->size == 4 && !from->is_unsigned) fromidx = 0; - else if (from->size == 4 && from->is_unsigned) fromidx = 1; - else if (from->size == 8 && !from->is_unsigned) fromidx = 2; - else if (from->size == 8 && from->is_unsigned) fromidx = 3; - } else if (from->is_float) { - if (from->size == 4) fromidx = 4; - else if (from->size == 8) fromidx = 5; - } - - if (to->is_int) { - if (to->size == 4 && !to->is_unsigned) toidx = 0; - else if (to->size == 4 && to->is_unsigned) toidx = 1; - else if (to->size == 8 && !to->is_unsigned) toidx = 2; - else if (to->size == 8 && to->is_unsigned) toidx = 3; - } else if (to->is_float) { - if (to->size == 4) toidx = 4; - else if (to->size == 8) toidx = 5; - } - - WasmInstructionType cast_op = cast_map[fromidx][toidx]; - if (cast_op != WI_NOP) { - bh_arr_push(func->code, ((WasmInstruction){ cast_op, 0x00 })); - } + compile_expression(mod, func, cast->left); + + OnyxTypeInfo* from = cast->left->type; + OnyxTypeInfo* to = cast->type; + + i32 fromidx = 0, toidx = 0; + if (from->is_int) { + if (from->size == 4 && !from->is_unsigned) fromidx = 0; + else if (from->size == 4 && from->is_unsigned) fromidx = 1; + else if (from->size == 8 && !from->is_unsigned) fromidx = 2; + else if (from->size == 8 && from->is_unsigned) fromidx = 3; + } else if (from->is_float) { + if (from->size == 4) fromidx = 4; + else if (from->size == 8) fromidx = 5; + } + + if (to->is_int) { + if (to->size == 4 && !to->is_unsigned) toidx = 0; + else if (to->size == 4 && to->is_unsigned) toidx = 1; + else if (to->size == 8 && !to->is_unsigned) toidx = 2; + else if (to->size == 8 && to->is_unsigned) toidx = 3; + } else if (to->is_float) { + if (to->size == 4) toidx = 4; + else if (to->size == 8) toidx = 5; + } + + WasmInstructionType cast_op = cast_map[fromidx][toidx]; + if (cast_op != WI_NOP) { + bh_arr_push(func->code, ((WasmInstruction){ cast_op, 0x00 })); + } } static void compile_return(OnyxWasmModule* mod, WasmFunc* func, OnyxAstNode* ret) { - if (ret->left) { - compile_expression(mod, func, ret->left); - } + if (ret->left) { + compile_expression(mod, func, ret->left); + } - bh_arr_push(func->code, ((WasmInstruction){ WI_RETURN, 0x00 })); + bh_arr_push(func->code, ((WasmInstruction){ WI_RETURN, 0x00 })); } static i32 generate_type_idx(OnyxWasmModule* mod, OnyxAstNodeFuncDef* fd) { - static char type_repr_buf[128]; - - char* t = type_repr_buf; - OnyxAstNodeParam* param = fd->params; - i32 param_count = 0; - while (param) { - // HACK: Using these directly as part of a string feels weird but they are - // valid characters so I don't think it is going to be much of an issue - *(t++) = (char) onyx_type_to_wasm_type(param->type); - param_count++; - param = param->next; - } - *(t++) = ':'; - - WasmType return_type = onyx_type_to_wasm_type(fd->return_type); - *(t++) = (char) return_type; - *t = '\0'; - - i32 type_idx = 0; - if (bh_table_has(i32, mod->type_map, type_repr_buf)) { - type_idx = bh_table_get(i32, mod->type_map, type_repr_buf); - } else { - // NOTE: Make a new type - // TODO: Ensure that this isn't going to break things because of alignment - WasmFuncType* type = (WasmFuncType*) bh_alloc(mod->allocator, sizeof(WasmFuncType) + sizeof(WasmType) * param_count); - type->return_type = return_type; - type->param_count = param_count; - - // HACK ish thing - memcpy(type->param_types, type_repr_buf, type->param_count); - - bh_arr_push(mod->functypes, type); - - bh_table_put(i32, mod->type_map, type_repr_buf, mod->next_type_idx); - type_idx = mod->next_type_idx; - mod->next_type_idx++; - } + static char type_repr_buf[128]; + + char* t = type_repr_buf; + OnyxAstNodeParam* param = fd->params; + i32 param_count = 0; + while (param) { + // HACK: Using these directly as part of a string feels weird but they are + // valid characters so I don't think it is going to be much of an issue + *(t++) = (char) onyx_type_to_wasm_type(param->type); + param_count++; + param = param->next; + } + *(t++) = ':'; + + WasmType return_type = onyx_type_to_wasm_type(fd->return_type); + *(t++) = (char) return_type; + *t = '\0'; + + i32 type_idx = 0; + if (bh_table_has(i32, mod->type_map, type_repr_buf)) { + type_idx = bh_table_get(i32, mod->type_map, type_repr_buf); + } else { + // NOTE: Make a new type + // TODO: Ensure that this isn't going to break things because of alignment + WasmFuncType* type = (WasmFuncType*) bh_alloc(mod->allocator, sizeof(WasmFuncType) + sizeof(WasmType) * param_count); + type->return_type = return_type; + type->param_count = param_count; + + // HACK ish thing + memcpy(type->param_types, type_repr_buf, type->param_count); + + bh_arr_push(mod->functypes, type); + + bh_table_put(i32, mod->type_map, type_repr_buf, mod->next_type_idx); + type_idx = mod->next_type_idx; + mod->next_type_idx++; + } return type_idx; } @@ -577,34 +577,34 @@ static i32 generate_type_idx(OnyxWasmModule* mod, OnyxAstNodeFuncDef* fd) { static void compile_function_definition(OnyxWasmModule* mod, OnyxAstNodeFuncDef* fd) { i32 type_idx = generate_type_idx(mod, fd); - WasmFunc wasm_func = { - .type_idx = type_idx, - .locals = { - .i32_count = 0, - .i64_count = 0, - .f32_count = 0, - .f64_count = 0, - }, - .code = NULL, - }; + WasmFunc wasm_func = { + .type_idx = type_idx, + .locals = { + .i32_count = 0, + .i64_count = 0, + .f32_count = 0, + .f64_count = 0, + }, + .code = NULL, + }; - if (fd->flags & ONYX_AST_FLAG_EXPORTED) { - onyx_token_null_toggle(*fd->token); + if (fd->flags & ONYX_AST_FLAG_EXPORTED) { + onyx_token_null_toggle(*fd->token); i32 func_idx = (i32) bh_imap_get(&mod->func_map, (u64) fd); - WasmExport wasm_export = { - .kind = WASM_FOREIGN_FUNCTION, - .idx = func_idx, - }; - bh_table_put(WasmExport, mod->exports, fd->token->token, wasm_export); - mod->export_count++; + WasmExport wasm_export = { + .kind = WASM_FOREIGN_FUNCTION, + .idx = func_idx, + }; + bh_table_put(WasmExport, mod->exports, fd->token->token, wasm_export); + mod->export_count++; - onyx_token_null_toggle(*fd->token); - } + onyx_token_null_toggle(*fd->token); + } - // If there is no body then don't process the code - if (fd->body != NULL) { + // If there is no body then don't process the code + if (fd->body != NULL) { // NOTE: Generate the local map i32 localidx = 0; forll (OnyxAstNodeParam, param, fd->params, next) { @@ -635,10 +635,10 @@ static void compile_function_definition(OnyxWasmModule* mod, OnyxAstNodeFuncDef* bh_arr_push(wasm_func.code, ((WasmInstruction){ WI_BLOCK_END, 0x00 })); } - bh_arr_push(mod->funcs, wasm_func); + bh_arr_push(mod->funcs, wasm_func); - // NOTE: Clear the local map on exit of generating this function - bh_imap_clear(&mod->local_map); + // NOTE: Clear the local map on exit of generating this function + bh_imap_clear(&mod->local_map); } static void compile_foreign(OnyxWasmModule* module, OnyxAstNodeForeign* foreign) { @@ -662,38 +662,38 @@ static void compile_foreign(OnyxWasmModule* module, OnyxAstNodeForeign* foreign) } OnyxWasmModule onyx_wasm_module_create(bh_allocator alloc) { - OnyxWasmModule module = { - .allocator = alloc, + OnyxWasmModule module = { + .allocator = alloc, - .type_map = NULL, - .next_type_idx = 0, - .functypes = NULL, + .type_map = NULL, + .next_type_idx = 0, + .functypes = NULL, - .funcs = NULL, - .next_func_idx = 0, + .funcs = NULL, + .next_func_idx = 0, - .exports = NULL, - .export_count = 0, + .exports = NULL, + .export_count = 0, .imports = NULL, .next_import_func_idx = 0, - }; + }; - bh_arr_new(alloc, module.functypes, 4); - bh_arr_new(alloc, module.funcs, 4); + bh_arr_new(alloc, module.functypes, 4); + bh_arr_new(alloc, module.funcs, 4); bh_arr_new(alloc, module.imports, 4); - bh_table_init(bh_heap_allocator(), module.type_map, 61); - bh_table_init(bh_heap_allocator(), module.exports, 61); + bh_table_init(bh_heap_allocator(), module.type_map, 61); + bh_table_init(bh_heap_allocator(), module.exports, 61); - bh_imap_init(&module.local_map, bh_heap_allocator()); + bh_imap_init(&module.local_map, bh_heap_allocator()); bh_imap_init(&module.func_map, bh_heap_allocator()); return module; } void onyx_wasm_module_compile(OnyxWasmModule* module, OnyxAstNodeFile* program) { - OnyxAstNode* walker; + OnyxAstNode* walker; OnyxAstNodeFile* top_walker = program; while (top_walker) { @@ -735,7 +735,7 @@ void onyx_wasm_module_compile(OnyxWasmModule* module, OnyxAstNodeFile* program) top_walker = top_walker->next; } - top_walker = program; + top_walker = program; while (top_walker) { walker = top_walker->contents; @@ -758,12 +758,12 @@ void onyx_wasm_module_compile(OnyxWasmModule* module, OnyxAstNodeFile* program) } void onyx_wasm_module_free(OnyxWasmModule* module) { - bh_arr_free(module->functypes); - bh_arr_free(module->funcs); - bh_imap_free(&module->local_map); + bh_arr_free(module->functypes); + bh_arr_free(module->funcs); + bh_imap_free(&module->local_map); bh_imap_free(&module->func_map); - bh_table_free(module->type_map); - bh_table_free(module->exports); + bh_table_free(module->type_map); + bh_table_free(module->exports); } @@ -791,18 +791,18 @@ static const u8 WASM_MAGIC_STRING[] = { 0x00, 0x61, 0x73, 0x6D }; static const u8 WASM_VERSION[] = { 0x01, 0x00, 0x00, 0x00 }; static i32 output_vector(void** arr, i32 stride, i32 arrlen, vector_func elem, bh_buffer* vec_buff) { - i32 len; - u8* leb = uint_to_uleb128((u64) arrlen, &len); - bh_buffer_append(vec_buff, leb, len); - - i32 i = 0; - while (i < arrlen) { - elem(*arr, vec_buff); - arr = bh_pointer_add(arr, stride); - i++; - } - - return vec_buff->length; + i32 len; + u8* leb = uint_to_uleb128((u64) arrlen, &len); + bh_buffer_append(vec_buff, leb, len); + + i32 i = 0; + while (i < arrlen) { + elem(*arr, vec_buff); + arr = bh_pointer_add(arr, stride); + i++; + } + + return vec_buff->length; } static i32 output_name(const char* start, i32 length, bh_buffer* buff) { @@ -814,84 +814,84 @@ static i32 output_name(const char* start, i32 length, bh_buffer* buff) { } static i32 output_functype(WasmFuncType* type, bh_buffer* buff) { - i32 prev_len = buff->length; + i32 prev_len = buff->length; - bh_buffer_write_byte(buff, 0x60); + bh_buffer_write_byte(buff, 0x60); - i32 len; - u8* leb_buff = uint_to_uleb128(type->param_count, &len); - bh_buffer_append(buff, leb_buff, len); - bh_buffer_append(buff, type->param_types, type->param_count); + i32 len; + u8* leb_buff = uint_to_uleb128(type->param_count, &len); + bh_buffer_append(buff, leb_buff, len); + bh_buffer_append(buff, type->param_types, type->param_count); - if (type->return_type != WASM_TYPE_VOID) { - bh_buffer_write_byte(buff, 0x01); - bh_buffer_write_byte(buff, type->return_type); - } else { - bh_buffer_write_byte(buff, 0x00); - } + if (type->return_type != WASM_TYPE_VOID) { + bh_buffer_write_byte(buff, 0x01); + bh_buffer_write_byte(buff, type->return_type); + } else { + bh_buffer_write_byte(buff, 0x00); + } - return buff->length - prev_len; + return buff->length - prev_len; } static i32 output_typesection(OnyxWasmModule* module, bh_buffer* buff) { - i32 prev_len = buff->length; - bh_buffer_write_byte(buff, 0x01); + i32 prev_len = buff->length; + bh_buffer_write_byte(buff, 0x01); - bh_buffer vec_buff; - bh_buffer_init(&vec_buff, buff->allocator, 128); + bh_buffer vec_buff; + bh_buffer_init(&vec_buff, buff->allocator, 128); - i32 vec_len = output_vector( - (void**) module->functypes, - sizeof(WasmFuncType*), - bh_arr_length(module->functypes), - (vector_func *) output_functype, - &vec_buff); + i32 vec_len = output_vector( + (void**) module->functypes, + sizeof(WasmFuncType*), + bh_arr_length(module->functypes), + (vector_func *) output_functype, + &vec_buff); - i32 leb_len; - u8* leb = uint_to_uleb128((u64) vec_len, &leb_len); - bh_buffer_append(buff, leb, leb_len); + i32 leb_len; + u8* leb = uint_to_uleb128((u64) vec_len, &leb_len); + bh_buffer_append(buff, leb, leb_len); - bh_buffer_concat(buff, vec_buff); - bh_buffer_free(&vec_buff); + bh_buffer_concat(buff, vec_buff); + bh_buffer_free(&vec_buff); - return buff->length - prev_len; + return buff->length - prev_len; } static i32 output_funcsection(OnyxWasmModule* module, bh_buffer* buff) { - i32 prev_len = buff->length; - bh_buffer_write_byte(buff, WASM_SECTION_ID_FUNCTION); + i32 prev_len = buff->length; + bh_buffer_write_byte(buff, WASM_SECTION_ID_FUNCTION); - bh_buffer vec_buff; - bh_buffer_init(&vec_buff, buff->allocator, 128); + bh_buffer vec_buff; + bh_buffer_init(&vec_buff, buff->allocator, 128); - i32 leb_len; - u8* leb = uint_to_uleb128((u64) (bh_arr_length(module->funcs)), &leb_len); - bh_buffer_append(&vec_buff, leb, leb_len); + i32 leb_len; + u8* leb = uint_to_uleb128((u64) (bh_arr_length(module->funcs)), &leb_len); + bh_buffer_append(&vec_buff, leb, leb_len); - bh_arr_each(WasmFunc, func, module->funcs) { - leb = uint_to_uleb128((u64) (func->type_idx), &leb_len); - bh_buffer_append(&vec_buff, leb, leb_len); - } + bh_arr_each(WasmFunc, func, module->funcs) { + leb = uint_to_uleb128((u64) (func->type_idx), &leb_len); + bh_buffer_append(&vec_buff, leb, leb_len); + } - leb = uint_to_uleb128((u64) (vec_buff.length), &leb_len); - bh_buffer_append(buff, leb, leb_len); + leb = uint_to_uleb128((u64) (vec_buff.length), &leb_len); + bh_buffer_append(buff, leb, leb_len); - bh_buffer_concat(buff, vec_buff); - bh_buffer_free(&vec_buff); + bh_buffer_concat(buff, vec_buff); + bh_buffer_free(&vec_buff); - return buff->length - prev_len; + return buff->length - prev_len; } static i32 output_importsection(OnyxWasmModule* module, bh_buffer* buff) { - i32 prev_len = buff->length; - bh_buffer_write_byte(buff, WASM_SECTION_ID_IMPORT); + i32 prev_len = buff->length; + bh_buffer_write_byte(buff, WASM_SECTION_ID_IMPORT); - bh_buffer vec_buff; - bh_buffer_init(&vec_buff, buff->allocator, 128); + bh_buffer vec_buff; + bh_buffer_init(&vec_buff, buff->allocator, 128); - i32 leb_len; - u8* leb = uint_to_uleb128((u64) (bh_arr_length(module->imports)), &leb_len); - bh_buffer_append(&vec_buff, leb, leb_len); + i32 leb_len; + u8* leb = uint_to_uleb128((u64) (bh_arr_length(module->imports)), &leb_len); + bh_buffer_append(&vec_buff, leb, leb_len); bh_arr_each(WasmImport, import, module->imports) { output_name(import->mod->token, import->mod->length, &vec_buff); @@ -902,209 +902,209 @@ static i32 output_importsection(OnyxWasmModule* module, bh_buffer* buff) { bh_buffer_append(&vec_buff, leb, leb_len); } - leb = uint_to_uleb128((u64) (vec_buff.length), &leb_len); - bh_buffer_append(buff, leb, leb_len); + leb = uint_to_uleb128((u64) (vec_buff.length), &leb_len); + bh_buffer_append(buff, leb, leb_len); - bh_buffer_concat(buff, vec_buff); - bh_buffer_free(&vec_buff); + bh_buffer_concat(buff, vec_buff); + bh_buffer_free(&vec_buff); - return buff->length - prev_len; + return buff->length - prev_len; } static i32 output_exportsection(OnyxWasmModule* module, bh_buffer* buff) { - i32 prev_len = buff->length; - bh_buffer_write_byte(buff, WASM_SECTION_ID_EXPORT); + i32 prev_len = buff->length; + bh_buffer_write_byte(buff, WASM_SECTION_ID_EXPORT); - bh_buffer vec_buff; - bh_buffer_init(&vec_buff, buff->allocator, 128); + bh_buffer vec_buff; + bh_buffer_init(&vec_buff, buff->allocator, 128); - i32 leb_len; - u8* leb = uint_to_uleb128((u64) (module->export_count), &leb_len); - bh_buffer_append(&vec_buff, leb, leb_len); + i32 leb_len; + u8* leb = uint_to_uleb128((u64) (module->export_count), &leb_len); + bh_buffer_append(&vec_buff, leb, leb_len); - i32 key_len = 0; - bh_table_each_start(WasmExport, module->exports); - key_len = strlen(key); + i32 key_len = 0; + bh_table_each_start(WasmExport, module->exports); + key_len = strlen(key); output_name(key, key_len, &vec_buff); - bh_buffer_write_byte(&vec_buff, (u8) (value.kind)); - leb = uint_to_uleb128((u64) value.idx, &leb_len); - bh_buffer_append(&vec_buff, leb, leb_len); - bh_table_each_end; + bh_buffer_write_byte(&vec_buff, (u8) (value.kind)); + leb = uint_to_uleb128((u64) value.idx, &leb_len); + bh_buffer_append(&vec_buff, leb, leb_len); + bh_table_each_end; - leb = uint_to_uleb128((u64) (vec_buff.length), &leb_len); - bh_buffer_append(buff, leb, leb_len); + leb = uint_to_uleb128((u64) (vec_buff.length), &leb_len); + bh_buffer_append(buff, leb, leb_len); - bh_buffer_concat(buff, vec_buff); - bh_buffer_free(&vec_buff); + bh_buffer_concat(buff, vec_buff); + bh_buffer_free(&vec_buff); - return buff->length - prev_len; + return buff->length - prev_len; } static i32 output_startsection(OnyxWasmModule* module, bh_buffer* buff) { - i32 prev_len = buff->length; - - i32 start_idx = -1; - bh_table_each_start(WasmExport, module->exports) { - if (value.kind == WASM_FOREIGN_FUNCTION) { - if (strncmp("main", key, 5) == 0) { - start_idx = value.idx; - break; - } - } - } bh_table_each_end; - - if (start_idx != -1) { - bh_buffer_write_byte(buff, WASM_SECTION_ID_START); - - i32 start_leb_len, section_leb_len; - uint_to_uleb128((u64) start_idx, &start_leb_len); - u8* section_leb = uint_to_uleb128((u64) start_leb_len, §ion_leb_len); - bh_buffer_append(buff, section_leb, section_leb_len); - - u8* start_leb = uint_to_uleb128((u64) start_idx, &start_leb_len); - bh_buffer_append(buff, start_leb, start_leb_len); - } - - return buff->length - prev_len; + i32 prev_len = buff->length; + + i32 start_idx = -1; + bh_table_each_start(WasmExport, module->exports) { + if (value.kind == WASM_FOREIGN_FUNCTION) { + if (strncmp("main", key, 5) == 0) { + start_idx = value.idx; + break; + } + } + } bh_table_each_end; + + if (start_idx != -1) { + bh_buffer_write_byte(buff, WASM_SECTION_ID_START); + + i32 start_leb_len, section_leb_len; + uint_to_uleb128((u64) start_idx, &start_leb_len); + u8* section_leb = uint_to_uleb128((u64) start_leb_len, §ion_leb_len); + bh_buffer_append(buff, section_leb, section_leb_len); + + u8* start_leb = uint_to_uleb128((u64) start_idx, &start_leb_len); + bh_buffer_append(buff, start_leb, start_leb_len); + } + + return buff->length - prev_len; } static i32 output_locals(WasmFunc* func, bh_buffer* buff) { - i32 prev_len = buff->length; - - // NOTE: Output vector length - i32 total_locals = - (i32) (func->locals.i32_count != 0) + - (i32) (func->locals.i64_count != 0) + - (i32) (func->locals.f32_count != 0) + - (i32) (func->locals.f64_count != 0); - - i32 leb_len; - u8* leb = uint_to_uleb128((u64) total_locals, &leb_len); - bh_buffer_append(buff, leb, leb_len); - - if (func->locals.i32_count != 0) { - leb = uint_to_uleb128((u64) func->locals.i32_count, &leb_len); - bh_buffer_append(buff, leb, leb_len); - bh_buffer_write_byte(buff, WASM_TYPE_INT32); - } - if (func->locals.i64_count != 0) { - leb = uint_to_uleb128((u64) func->locals.i64_count, &leb_len); - bh_buffer_append(buff, leb, leb_len); - bh_buffer_write_byte(buff, WASM_TYPE_INT64); - } - if (func->locals.f32_count != 0) { - leb = uint_to_uleb128((u64) func->locals.f32_count, &leb_len); - bh_buffer_append(buff, leb, leb_len); - bh_buffer_write_byte(buff, WASM_TYPE_FLOAT32); - } - if (func->locals.f64_count != 0) { - leb = uint_to_uleb128((u64) func->locals.f64_count, &leb_len); - bh_buffer_append(buff, leb, leb_len); - bh_buffer_write_byte(buff, WASM_TYPE_FLOAT64); - } - - return buff->length - prev_len; + i32 prev_len = buff->length; + + // NOTE: Output vector length + i32 total_locals = + (i32) (func->locals.i32_count != 0) + + (i32) (func->locals.i64_count != 0) + + (i32) (func->locals.f32_count != 0) + + (i32) (func->locals.f64_count != 0); + + i32 leb_len; + u8* leb = uint_to_uleb128((u64) total_locals, &leb_len); + bh_buffer_append(buff, leb, leb_len); + + if (func->locals.i32_count != 0) { + leb = uint_to_uleb128((u64) func->locals.i32_count, &leb_len); + bh_buffer_append(buff, leb, leb_len); + bh_buffer_write_byte(buff, WASM_TYPE_INT32); + } + if (func->locals.i64_count != 0) { + leb = uint_to_uleb128((u64) func->locals.i64_count, &leb_len); + bh_buffer_append(buff, leb, leb_len); + bh_buffer_write_byte(buff, WASM_TYPE_INT64); + } + if (func->locals.f32_count != 0) { + leb = uint_to_uleb128((u64) func->locals.f32_count, &leb_len); + bh_buffer_append(buff, leb, leb_len); + bh_buffer_write_byte(buff, WASM_TYPE_FLOAT32); + } + if (func->locals.f64_count != 0) { + leb = uint_to_uleb128((u64) func->locals.f64_count, &leb_len); + bh_buffer_append(buff, leb, leb_len); + bh_buffer_write_byte(buff, WASM_TYPE_FLOAT64); + } + + return buff->length - prev_len; } static void output_instruction(WasmInstruction* instr, bh_buffer* buff) { - i32 leb_len; - u8* leb; + i32 leb_len; + u8* leb; bh_buffer_write_byte(buff, (u8) instr->type); - switch (instr->type) { - case WI_LOCAL_GET: - case WI_LOCAL_SET: + switch (instr->type) { + case WI_LOCAL_GET: + case WI_LOCAL_SET: case WI_CALL: - case WI_BLOCK_START: + case WI_BLOCK_START: case WI_LOOP_START: case WI_JUMP: case WI_COND_JUMP: - case WI_IF_START: - leb = uint_to_uleb128((u64) instr->data.i1, &leb_len); - bh_buffer_append(buff, leb, leb_len); - break; + case WI_IF_START: + leb = uint_to_uleb128((u64) instr->data.i1, &leb_len); + bh_buffer_append(buff, leb, leb_len); + break; - case WI_I32_CONST: + case WI_I32_CONST: leb = int_to_leb128((i64) instr->data.i1, &leb_len); bh_buffer_append(buff, leb, leb_len); break; - case WI_I64_CONST: + case WI_I64_CONST: leb = int_to_leb128((i64) instr->data.l, &leb_len); bh_buffer_append(buff, leb, leb_len); break; - case WI_F32_CONST: + case WI_F32_CONST: leb = float_to_ieee754(instr->data.f, 0); bh_buffer_append(buff, leb, 4); break; - case WI_F64_CONST: + case WI_F64_CONST: leb = double_to_ieee754(instr->data.d, 0); bh_buffer_append(buff, leb, 8); break; - default: break; - } + default: break; + } } static i32 output_code(WasmFunc* func, bh_buffer* buff) { - bh_buffer code_buff; - bh_buffer_init(&code_buff, buff->allocator, 128); + bh_buffer code_buff; + bh_buffer_init(&code_buff, buff->allocator, 128); - // Output locals - output_locals(func, &code_buff); + // Output locals + output_locals(func, &code_buff); - // Output code - bh_arr_each(WasmInstruction, instr, func->code) output_instruction(instr, &code_buff); + // Output code + bh_arr_each(WasmInstruction, instr, func->code) output_instruction(instr, &code_buff); - i32 leb_len; - u8* leb = uint_to_uleb128((u64) code_buff.length, &leb_len); - bh_buffer_append(buff, leb, leb_len); + i32 leb_len; + u8* leb = uint_to_uleb128((u64) code_buff.length, &leb_len); + bh_buffer_append(buff, leb, leb_len); - bh_buffer_concat(buff, code_buff); - bh_buffer_free(&code_buff); + bh_buffer_concat(buff, code_buff); + bh_buffer_free(&code_buff); - return 0; + return 0; } static i32 output_codesection(OnyxWasmModule* module, bh_buffer* buff) { - i32 prev_len = buff->length; + i32 prev_len = buff->length; - bh_buffer_write_byte(buff, WASM_SECTION_ID_CODE); + bh_buffer_write_byte(buff, WASM_SECTION_ID_CODE); - bh_buffer vec_buff; - bh_buffer_init(&vec_buff, buff->allocator, 128); + bh_buffer vec_buff; + bh_buffer_init(&vec_buff, buff->allocator, 128); - i32 leb_len; - u8* leb = uint_to_uleb128((u64) bh_arr_length(module->funcs), &leb_len); - bh_buffer_append(&vec_buff, leb, leb_len); + i32 leb_len; + u8* leb = uint_to_uleb128((u64) bh_arr_length(module->funcs), &leb_len); + bh_buffer_append(&vec_buff, leb, leb_len); - // DEBUG_HERE; + // DEBUG_HERE; - bh_arr_each(WasmFunc, func, module->funcs) output_code(func, &vec_buff); + bh_arr_each(WasmFunc, func, module->funcs) output_code(func, &vec_buff); - leb = uint_to_uleb128((u64) (vec_buff.length), &leb_len); - bh_buffer_append(buff, leb, leb_len); + leb = uint_to_uleb128((u64) (vec_buff.length), &leb_len); + bh_buffer_append(buff, leb, leb_len); - bh_buffer_concat(buff, vec_buff); - bh_buffer_free(&vec_buff); + bh_buffer_concat(buff, vec_buff); + bh_buffer_free(&vec_buff); - return buff->length - prev_len; + return buff->length - prev_len; } void onyx_wasm_module_write_to_file(OnyxWasmModule* module, bh_file file) { - bh_buffer master_buffer; - bh_buffer_init(&master_buffer, bh_heap_allocator(), 128); - bh_buffer_append(&master_buffer, WASM_MAGIC_STRING, 4); - bh_buffer_append(&master_buffer, WASM_VERSION, 4); + bh_buffer master_buffer; + bh_buffer_init(&master_buffer, bh_heap_allocator(), 128); + bh_buffer_append(&master_buffer, WASM_MAGIC_STRING, 4); + bh_buffer_append(&master_buffer, WASM_VERSION, 4); - output_typesection(module, &master_buffer); + output_typesection(module, &master_buffer); output_importsection(module, &master_buffer); - output_funcsection(module, &master_buffer); - output_exportsection(module, &master_buffer); - output_startsection(module, &master_buffer); - output_codesection(module, &master_buffer); + output_funcsection(module, &master_buffer); + output_exportsection(module, &master_buffer); + output_startsection(module, &master_buffer); + output_codesection(module, &master_buffer); - bh_file_write(&file, master_buffer.data, master_buffer.length); + bh_file_write(&file, master_buffer.data, master_buffer.length); } -- 2.25.1