- `[captures] ( expr )` for expressions.
- `Optional.with` for running a block of code with the value in an Optional, if one is present.
- `iter.flatten`
+- `-Dvariable=value` command line option to add symbols to the `runtime.vars` package.
+- `--no-type-info` command line option to omit type information from the binary.
Removals:
- Remove old syntax for quoted blocks, `#quote` and `#()`.
- Switch to `[] {}` and `[] ()` respectively.
+- Old WASI specific modules for time and environment variables.
Changes:
bh_imap implicit_cast_to_bool_cache;
} ContextCaches;
+typedef struct DefinedVariable {
+ char *key;
+ char *value;
+} DefinedVariable;
+
typedef struct CompileOptions CompileOptions;
struct CompileOptions {
b32 use_post_mvp_features : 1;
b32 use_multi_threading : 1;
b32 generate_foreign_info : 1;
+ b32 generate_type_info : 1;
b32 no_std : 1;
b32 no_stale_code : 1;
b32 show_all_errors : 1;
const char* documentation_file;
const char* symbol_info_file;
const char* help_subcommand;
+ bh_arr(DefinedVariable) defined_variables;
b32 debug_enabled;
void introduce_build_options(bh_allocator a) {
Package* p = package_lookup_or_create("runtime", context.global_scope, a, context.global_scope->created_at);
+
+ // HACK creating this for later
+ package_lookup_or_create("runtime.vars", p->scope, a, context.global_scope->created_at);
AstType* Runtime_Type = (AstType *) symbol_raw_resolve(p->scope, "Runtime");
if (Runtime_Type == NULL) {
"\t--tag Generates a C-Tag file.\n"
"\t--syminfo <target_file> Generates a symbol resolution information file. Used by onyx-lsp.\n"
"\t--no-stale-code Disables use of `#allow_stale_code` directive\n"
+ "\t--no-type-info Disables generating type information\n"
"\t--generate-foreign-info\n"
"\n"
"Developer options:\n"
.use_post_mvp_features = 1,
.use_multi_threading = 0,
+ .generate_foreign_info = 0,
+ .generate_type_info = 1,
.no_std = 0,
.no_stale_code = 0,
.show_all_errors = 0,
.symbol_info_file = NULL,
.help_subcommand = NULL,
+ .defined_variables = NULL,
+
.debug_enabled = 0,
.passthrough_argument_count = 0,
bh_arr_new(alloc, options.files, 2);
bh_arr_new(alloc, options.included_folders, 2);
+ bh_arr_new(alloc, options.defined_variables, 2);
char* core_installation;
#ifdef _BH_LINUX
else if (!strcmp(argv[i], "--generate-foreign-info")) {
options.generate_foreign_info = 1;
}
+ else if (!strcmp(argv[i], "--no-type-info")) {
+ options.generate_type_info = 0;
+ }
else if (!strcmp(argv[i], "--no-std")) {
options.no_std = 1;
}
else if (!strcmp(argv[i], "-I")) {
bh_arr_push(options.included_folders, argv[++i]);
}
+ else if (!strncmp(argv[i], "-D", 2)) {
+ i32 len = strlen(argv[i]);
+ i32 j=2;
+ while (argv[i][j] != '=' && j < len) j++;
+
+ if (j < len) argv[i][j] = '\0';
+
+ DefinedVariable dv;
+ dv.key = argv[i] + 2;
+ dv.value = argv[i] + j + 1;
+ bh_arr_push(options.defined_variables, dv);
+ }
else if (!strcmp(argv[i], "-r") || !strcmp(argv[i], "--runtime")) {
i += 1;
if (!strcmp(argv[i], "onyx")) options.runtime = Runtime_Onyx;
return include_node;
}
+static void create_and_add_defined_variable(char *name, char *value) {
+ OnyxToken *value_token = bh_alloc_item(context.ast_alloc, OnyxToken);
+ value_token->text = value;
+ value_token->length = strlen(value);
+
+ OnyxToken *name_token = bh_alloc_item(context.ast_alloc, OnyxToken);
+ name_token->text = name;
+ name_token->length = strlen(name);
+
+ Package *p = package_lookup("runtime.vars");
+ assert(p);
+
+ AstStrLit *value_node = make_string_literal(context.ast_alloc, value_token);
+ add_entities_for_node(NULL, (AstNode *) value_node, NULL, NULL);
+
+ AstBinding *binding = onyx_ast_node_new(context.ast_alloc, sizeof(AstBinding), Ast_Kind_Binding);
+ binding->token = name_token;
+ binding->node = (AstNode *) value_node;
+
+ add_entities_for_node(NULL, (AstNode *) binding, p->scope, p);
+}
+
+static void introduce_defined_variables() {
+ bh_arr_each(DefinedVariable, dv, context.options->defined_variables) {
+ create_and_add_defined_variable(dv->key, dv->value);
+ }
+}
+
// HACK
static u32 special_global_entities_remaining = 3;
static Entity *runtime_info_types_entity;
context.builtins_initialized = 1;
initialize_builtins(context.ast_alloc);
introduce_build_options(context.ast_alloc);
+ introduce_defined_variables();
}
// GROSS
u64 alignment = type_alignment_of(effective_type);
u64 size = type_size_of(effective_type);
- if (type_table_node != NULL && (AstMemRes *) type_table_node == memres) {
- u64 table_location = build_type_table(mod);
- memres->data_id = table_location;
- return;
+ if (context.options->generate_type_info) {
+ if (type_table_node != NULL && (AstMemRes *) type_table_node == memres) {
+ u64 table_location = build_type_table(mod);
+ memres->data_id = table_location;
+ return;
+ }
+
+ if (tagged_procedures_node != NULL && (AstMemRes *) tagged_procedures_node == memres) {
+ u64 tagged_procedures_location = build_tagged_procedures(mod);
+ memres->data_id = tagged_procedures_location;
+ return;
+ }
}
if (foreign_blocks_node != NULL && (AstMemRes *) foreign_blocks_node == memres) {
return;
}
- if (tagged_procedures_node != NULL && (AstMemRes *) tagged_procedures_node == memres) {
- u64 tagged_procedures_location = build_tagged_procedures(mod);
- memres->data_id = tagged_procedures_location;
- return;
- }
-
if (memres->threadlocal) {
memres->tls_offset = mod->next_tls_offset;
bh_align(memres->tls_offset, alignment);
+++ /dev/null
-package core.clock
-
-#local runtime :: package runtime
-#if runtime.runtime != .Wasi
- && runtime.runtime != .Onyx {
- #error "'core.clock' is only available with the 'wasi' or 'onyx' runtimes.";
-}
-
-use wasi {package, *}
-
-time :: () -> u64 {
- output_time: Timestamp;
- clock_time_get(.Realtime, 500000, &output_time);
- return ~~(output_time / 1000000);
-}
-
-time_ns :: () -> u64 {
- output_time: Timestamp;
- clock_time_get(.Realtime, 1, &output_time);
- return ~~output_time;
-}
-
-sleep :: #match {
- (seconds: u64) { sleep(nanoseconds=seconds * 1000000000); },
- (milliseconds: u64) { sleep(nanoseconds=milliseconds * 1000000); },
-
- (nanoseconds: u64) {
- tagged: SubscriptionTagged;
- tagged.tag = .Clock;
- tagged.clock = .{
- id = .Realtime,
- timeout = cast(u64) nanoseconds,
- precision = 1,
- flags = ~~0,
- };
-
- subscription := Subscription.{
- userdata = 0,
- u = tagged,
- };
-
- event: Event;
- number_of_events: u32;
-
- error_code := poll_oneoff(&subscription, &event, 1, &number_of_events);
- }
-}
+++ /dev/null
-package core.env
-
-use runtime
-use core { Pair }
-use core.map
-use core.memory
-use core.string
-use wasi
-
-
-#if runtime.runtime != .Wasi
- && runtime.runtime != .Onyx {
- #error "'core.env' is only available with the 'wasi' and 'onyx' runtimes.";
-}
-
-use wasi { environ_get, environ_sizes_get, Size }
-
-Environment :: struct {
- vars : 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.from_cstr(env);
- var := string.read_until(&s, #char "=");
- map.put(&env_map, var, string.advance(s, 1));
- }
-
- // raw_free(allocator, env_var.data);
- memory.free_slice(&env_var, allocator);
-
- return .{
- vars = env_map,
- buffer = env_buf,
- buffer_allocator = allocator,
- };
-}
-
-free_env :: (use env: &Environment) {
- map.free(&vars);
-
- raw_free(buffer_allocator, buffer.data);
-}