From: Brendan Hansen Date: Sat, 29 Aug 2020 20:01:55 +0000 (-0500) Subject: critical bugfixes and sublime/vim compiliation support X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=f90c4c1a49f53c7977638f0a09a773a384ac075c;p=onyx.git critical bugfixes and sublime/vim compiliation support --- diff --git a/Makefile b/Makefile index 177c8395..21ec2025 100644 --- a/Makefile +++ b/Makefile @@ -37,8 +37,10 @@ install: $(TARGET) core/* cp -r core/ /usr/share/onyx install_syntax: misc/onyx.vim misc/onyx.sublime-syntax + cp ./misc/onyx_compiler.vim /usr/share/vim/vim82/compiler/onyx.vim cp ./misc/onyx.vim /usr/share/vim/vim82/syntax/onyx.vim cp ./misc/onyx.sublime-syntax /home/brendan/.config/sublime-text-3/Packages/User/onyx.sublime-syntax + cp ./misc/onyx.sublime-build /home/brendan/.config/sublime-text-3/Packages/User/Onyx.sublime-build clean: rm -f $(OBJ_FILES) 2>&1 >/dev/null diff --git a/core/builtin.onyx b/core/builtin.onyx index 022be1df..694a0744 100644 --- a/core/builtin.onyx +++ b/core/builtin.onyx @@ -7,6 +7,9 @@ Buffer :: #type []void; null :: cast(rawptr) 0; +// --------------------------------- +// Allocation +// --------------------------------- DEFAULT_ALLOCATION_ALIGNMENT :: 16 AllocAction :: enum { @@ -38,6 +41,11 @@ calloc :: proc (size: u32) -> rawptr do return alloc(context.allocator, size); cresize :: proc (ptr: rawptr, size: u32) -> rawptr do return resize(context.allocator, ptr, size); cfree :: proc (ptr: rawptr) do free(context.allocator, ptr); + + +// --------------------------------- +// Dynamic Arrays +// --------------------------------- array_init :: proc (arr: ^[..] $T, initial_cap := 4) { arr.count = 0; arr.capacity = initial_cap; @@ -78,7 +86,7 @@ array_add_at :: proc (arr: ^[..] $T, x: T, idx: u32) { } array_remove :: proc (arr: ^[..] $T, elem: T) { - move := 0; + move := 0; for i: 0, arr.count - move { if arr.data[i + move] == elem do move += 1; @@ -117,8 +125,12 @@ array_average :: proc (arr: ^[..] $T) -> T { return sum / cast(T) arr.count; } +array_to_slice :: proc (arr: ^[..] $T) -> [] T { + return arr.data[0 : arr.count]; +} + context : struct { allocator : Allocator; temp_allocator : Allocator; -} \ No newline at end of file +} diff --git a/core/stdio.onyx b/core/stdio.onyx index 5eab4dfe..9402b756 100644 --- a/core/stdio.onyx +++ b/core/stdio.onyx @@ -10,15 +10,15 @@ print_string :: proc (s: string) { } print_cstring :: proc (s: cstring) do string_builder_append(^cout_state.sb, s); -print_u64 :: proc (n: u64, base := 10l) do string_builder_append(^cout_state.sb, n, base); -print_u32 :: proc (n: u32, base := 10) do string_builder_append(^cout_state.sb, cast(u64) n, cast(u64) base); +print_i64 :: proc (n: i64, base := 10l) do string_builder_append(^cout_state.sb, n, base); +print_i32 :: proc (n: i32, base := 10) do string_builder_append(^cout_state.sb, cast(i64) n, cast(u64) base); print_bool :: proc (b: bool) do string_builder_append(^cout_state.sb, b); print :: proc #overloaded { print_string, print_cstring, - print_u64, - print_u32, + print_i64, + print_i32, print_bool, } diff --git a/include/bh.h b/include/bh.h index 0a44d9af..e5f0be86 100644 --- a/include/bh.h +++ b/include/bh.h @@ -1,6 +1,9 @@ #ifndef BH_H #define BH_H +// NOTE: For lseek64 +#define _LARGEFILE64_SOURCE + #include #include #include @@ -1255,9 +1258,9 @@ bh_file_error bh_file_open_mode(bh_file* file, bh_file_mode mode, const char* fi 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: 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; @@ -1293,8 +1296,8 @@ b32 bh_file_read_at(bh_file* file, i64 offset, void* buffer, isize buff_size, is 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) { + bh__file_seek_wrapper(file->fd, 0, BH_FILE_WHENCE_CURRENT, ¤t_offset); + if (current_offset == offset || file->fd == 1 || file->fd == 2) { // Standard in and out do like pwrite() res = write(file->fd, buffer, buff_size); } else { @@ -1307,7 +1310,7 @@ b32 bh_file_write_at(bh_file* file, i64 offset, void const* buffer, isize buff_s } static b32 bh__file_seek_wrapper(i32 fd, i64 offset, bh_file_whence whence, i64* new_offset) { - i64 res = lseek(fd, offset, whence); + i64 res = lseek64(fd, offset, whence); if (res < 0) return 0; if (new_offset) *new_offset = res; return 1; diff --git a/misc/onyx.sublime-build b/misc/onyx.sublime-build new file mode 100644 index 00000000..fcf81eac --- /dev/null +++ b/misc/onyx.sublime-build @@ -0,0 +1,7 @@ +{ + "target": "exec", + "shell_cmd": "/usr/bin/onyx -o \"${folder}/${file_base_name}.wasm\" \"$file\"", + "working_dir": "${folder}", + "selector": "source.onyx", + "file_regex": "^\\(([^:]+):([0-9]+),([0-9]+)\\) (.*)", +} \ No newline at end of file diff --git a/misc/onyx_compiler.vim b/misc/onyx_compiler.vim new file mode 100644 index 00000000..dd242392 --- /dev/null +++ b/misc/onyx_compiler.vim @@ -0,0 +1,19 @@ +" Vim compiler file +" Compiler: Onyx +" Previous Maintainer: Brendan Hansen +" Latest Revision: 2020-08-29 + +if exists("current_compiler") + finish +endif +let current_compiler = "onyx" + +let s:cpo_save = &cpo +set cpo&vim + +CompilerSet errorformat=%E\(%f\:%l\\,%c\)\ \%m,%C%.%# + +set makeprg=onyx\ % + +let &cpo = s:cpo_save +unlet s:cpo_save diff --git a/onyx b/onyx index c9f25d80..ceacaca6 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/poly_test.onyx b/progs/poly_test.onyx index 430f4636..45ccbbf4 100644 --- a/progs/poly_test.onyx +++ b/progs/poly_test.onyx @@ -11,11 +11,7 @@ package main #include_file "file" use package builtin - -// NOTE: Didn't realize this would work so easily -use package core { string_builder_append as sba } use package core - use package memory use package wasi use package intrinsics @@ -30,10 +26,15 @@ print_arr_details :: proc (arr: ^[..] $T) { print(arr.capacity); print("\n\tData ptr: "); print(cast(u32) arr.data, 16); + print("\n\tSize of elements: "); + print(sizeof T); + print("\n\tAlignment of elements: "); + print(alignof T); print("\n\n"); } -print_arr :: proc (arr: ^[..] $T) { +// This works on both slices and arrays +print_arr :: proc (arr: $T) { for i: 0, arr.count { print(arr.data[i]); print(" "); @@ -42,26 +43,61 @@ print_arr :: proc (arr: ^[..] $T) { print("\n"); } -print_vec_arr :: proc (arr: ^[..] Vec3) { +print_vec_arr :: proc (arr: [..] Vec3) { for i: 0, arr.count { print("Vec3("); - print(arr.data[i].x); + print(arr[i].x); print(", "); - print(arr.data[i].y); + print(arr[i].y); print(", "); - print(arr.data[i].z); + print(arr[i].z); print(")\n"); } print("\n"); } +// This demonstrates that we have something similar to static 'duck' typing. +get_count :: proc (x: $T) -> u32 do return x.count; + + + +SOA :: struct { + a : [..] i32; + b : [..] i64; +} + main :: proc (args: [] cstring) { + s : SOA; + array_init(^s.a, 10); + array_init(^s.b, 10); + defer array_free(^s.a); + defer array_free(^s.b); + + print_arr_details(^s.a); + print_arr_details(^s.b); + + for i: 0, 100 { + array_add(^s.a, 5 * i); + array_add(^s.b, 3l * cast(i64) i); + } + + print_arr(^s.a); + print_arr(array_to_slice(^s.a)); + + print("After adding...\n"); + print_arr_details(^s.a); + print_arr_details(^s.b); +} + +main2 :: proc (args: [] cstring) { print(cast(u32) __heap_start, 16); + iarr_backing : [32] i32; iarr : [..] i32; - array_init(^iarr, 24); - defer array_free(^iarr); + iarr.data = cast(^i32) iarr_backing; + iarr.count = 0; + iarr.capacity = 32; print_arr_details(^iarr); @@ -116,15 +152,28 @@ main :: proc (args: [] cstring) { defer array_free(^varr); for i: 0, 20 { - array_add(^varr, Vec3.{ i, i * i, i * i * i }); + array_add(^varr, Vec3.{ + x = i, + y = i * i, + z = i * i * i, + }); } + array_add(^varr, Vec3.{ 4, 2, 3 }); + print_arr_details(^varr); - print_vec_arr(^varr); + print_vec_arr(varr); + + print(get_count(iarr)); + print("\n"); + print(get_count(barr)); + print("\n"); + print(get_count(varr)); + print("\n"); } Vec3 :: struct { x: i32; y: i32; z: i32; -} \ No newline at end of file +} diff --git a/progs/wasi_test.onyx b/progs/wasi_test.onyx index 62fbc25d..45a4cb31 100644 --- a/progs/wasi_test.onyx +++ b/progs/wasi_test.onyx @@ -81,10 +81,10 @@ readdir :: proc (fd: FileDescriptor) { print("\n"); print("\td_namlen: "); - print_u64(cast(u64) dirent.d_namlen, 16l); + print_i64(cast(u64) dirent.d_namlen, 16l); print("\n"); print("\td_type: "); - print_u64(cast(u64) dirent.d_type, 16l); + print_i64(cast(u64) dirent.d_type, 16l); print("\n"); bufused -= sizeof DirEnt + dirent.d_namlen; @@ -186,7 +186,7 @@ main :: proc (args: []cstring) { sum := 0l; for i: 0, 20000 do if is_prime(i) do sum += cast(u64) i; print("Sum of primes less than 20000 is: "); - print_u64(sum); + print_i64(sum); print("\n"); matches := string_split("This is a test string to test splitting. It surprisingly works very well.", #char " "); @@ -215,7 +215,7 @@ main :: proc (args: []cstring) { case #default { print("Unexpected token: "); - print_u64(cast(u64) tokens[i][0], 16l); + print_i64(cast(u64) tokens[i][0], 16l); print("\n"); // This breaks out of the for loop @@ -275,9 +275,9 @@ main :: proc (args: []cstring) { foobar(10, 1230); sl := make_i32_arr(); - print_u64(cast(u64) sl.count); + print_i64(cast(u64) sl.count); - print_u64(cast(u64) fib(20)); + print_i64(cast(u64) fib(20)); print("\n"); print(add(20l, 5l)); @@ -313,11 +313,11 @@ main :: proc (args: []cstring) { } foobar :: proc (a: i32, b := 1, c := 5l) { - print_u64(cast(u64) a); + print_i64(cast(u64) a); print("\n"); - print_u64(cast(u64) b, 16l); + print_i64(cast(u64) b, 16l); print("\n"); - print_u64(c); + print_i64(c); print("\n"); } diff --git a/src/onyx.c b/src/onyx.c index 4a867397..32880828 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -387,7 +387,7 @@ static i32 onyx_compile(CompilerState* compiler_state) { if (compiler_state->options->action == ONYX_COMPILE_ACTION_DOCUMENT) { OnyxDocumentation docs = onyx_docs_generate(&compiler_state->prog_info); onyx_docs_write(&docs); - + return ONYX_COMPILER_PROGRESS_SUCCESS; } @@ -462,7 +462,7 @@ int main(int argc, char *argv[]) { break; case ONYX_COMPILER_PROGRESS_SUCCESS: - if (compile_opts.verbose_output) bh_printf("Successfully compiled to '%s'\n", compile_opts.target_file); + bh_printf("Successfully compiled to '%s'\n", compile_opts.target_file); break; } diff --git a/src/onyxclone.c b/src/onyxclone.c index 459d4630..bbf58526 100644 --- a/src/onyxclone.c +++ b/src/onyxclone.c @@ -201,6 +201,7 @@ AstNode* ast_clone(bh_allocator a, void* n) { case Ast_Kind_Block: ((AstBlock *) nn)->body = ast_clone_list(a, ((AstBlock *) node)->body); ((AstBlock *) nn)->locals = NULL; + bh_arr_new(global_heap_allocator, ((AstBlock *) nn)->locals, 4); break; case Ast_Kind_Defer: @@ -288,6 +289,9 @@ AstNode* ast_clone(bh_allocator a, void* n) { df->return_type = (AstType *) ast_clone(a, sf->return_type); df->body = (AstBlock *) ast_clone(a, sf->body); + df->locals = NULL; + bh_arr_new(global_heap_allocator, df->locals, 4); + df->params = NULL; bh_arr_new(global_heap_allocator, df->params, bh_arr_length(sf->params)); diff --git a/src/onyxmsgs.c b/src/onyxmsgs.c index 539a8730..b436e9a9 100644 --- a/src/onyxmsgs.c +++ b/src/onyxmsgs.c @@ -59,6 +59,7 @@ void onyx_message_add(MsgType type, OnyxFilePos pos, ...) { va_end(arg_list); Message** walker = &msgs.first; + while (*walker && strcmp((*walker)->pos.filename, pos.filename) < 0) walker = &(*walker)->next; 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; diff --git a/src/onyxparser.c b/src/onyxparser.c index 8db27f25..177b4ad6 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -1129,12 +1129,12 @@ static AstBlock* parse_block(OnyxParser* parser) { // NOTE: --- is for an empty block if (parser->curr->type == Token_Type_Empty_Block) { - expect_token(parser, Token_Type_Empty_Block); + block->token = expect_token(parser, Token_Type_Empty_Block); return block; } if (parser->curr->type == Token_Type_Keyword_Do) { - consume_token(parser); + block->token = expect_token(parser, Token_Type_Keyword_Do); block->body = parse_statement(parser); return block; } @@ -1144,7 +1144,7 @@ static AstBlock* parse_block(OnyxParser* parser) { find_token(parser, '}'); return block; } - expect_token(parser, '{'); + block->token = expect_token(parser, '{'); AstNode** next = &block->body; AstNode* stmt = NULL; diff --git a/src/onyxutils.c b/src/onyxutils.c index 73cb70e4..00c7bae4 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -431,10 +431,19 @@ AstFunction* polymorphic_proc_lookup(AstPolyProc* pp, AstCall* call) { bh_table_put(AstFunction *, pp->concrete_funcs, key_buf, func); symres_function(func); - if (onyx_message_has_errors()) return NULL; - if (check_function_header(func)) return NULL; - if (check_function(func)) return NULL; - if (onyx_message_has_errors()) return NULL; + if (onyx_message_has_errors()) goto has_error; + if (check_function_header(func)) goto has_error; + if (check_function(func)) goto has_error; + if (onyx_message_has_errors()) goto has_error; + goto no_errors; + +has_error: + onyx_message_add(Msg_Type_Literal, + call->token->pos, + "error in polymorphic procedure generated from this call site."); + return NULL; + +no_errors: bh_arr_push(semstate.other_entities, ((Entity) { .type = Entity_Type_Function_Header, diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 13661c7a..f79e6ca1 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -1175,7 +1175,7 @@ COMPILE_FUNC(array_access_location, AstArrayAccess* aa, u64* offset_return) { } else if (aa->addr->kind == Ast_Kind_Field_Access && aa->addr->type->kind == Type_Kind_Array) { compile_field_access_location(mod, &code, (AstFieldAccess *) aa->addr, &offset); - } else if (aa->addr->kind == Ast_Kind_Local + } else if ((aa->addr->kind == Ast_Kind_Local || aa->addr->kind == Ast_Kind_Param) && aa->addr->type->kind == Type_Kind_Array) { compile_local_location(mod, &code, (AstLocal *) aa->addr, &offset); } else if (aa->addr->kind == Ast_Kind_Memres @@ -1207,7 +1207,7 @@ COMPILE_FUNC(field_access_location, AstFieldAccess* field, u64* offset_return) { u64 o2 = 0; compile_array_access_location(mod, &code, (AstArrayAccess *) source_expr, &o2); offset += o2; - } else if (source_expr->kind == Ast_Kind_Local + } else if ((source_expr->kind == Ast_Kind_Local || source_expr->kind == Ast_Kind_Param) && source_expr->type->kind != Type_Kind_Pointer) { u64 o2 = 0; compile_local_location(mod, &code, (AstLocal *) source_expr, &o2); @@ -1603,7 +1603,7 @@ COMPILE_FUNC(expression, AstTyped* expr) { WID(WI_I32_CONST, sl->elem_size); WI(WI_I32_MUL); } - compile_location(mod, &code, sl->addr); + compile_expression(mod, &code, sl->addr); WI(WI_I32_ADD); compile_expression(mod, &code, sl->hi); WIL(WI_LOCAL_GET, tmp_local);