--- /dev/null
+package core.env
+
+use package build_opts as build_opts
+#if build_opts.Runtime != build_opts.Runtime_Wasi {
+ #error "'core.env' is only available with the 'wasi' runtime.";
+}
+
+
+use package wasi { environ_get, environ_sizes_get, Size }
+use package core.map as map
+use package core.memory as memory
+use package core.string as string
+
+Environment :: struct {
+ vars : map.Map(str, str);
+
+ buffer : [] u8;
+ buffer_allocator : Allocator;
+}
+
+get_env :: (allocator := context.allocator) -> Environment {
+ env_count, env_buf_size : Size;
+ environ_sizes_get(^env_count, ^env_buf_size);
+
+ env_var := memory.make_slice(cstr, env_count, allocator=allocator);
+ env_buf := memory.make_slice(u8, env_buf_size, allocator=allocator);
+
+ environ_get(env_var.data, env_buf.data);
+
+ while i := cast(i32) (env_var.count - 1); i >= 0 {
+ defer i -= 1;
+
+ env_var[i] = cast(cstr) (cast(^u32) env_var.data)[i];
+ }
+
+ env_map := map.make(str, str, "");
+ for env: env_var {
+ s := string.make(env);
+ var := string.read_until(^s, #char "=");
+ map.put(^env_map, var, string.advance(s, 1));
+ }
+
+ raw_free(allocator, env_var.data);
+
+ return .{
+ vars = env_map,
+ buffer = env_buf,
+ buffer_allocator = allocator,
+ };
+}
+
+free_env :: (use env: ^Environment) {
+ map.free(^vars);
+
+ raw_free(buffer_allocator, buffer.data);
+}
file_write :: (file: File, data: str) {
vec := IOVec.{ buf = cast(u32) data.data, len = data.count };
tmp : Size;
- wasi.fd_write(file.fd, IOVecArray.{ cast(u32) ^vec, 1 }, ^tmp);
+ wasi.fd_write(file.fd, .{ cast(u32) ^vec, 1 }, ^tmp);
wasi.fd_datasync(file.fd);
}
dummy2: u32;
buf := IOVec.{ cast(u32) data, size };
- wasi.fd_pread(file.fd, IOVecArray.{ cast(u32) ^buf, 1 }, 0, ^dummy2);
+ wasi.fd_pread(file.fd, .{ cast(u32) ^buf, 1 }, 0, ^dummy2);
wasi.fd_seek(file.fd, prev_loc, Whence.Set, ^dummy);
proc (path: str) -> str {
tmp_file, success := file_open(path, OpenMode.Read);
- if !success do return str.{ null, 0 };
+ if !success do return .{ null, 0 };
defer file_close(tmp_file);
return get_contents(tmp_file);
open :: (path: str, mode := OpenMode.Read) -> (Error, FileStream) {
fs := FileStream.{
- stream = Stream.{ vtable = null },
- file = File.{ fd = -1 },
+ stream = .{ vtable = null },
+ file = .{ fd = -1 },
};
file, success := file_open(path, mode);
hash_function :: proc {
(key: rawptr) -> u32 { return 0xcbf29ce7 ^ cast(u32) key; },
- (key: i32) -> u32 { return 0xcbf29ce7 ^ cast(u32) key; },
- (key: i64) -> u32 { return cast(u32) (cast(u64) 0xcbf29ce7 ^ cast(u64) key); },
-
- (key: str) -> u32 {
+ (key: i32) -> u32 { return 0xcbf29ce7 ^ cast(u32) key; },
+ (key: i64) -> u32 { return cast(u32) (cast(u64) 0xcbf29ce7 ^ cast(u64) key); },
+ (key: str) -> u32 {
hash: u32 = 5381;
for ch: key do hash += (hash << 5) + ~~ch;
return hash;
#load "core/sys/wasi"
#load "core/wasi"
#load "core/io/file"
+ #load "core/env"
}
#if build_opts.Runtime == build_opts.Runtime_Js {
SN.foo()
}
+[ ] There is a segfault when passing an anonymous struct literal to an untyped vararg.
+
+ vararg_proc :: (va: ...) {
+ ...
+ }
+
+ vararg_proc(.{ 1, 2 });
+
+[ ] This currently does not work but I think it should:
+
+ baked_proc :: (x: $T, $func: (T) -> T) -> T {
+ return func(x);
+ }
+
+ The problem is that 'T' is an unresolved symbol because the context of the function type
+ does not have the solved value of T in it.
+
+
List of things to change:
[X] Currently, there is no way to use the initialized members of a structure without using a struct literal.
There should be a initialize intrinsic procedure that takes a pointer to anything and initializes it.
if (node_is_type((AstNode *) node)) return 0;
if (node->kind == Ast_Kind_Struct_Literal && node->type_node == NULL) {
+ if (type->kind == Type_Kind_VarArgs) type = type->VarArgs.ptr_to_data->Pointer.elem;
node->type = type;
add_entities_for_node(NULL, (AstNode *) node, NULL, NULL);
token_toggle_end(symbol);
symbol_subpackage_introduce(package->scope, symbol->text, pnode);
token_toggle_end(symbol);
+
+ package_reinsert_use_packages(package);
}
package = newpackage;
}
static SymresStatus symres_polyproc(AstPolyProc* pp) {
+ pp->flags |= Ast_Flag_Comptime;
pp->poly_scope = curr_scope;
bh_arr_each(AstPolyParam, param, pp->poly_params) {