print_check "$name"
if ! ./bin/onyx -r js --use-post-mvp-features "$test_file" -o "./tests/$name.wasm" >/dev/null; then
- print "\n❌ Failed to compile $name.onyx.\n"
+ printf "\n❌ Failed to compile $name.onyx.\n"
failed=1
continue
fi
if ! ./bin/onyx-js "./tests/$name.wasm" > ./tmpoutput; then
- print "\n❌ Failed to run $name.onyx.\n"
+ printf "\n❌ Failed to run $name.onyx.\n"
failed=1
continue
fi
if ! diff ./tmpoutput "$dirname/$name" >/dev/null; then
- print "\n❌ Test output did not match.\n"
+ printf "\n❌ Test output did not match.\n"
diff ./tmpoutput "$dirname/$name"
# failed=0
continue
+++ /dev/null
-// This following sybmols are not meant to be included in any compilation.
-// Instead, all of the commented out symbols are defined automatically by the compiler
-// and can be used in compile time #if statements.
-
-// Runtime :: Runtime_Wasi OR Runtime_Js OR Runtime_Custom
-
-
-
-
-
-package build_opts
-
-
-// At some point, these will become an enum. The problem at the moment is that
-// compile-time if statements are not well integrated into other language features
-// such as enums. They can only really handle compile time number math and boolean
-// logic. - brendanfh 2020/02/08
-
-Runtime_Wasi :: 1
-Runtime_Js :: 2
-Runtime_Custom :: 3
package builtin
-use package build_opts as build_opts
+
+// CLEANUP: Should builtin.onyx really be including other files in the compilation?
+// Does that complicate things too much?
+#load "core/runtime/build_opts"
+use package runtime as runtime
str :: #type []u8;
cstr :: #type ^u8;
ret := *cast(^T) va.data;
va.data = cast(rawptr) (cast(^u8) va.data + sizeof T);
va.count -= 1;
- return res;
+ return ret;
}
}
assert_handler : (msg: str, file: str) -> void;
}
-#if build_opts.Runtime != build_opts.Runtime_Custom {
+#if runtime.Runtime != runtime.Runtime_Custom {
#private_file default_logger :: (data: rawptr, msg: str) {
use package core
println(msg);
cresize :: (ptr: rawptr, size: u32) -> rawptr do return raw_resize(context.allocator, ptr, size);
cfree :: (ptr: rawptr) do raw_free(context.allocator, ptr);
-#if build_opts.Runtime != build_opts.Runtime_Custom {
+#if runtime.Runtime != runtime.Runtime_Custom {
new :: ($T: type_expr, allocator := context.allocator, initialize := true) -> ^T {
res := cast(^T) raw_alloc(allocator, sizeof T);
// @Robustness: This should be a '#if' when those are added in procedures because
// otherwise the __initialize intrinsic is going to be generated no matter what.
// This could be a problem if the type is not something that can be initialized.
- use package core.intrinsics.wasm { __initialize }
+ use package core.intrinsics.onyx { __initialize }
if initialize do __initialize(res);
return res;
package core.env
-use package build_opts as build_opts
-#if build_opts.Runtime != build_opts.Runtime_Wasi {
+use package runtime as runtime
+#if runtime.Runtime != runtime.Runtime_Wasi {
#error "'core.env' is only available with the 'wasi' runtime.";
}
--- /dev/null
+package core.intrinsics.onyx
+
+__initialize :: (val: ^$T) -> void #intrinsic ---
memory_copy :: (dst: rawptr, src: rawptr, count: i32) -> void #intrinsic ---
memory_fill :: (dst: rawptr, byte: u8, count: i32) -> void #intrinsic ---
-__initialize :: (val: ^$T) -> void #intrinsic ---
-
clz_i32 :: (val: i32) -> i32 #intrinsic ---
ctz_i32 :: (val: i32) -> i32 #intrinsic ---
popcnt_i32 :: (val: i32) -> i32 #intrinsic ---
package core.io
-use package build_opts as build_opts
-#if build_opts.Runtime != build_opts.Runtime_Wasi {
+use package runtime as runtime
+#if runtime.Runtime != runtime.Runtime_Wasi {
#error "The file system library is currently only available on the WASI runtime, and should only be included if that is the chosen runtime."
}
// To be used with the corresponding gl.js
// There are many things that are missing but this suffices for me.
-use package build_opts as build_opts
-#if build_opts.Runtime != build_opts.Runtime_Js {
+use package runtime as runtime
+#if runtime.Runtime != runtime.Runtime_Js {
#error "'webgl' can only be used with the 'js' runtime."
}
package core.map
-use package core { printf }
use package core.array as array
use package core.string as string
--- /dev/null
+// This following sybmols are not meant to be included in any compilation.
+// Instead, all of the commented out symbols are defined automatically by the compiler
+// and can be used in compile time #if statements.
+
+// Runtime :: Runtime_Wasi OR Runtime_Js OR Runtime_Custom
+
+
+
+
+
+package runtime
+
+
+// At some point, these will become an enum. The problem at the moment is that
+// compile-time if statements are not well integrated into other language features
+// such as enums. They can only really handle compile time number math and boolean
+// logic. - brendanfh 2020/02/08
+
+Runtime_Wasi :: 1
+Runtime_Js :: 2
+Runtime_Custom :: 3
--- /dev/null
+package runtime
+
+use package core
+use package core.intrinsics.onyx { __initialize }
+
+// The default assert handler. This assumes that __output_string
+// and __exit are defined in the 'runtime' package.
+__assert_handler :: (msg: str, file: str) {
+ __output_string("Assert failed: ");
+ __output_string(msg);
+
+ if file.data != null {
+ __output_string(" in ");
+ __output_string(file);
+ }
+
+ __output_string("\n");
+
+ __exit(1);
+}
+
+// Use this procedure to initialize everything needed in the
+// standard library when you are dropped directly into a function.
+__runtime_initialize :: () {
+ alloc.init();
+
+ __initialize(^context);
+ context.allocator = alloc.heap_allocator;
+ context.temp_allocator = alloc.temp_allocator;
+ context.assert_handler = __assert_handler;
+
+ __stdio_init();
+}
+
--- /dev/null
+package runtime
+
+#load "core/runtime/common"
+
+use package core
+use package main as main
+
+__output_string :: (s: str) -> u32 #foreign "host" "print_str" ---
+__exit :: (status: i32) -> void #foreign "host" "exit" ---
+
+// The builtin _start proc.
+// Sets up everything needed for execution.
+proc () #export "_start" {
+ __runtime_initialize();
+
+ args: [] cstr = .{ null, 0 };
+ main.main(args);
+
+ __flush_stdio();
+}
--- /dev/null
+package runtime
+
+#load "core/wasi"
+#load "core/runtime/common"
+
+use package wasi
+use package core
+use package main as main
+
+__output_string :: (s: str) -> u32 {
+ STDOUT_FILENO :: 1
+
+ vec := IOVec.{ buf = cast(u32) s.data, len = s.count };
+ tmp : Size;
+ fd_write(STDOUT_FILENO, IOVecArray.{ cast(u32) ^vec, 1 }, ^tmp);
+ fd_datasync(STDOUT_FILENO);
+ return tmp;
+}
+
+__exit :: (status: i32) do proc_exit(status);
+
+// The builtin _start proc.
+// Sets up everything needed for execution.
+proc () #export "_start" {
+ __runtime_initialize();
+
+ args : [] cstr;
+ argv_buf_size : Size;
+ args_sizes_get(^args.count, ^argv_buf_size);
+
+ args = memory.make_slice(cstr, args.count);
+ argv_buf := cast(cstr) calloc(argv_buf_size);
+ args_get(args.data, argv_buf);
+
+
+ // This post processing of the argv array needs to happen if the target is using
+ // 32-bit pointers, instead of 64-bits. Right now, Onyx pointers take up 64-bits,
+ // but in most circumstances, only the lower 32-bits are used. When webassembly
+ // standardizes the 64-bit address space, it will be an easy conversion over.
+ // But for right now, WASI will give the argv array 32-bit pointers, instead of
+ // 64-bit pointers. This loops expands the 32-bit pointers into 64-bit pointers
+ // while not clobbering any of them.
+ while i := cast(i32) (args.count - 1); i >= 0 {
+ defer i -= 1;
+
+ args[i] = cast(cstr) (cast(^u32) args.data)[i];
+ }
+
+ main.main(args);
+
+ __flush_stdio();
+}
package core
-#load "core/build_opts"
-
#load "core/alloc"
#load "core/memory"
#load "core/string/builder"
#load "core/string/reader"
+#load "core/intrinsics/onyx"
#load "core/intrinsics/wasm"
#load "core/io/io"
#load "core/io/writer"
#load "core/io/binary"
-use package build_opts as build_opts
-#if build_opts.Runtime == build_opts.Runtime_Wasi {
- #load "core/sys/wasi"
+#load "core/runtime/build_opts"
+#load "core/runtime/common"
+
+use package runtime as runtime
+#if runtime.Runtime == runtime.Runtime_Wasi {
+ #load "core/runtime/wasi"
#load "core/wasi"
#load "core/io/file"
#load "core/env"
}
-#if build_opts.Runtime == build_opts.Runtime_Js {
- #load "core/sys/js"
+#if runtime.Runtime == runtime.Runtime_Js {
+ #load "core/runtime/js"
}
-#if build_opts.Runtime != build_opts.Runtime_Custom {
+#if runtime.Runtime != runtime.Runtime_Custom {
#load "core/stdio"
}
// It is expected that a file will be included that will be part
// of the system package
-use package build_opts as build_opts
-#if build_opts.Runtime != build_opts.Runtime_Custom {
- use package system as system
-} else {
+use package runtime as runtime
+#if runtime.Runtime == runtime.Runtime_Custom {
#error "'stdio' can only be included in the 'wasi' or 'js' runtime."
}
-#private_file print_stream : io.DynamicStringStream;
-#private_file print_writer : io.Writer;
-
-stdio_init :: () {
- print_stream = io.dynamic_string_stream_make(2048, context.allocator);
- print_writer = io.writer_make(^print_stream);
-}
-
print :: proc {
(x: str) {
io.write(^print_writer, x);
- if x[x.count - 1] == #char "\n" do print_stream_flush();
+ if x[x.count - 1] == #char "\n" do __flush_stdio();
},
(x: $T) { io.write(^print_writer, x); },
}
}
-print_stream_flush :: () {
+
+//
+// Private and internal things
+//
+
+#private_file print_stream : io.DynamicStringStream;
+#private_file print_writer : io.Writer;
+
+__stdio_init :: () {
+ print_stream = io.dynamic_string_stream_make(2048, context.allocator);
+ print_writer = io.writer_make(^print_stream);
+}
+
+
+__flush_stdio :: () {
if print_stream.data.count == 0 do return;
^print_stream
|> io.dynamic_string_stream_to_str()
- |> system.output_str();
+ |> runtime.__output_string();
^print_stream |> io.stream_flush();
}
},
}
-// trim_start :: (s: str, ch := #char " ") -> str
-// trim_start :: (s: ^str, ch := #char " ")
-// trim_end :: (s: str, ch := #char " ") -> str
-// trim_end :: (s: ^str, ch := #char " ")
+concat :: proc {
+ (s1: str, s2: str, allocator := context.allocator) -> str {
+ len1 := length(s1);
+ len2 := length(s2);
-concat :: (s1: str, s2: str, allocator := context.allocator) -> str {
- len1 := length(s1);
- len2 := length(s2);
+ data := cast(^u8) raw_alloc(allocator, len1 + len2);
+ memory.copy(data, s1.data, len1);
+ memory.copy(data + len1, s2.data, len2);
- data := cast(^u8) raw_alloc(allocator, len1 + len2);
- memory.copy(data, s1.data, len1);
- memory.copy(data + len1, s2.data, len2);
+ return str.{ data, len1 + len2 };
+ },
- return str.{ data, len1 + len2 };
+ (into: ^[..] u8, s: str) -> str {
+ array.ensure_capacity(into, into.count + s.count);
+ memory.copy(into.data, s.data, into.count);
+ into.count += s.count;
+ return .{ into.data, into.count };
+ }
}
split :: (s: str, delim: u8, allocator := context.allocator) -> []str {
return false;
},
- (s: str, substr: str) -> bool #export "ASDFASDFASDF" {
+ (s: str, substr: str) -> bool {
while i := 0; i < s.count {
while j := 0; j < substr.count {
if s[i + j] != substr[j] {
package core.string.reader
-use package core { printf }
-
StringReader :: struct {
// Think of this as `use s : str`;
data : ^u8;
+++ /dev/null
-package system
-
-use package core
-use package main as main
-use package core.intrinsics.wasm { __initialize }
-
-output_str :: (s: str) -> u32 #foreign "host" "print_str" ---
-
-assert_handler :: (msg: str, file: str) {
- output_str("Assert failed: ");
- output_str(msg);
-
- if file.data != null {
- output_str(" in ");
- output_str(file);
- }
-
- output_str("\n");
-
- process_exit :: proc (status: i32) #foreign "host" "exit" ---
- process_exit(1);
-}
-
-// The builtin _start proc.
-// Sets up everything needed for execution.
-proc () #export "_start" {
- alloc.init();
-
- __initialize(^context);
- context.allocator = alloc.heap_allocator;
- context.temp_allocator = alloc.temp_allocator;
- context.assert_handler = assert_handler;
-
- args : [] cstr;
- args.data = null;
- args.count = 0;
-
- stdio_init();
-
- main.main(args);
-
- print_stream_flush();
-}
+++ /dev/null
-package system
-
-#load "core/wasi"
-
-use package wasi
-use package core
-use package main as main
-use package core.intrinsics.wasm { __initialize }
-
-STDOUT_FILENO :: 1
-
-output_str :: (s: str) -> u32 {
- vec := IOVec.{ buf = cast(u32) s.data, len = s.count };
- tmp : Size;
- fd_write(STDOUT_FILENO, IOVecArray.{ cast(u32) ^vec, 1 }, ^tmp);
- fd_datasync(STDOUT_FILENO);
- return tmp;
-}
-
-assert_handler :: (msg: str, file: str) {
- output_str("Assert failed: ");
- output_str(msg);
-
- if file.data != null {
- output_str(" in ");
- output_str(file);
- }
-
- output_str("\n");
-
- proc_exit(1);
-}
-
-proc () #export "_initialize" {
- alloc.init();
-
- __initialize(^context);
- context.allocator = alloc.heap_allocator;
- context.temp_allocator = alloc.temp_allocator;
- context.assert_handler = assert_handler;
-
- stdio_init();
-}
-
-// The builtin _start proc.
-// Sets up everything needed for execution.
-proc () #export "_start" {
- alloc.init();
-
- __initialize(^context);
- context.allocator = alloc.heap_allocator;
- context.temp_allocator = alloc.temp_allocator;
- context.assert_handler = assert_handler;
-
- stdio_init();
-
- args : [] cstr;
- argv_buf_size : Size;
- args_sizes_get(^args.count, ^argv_buf_size);
-
- args = memory.make_slice(cstr, args.count);
- argv_buf := cast(cstr) calloc(argv_buf_size);
- args_get(args.data, argv_buf);
-
-
- // This post processing of the argv array needs to happen if the target is using
- // 32-bit pointers, instead of 64-bits. Right now, Onyx pointers take up 64-bits,
- // but in most circumstances, only the lower 32-bits are used. When webassembly
- // standardizes the 64-bit address space, it will be an easy conversion over.
- // But for right now, WASI will give the argv array 32-bit pointers, instead of
- // 64-bit pointers. This loops expands the 32-bit pointers into 64-bit pointers
- // while not clobbering any of them.
- while i := cast(i32) (args.count - 1); i >= 0 {
- defer i -= 1;
-
- args[i] = cast(cstr) (cast(^u32) args.data)[i];
- }
-
- main.main(args);
-
- print_stream_flush();
-}
while (*e == *s && e != end && s != str) e--, s--;
- return e == end;
+ return *e == *s;
}
char* bh_strdup(bh_allocator a, char* str) {
specific_compose_2 :: #solidify specific_compose_1 { C = f64 };
main :: proc (args: [] cstr) {
- use package build_opts
+ use package runtime
println(Runtime);
println("==================================================");
}
}
-double :: proc (v: $V) -> V do return v * 2;
\ No newline at end of file
+double :: proc (v: $V) -> V do return v * 2;
}
void introduce_build_options(bh_allocator a) {
- Package* p = package_lookup_or_create("build_opts", context.global_scope, a);
+ Package* p = package_lookup_or_create("runtime", context.global_scope, a);
AstNumLit* runtime_type = make_int_literal(a, context.options->runtime);
symbol_builtin_introduce(p->scope, "Runtime", (AstNode *) runtime_type);