#load "core/intrinsics/wasm"
use package core.intrinsics.wasm { memory_size, memory_grow }
-use package core.memory as memory
+#private_file memory :: package core.memory
// The global heap state
#private_file
use package core.alloc { heap_allocator }
heap_allocator.data = ^heap_state;
heap_allocator.func = heap_alloc_proc;
-}
\ No newline at end of file
+}
package core.io
-use package runtime as runtime
+#private_file runtime :: package 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."
}
u64 bh__table_hash_function(const char* str, i32 len, i32 mod) {
u64 hash = 5381;
i32 c, l = 0;
- if (len == 0) len = ((u32) 1 << 31) - 1; // TODO: Verify this is right
+ if (len == 0) len = ((u32) 1 << 31) - 1;
while ((c = *str++) && l++ < len) {
hash = (hash << 5) + hash + c;
Ast_Kind_Package,
Ast_Kind_Load_File,
Ast_Kind_Load_Path,
- Ast_Kind_Use_Package,
Ast_Kind_Alias,
Ast_Kind_Memres,
// Intruction Node
struct AstReturn { AstNode_base; AstTyped* expr; };
struct AstJump { AstNode_base; JumpType jump; u32 count; };
-struct AstUse { AstNode_base; AstTyped* expr; };
+struct AstUse {
+ AstNode_base;
+
+ AstTyped* expr;
+ bh_arr(AstAlias *) only;
+};
// Structure Nodes
struct AstBlock {
struct AstBinding { AstTyped_base; AstNode* node; };
struct AstMemRes { AstTyped_base; u64 addr; AstTyped *initial_value; };
struct AstInclude { AstNode_base; char* name; };
-struct AstUsePackage {
- AstNode_base;
-
- AstPackage *package;
-
- OnyxToken *alias;
- AstPackage *alias_node;
-
- bh_arr(AstAlias *) only;
-};
struct AstAlias {
AstNode_base;
OnyxToken *alias;
union {
AstDirectiveError *error;
AstInclude *include;
- AstUsePackage *use_package;
AstBinding *binding;
AstStaticIf *static_if;
AstFunction *function;
"PACKAGE",
"INCLUDE FILE",
"INCLUDE FOLDER",
- "USE PACKAGE",
"ALIAS",
"MEMORY RESERVATION",
case Ast_Kind_Enum_Value:
case Ast_Kind_Overloaded_Function:
case Ast_Kind_Polymorphic_Proc:
- case Ast_Kind_Use_Package:
return 0;
default: return 1;
case Ast_Kind_Package: return sizeof(AstPackage);
case Ast_Kind_Load_File: return sizeof(AstInclude);
case Ast_Kind_Load_Path: return sizeof(AstInclude);
- case Ast_Kind_Use_Package: return sizeof(AstUsePackage);
case Ast_Kind_Alias: return sizeof(AstAlias);
case Ast_Kind_Memres: return sizeof(AstMemRes);
case Ast_Kind_Binding: return sizeof(AstBinding);
break;
}
- case Ast_Kind_Use_Package: {
- ent.state = Entity_State_Comptime_Resolve_Symbols;
- ent.type = Entity_Type_Use_Package;
- ent.use_package = (AstUsePackage *) node;
- ENTITY_INSERT(ent);
- break;
- }
-
case Ast_Kind_Use: {
- ent.type = Entity_Type_Use;
+ if (((AstUse *) node)->expr->kind == Ast_Kind_Package) {
+ ent.state = Entity_State_Comptime_Resolve_Symbols;
+ ent.type = Entity_Type_Use_Package;
+ } else {
+ ent.type = Entity_Type_Use;
+ }
+
ent.use = (AstUse *) node;
ENTITY_INSERT(ent);
break;
static void unconsume_token(OnyxParser* parser) {
if (parser->hit_unexpected_token) return;
- // TODO: This is probably wrong
while (parser->prev->type == Token_Type_Comment) parser->prev--;
parser->curr = parser->prev;
parser->prev--;
static AstNode* parse_use_stmt(OnyxParser* parser) {
OnyxToken* use_token = expect_token(parser, Token_Type_Keyword_Use);
+ AstUse* use_node = make_node(AstUse, Ast_Kind_Use);
+ use_node->token = use_token;
+ use_node->expr = parse_expression(parser, 1);
- if (parser->curr->type == Token_Type_Keyword_Package) {
- AstUsePackage* upack = make_node(AstUsePackage, Ast_Kind_Use_Package);
- upack->token = use_token;
- upack->package = parse_package_expression(parser);
-
- if (consume_token_if_next(parser, Token_Type_Keyword_As))
- upack->alias = expect_token(parser, Token_Type_Symbol);
-
- if (consume_token_if_next(parser, '{')) {
- bh_arr_new(global_heap_allocator, upack->only, 4);
+ if (consume_token_if_next(parser, '{')) {
+ bh_arr_new(global_heap_allocator, use_node->only, 4);
- while (!consume_token_if_next(parser, '}')) {
- if (parser->hit_unexpected_token) return NULL;
+ while (!consume_token_if_next(parser, '}')) {
+ if (parser->hit_unexpected_token) return NULL;
- AstAlias* alias = make_node(AstAlias, Ast_Kind_Alias);
- alias->token = expect_token(parser, Token_Type_Symbol);
+ AstAlias* alias = make_node(AstAlias, Ast_Kind_Alias);
+ alias->token = expect_token(parser, Token_Type_Symbol);
- if (consume_token_if_next(parser, Token_Type_Keyword_As))
- alias->alias = expect_token(parser, Token_Type_Symbol);
- else
- alias->alias = alias->token;
+ if (consume_token_if_next(parser, Token_Type_Keyword_As))
+ alias->alias = expect_token(parser, Token_Type_Symbol);
+ else
+ alias->alias = alias->token;
- bh_arr_push(upack->only, alias);
+ bh_arr_push(use_node->only, alias);
- if (parser->curr->type != '}')
- expect_token(parser, ',');
- }
+ if (parser->curr->type != '}')
+ expect_token(parser, ',');
}
-
- ENTITY_SUBMIT(upack);
+ }
+
+ if (use_node->expr->kind == Ast_Kind_Package) {
+ ENTITY_SUBMIT(use_node);
return NULL;
} else {
- AstUse* use_node = make_node(AstUse, Ast_Kind_Use);
- use_node->token = use_token;
- use_node->expr = parse_expression(parser, 1);
return (AstNode *) use_node;
}
}
parser->file_scope = scope_create(parser->allocator, parser->package->private_scope, parser->tokenizer->tokens[0].pos);
bh_arr_push(parser->scope_stack, parser->file_scope);
- AstUsePackage* implicit_use_builtin = make_node(AstUsePackage, Ast_Kind_Use_Package);
+ AstUse* implicit_use_builtin = make_node(AstUse, Ast_Kind_Use);
AstPackage* implicit_builtin_package = make_node(AstPackage, Ast_Kind_Package);
implicit_builtin_package->package_name = "builtin";
- implicit_use_builtin->package = implicit_builtin_package;
+ implicit_use_builtin->expr = (AstTyped *) implicit_builtin_package;
ENTITY_SUBMIT(implicit_use_builtin);
while (parser->curr->type != Token_Type_End_Stream) {
static SymresStatus symres_function(AstFunction* func);
static SymresStatus symres_global(AstGlobal* global);
static SymresStatus symres_overloaded_function(AstOverloadedFunction* ofunc);
-static SymresStatus symres_use_package(AstUsePackage* package);
static SymresStatus symres_package(AstPackage* package);
static SymresStatus symres_enum(AstEnumType* enum_node);
static SymresStatus symres_memres_type(AstMemRes** memres);
return Symres_Success;
}
+// CLEANUP: A lot of duplication going on in this function. A proper
+// "namespace" concept would be useful to remove a lot of the fluff
+// code here. There already is try_resolve_symbol_from_node which
+// may be able to do what is needed here?
static SymresStatus symres_use(AstUse* use) {
SYMRES(expression, &use->expr);
if (use->expr->kind == Ast_Kind_Package) {
AstPackage* package = (AstPackage *) use->expr;
- scope_include(curr_scope, package->package->scope, use->token->pos);
+ SYMRES(package, package);
+
+ if (package->package->scope == curr_scope) return Symres_Success;
+
+ if (use->only == NULL) {
+ OnyxFilePos pos = { 0 };
+ if (use->token != NULL)
+ pos = use->token->pos;
+
+ scope_include(curr_scope, package->package->scope, pos);
+
+ } else {
+ bh_arr_each(AstAlias *, alias, use->only) {
+ AstNode* thing = symbol_resolve(package->package->scope, (*alias)->token);
+ if (thing == NULL) { // :SymresStall
+ if (report_unresolved_symbols) {
+ onyx_report_error((*alias)->token->pos,
+ "The symbol '%b' was not found in this package.",
+ (*alias)->token->text, (*alias)->token->length);
+ return Symres_Error;
+ } else {
+ return Symres_Yield_Macro;
+ }
+ }
+
+ symbol_introduce(curr_scope, (*alias)->alias, thing);
+ }
+ }
+
return Symres_Success;
}
if (use->expr->kind == Ast_Kind_Struct_Type) {
AstStructType* st = (AstStructType *) use->expr;
+ if (!st->scope) return Symres_Success;
- if (st->scope)
+ if (use->only == NULL) {
scope_include(curr_scope, st->scope, use->token->pos);
+ } else {
+ bh_arr_each(AstAlias *, alias, use->only) {
+ AstNode* thing = symbol_resolve(st->scope, (*alias)->token);
+ if (thing == NULL) {
+ onyx_report_error((*alias)->token->pos,
+ "The symbol '%b' was not found in this scope.",
+ (*alias)->token->text, (*alias)->token->length);
+ return Symres_Error;
+ }
+
+ symbol_introduce(curr_scope, (*alias)->alias, thing);
+ }
+ }
+
return Symres_Success;
}
SYMRES(use, (AstUse *) *stmt);
break;
- case Ast_Kind_Use_Package:
- if (remove) *remove = 1;
- // This is handled by an entity now.
- // SYMRES(use_package, (AstUsePackage *) *stmt);
- break;
-
default: SYMRES(expression, (AstTyped **) stmt); break;
}
return Symres_Success;
}
-static SymresStatus symres_use_package(AstUsePackage* package) {
- SYMRES(package, package->package);
-
- // CLEANUP: Oofta that name
- Package* p = package->package->package;
-
- if (p->scope == curr_scope) return Symres_Success;
-
- if (package->alias != NULL) {
- if (!package->alias_node) {
- package->alias_node = onyx_ast_node_new(context.ast_alloc, sizeof(AstPackage), Ast_Kind_Package);
- package->alias_node->package = p;
- package->alias_node->token = package->alias;
- }
-
- symbol_introduce(curr_scope, package->alias, (AstNode *) package->alias_node);
- }
-
- if (package->only != NULL) {
- bh_arr_each(AstAlias *, alias, package->only) {
-
- AstNode* thing = symbol_resolve(p->scope, (*alias)->token);
- if (thing == NULL) { // :SymresStall
- if (report_unresolved_symbols) {
- onyx_report_error((*alias)->token->pos, "This symbol was not found in this package.");
- return Symres_Error;
- } else {
- return Symres_Yield_Macro;
- }
- }
-
- symbol_introduce(curr_scope, (*alias)->alias, thing);
- }
- }
-
- if (package->alias == NULL && package->only == NULL) {
- OnyxFilePos pos = { 0 };
- if (package->token != NULL)
- pos = package->token->pos;
-
- scope_include(curr_scope, p->scope, pos);
- }
-
- return Symres_Success;
-}
-
static SymresStatus symres_package(AstPackage* package) {
if (package->package == NULL) {
if (!package->package_name) return Symres_Error;
case Entity_Type_Foreign_Global_Header:
case Entity_Type_Global_Header: ss = symres_global(ent->global); break;
- case Entity_Type_Use_Package: ss = symres_use_package(ent->use_package);
- if (ent->use_package->package && ent->use_package->package->package)
- package_track_use_package(ent->use_package->package->package, ent);
+ case Entity_Type_Use_Package: ss = symres_use(ent->use);
+ if (ent->use->expr && ((AstPackage *) ent->use->expr)->package)
+ package_track_use_package(((AstPackage *) ent->use->expr)->package, ent);
next_state = Entity_State_Finalized;
break;
type_idx = bh_table_get(i32, mod->type_map, type_repr_buf);
} else {
// NOTE: Make a new type
- // TODO: Ensure that this isn't going to break things because of alignment
WasmFuncType* type = (WasmFuncType*) bh_alloc(mod->allocator, sizeof(WasmFuncType) + sizeof(WasmType) * param_count);
type->return_type = return_type;
type->param_count = param_count;
#load "core/std"
use package core
-use package core.string.reader as reader
+reader :: package core.string.reader
count_ending_paths :: (nums: [..] u32) -> u64 {
tally := array.make(u64, nums.count);
#load "core/std"
use package core
-use package core.string.reader as reader
+reader :: package core.string.reader
GameOfSeats :: struct {
width : u32;
#load "core/std"
use package core
-use package core.string.reader as reader
+reader :: package core.string.reader
Ship :: struct {
x : i32 = 0;
#load "core/std"
use package core
-use package core.string.reader as reader
+reader :: package core.string.reader
inv_mod :: (a_: i64, m_: i64) -> i64 {
if m_ <= 1 do return 0;
#load "core/std"
use package core
-use package core.string.reader as reader
+reader :: package core.string.reader
MASK_SIZE :: 36
Bitmask :: #type [MASK_SIZE] u8;
#load "core/std"
use package core
-use package core.string.reader as reader
+reader :: package core.string.reader
initial_numbers := u32.[ 1, 20, 8, 12, 0, 14 ];
#load "core/std"
use package core
-use package core.string.reader as reader
+reader :: package core.string.reader
Field :: struct {
name : str = "";
#load "core/std"
use package core
-use package core.string.reader as reader
+reader :: package core.string.reader
CubePos :: struct {
x, y, z, w : i32;
#load "core/std"
use package core
-use package core.string.reader as reader
+reader :: package core.string.reader
parse_factor :: (file: ^reader.StringReader) -> u64 {
reader.skip_whitespace(file);
#load "core/std"
use package core
-use package core.string.reader as reader
+reader :: package core.string.reader
// nt -> t
Term :: struct {
#load "core/std"
use package core
-use package core.string.reader as reader
+reader :: package core.string.reader
TILE_DATA_WIDTH :: 10
TILE_DATA_HEIGHT :: 10
#load "core/std"
use package core
-use package core.string.reader as reader
+reader :: package core.string.reader
/*
What questions the data layout needs to answer easily:
#load "core/std"
use package core
-use package core.string.reader as reader
+reader :: package core.string.reader
key_arena : alloc.arena.ArenaState;
key_alloc : Allocator;
// 4,5,2,8,|1,3,9,7,
// Larger numbers are encoded in base 64.
encode_hands :: (alloc: Allocator, p1: ^[..] u32, p2: ^[..] u32) -> str {
- use package core.string.builder as b
+ b :: package core.string.builder
builder := b.make(256, alloc);
for n: *p1 {
#load "core/std"
use package core
-use package core.string.reader as reader
+reader :: package core.string.reader
power_mod :: (base: u32, exp: u32, mod: u32) -> u32 {
t: u64 = 1;
#load "core/std"
use package core
-use package core.string.reader as reader
+reader :: package core.string.reader
BagGraph :: struct {
nodes : [..] ^BagNode;
#load "core/std"
use package core
-use package core.string.reader as reader
+reader :: package core.string.reader
OpCode :: enum (u16) {
Nop; Acc; Jmp;
#load "core/std"
use package core
-use package core.string.reader as reader
+reader :: package core.string.reader
find_contiguous_subarray_with_sum :: (nums: [..] u64, sum: u64) -> (i32, i32) {
start := 0;