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
null :: cast(rawptr) 0;
+// ---------------------------------
+// Allocation
+// ---------------------------------
DEFAULT_ALLOCATION_ALIGNMENT :: 16
AllocAction :: enum {
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;
}
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;
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
+}
}
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,
}
#ifndef BH_H
#define BH_H
+// NOTE: For lseek64
+#define _LARGEFILE64_SOURCE
+
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
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;
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 {
}
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;
--- /dev/null
+{
+ "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
--- /dev/null
+" Vim compiler file
+" Compiler: Onyx
+" Previous Maintainer: Brendan Hansen <brendan.f.hansen@gmail.com>
+" 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
#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
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(" ");
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);
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
+}
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;
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 " ");
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
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));
}
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");
}
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;
}
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;
}
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:
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));
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;
// 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;
}
find_token(parser, '}');
return block;
}
- expect_token(parser, '{');
+ block->token = expect_token(parser, '{');
AstNode** next = &block->body;
AstNode* stmt = NULL;
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,
} 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
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);
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);