`#import` will be removed soon.
\
NODE(Return) \
NODE(Jump) \
- NODE(Use) \
\
NODE(Block) \
NODE(IfWhile) \
Ast_Kind_For,
Ast_Kind_While,
Ast_Kind_Jump,
- Ast_Kind_Use,
+ // Ast_Kind_Use,
Ast_Kind_Defer,
Ast_Kind_Switch,
Ast_Kind_Switch_Case,
struct AstReturn { AstNode_base; AstTyped* expr; u32 count; }; // Note: This count is one less than it should be, because internal codegen with macros would have to know about this and that is error prone.
struct AstJump { AstNode_base; JumpType jump; u32 count; };
-typedef struct QualifiedUse {
- OnyxToken* symbol_name;
- OnyxToken* as_name;
-} QualifiedUse;
-struct AstUse {
- AstNode_base;
-
- AstTyped* expr;
- bh_arr(QualifiedUse) only;
-};
+// typedef struct QualifiedUse {
+// OnyxToken* symbol_name;
+// OnyxToken* as_name;
+// } QualifiedUse;
+// struct AstUse {
+// AstNode_base;
+//
+// AstTyped* expr;
+// bh_arr(QualifiedUse) only;
+// };
// Structure Nodes
struct AstBlock {
Package* package;
};
+typedef struct QualifiedImport {
+ OnyxToken* symbol_name;
+ OnyxToken* as_name;
+} QualifiedImport;
+
struct AstImport {
AstNode_base;
AstPackage *imported_package;
- AstUse *implicit_use_node;
+ bh_arr(QualifiedImport) only;
+
+ // When true, it means a list of imports
+ // was specified and the top-level package
+ // should not be imported.
+ b32 specified_imports;
+
+ // When true, even if a list of specified
+ // imports was given, the package name should
+ // also be imported.
+ //
+ // use core {package, *}
+ //
+ b32 also_import_package;
};
AstPolyQuery *poly_query;
AstForeignBlock *foreign_block;
AstMacro *macro;
- AstUse *use;
AstInterface *interface;
AstConstraint *constraint;
AstDirectiveLibrary *library;
"FOR",
"WHILE",
"JUMP",
- "USE",
+ // "USE",
"DEFER",
"SWITCH",
"CASE",
case Ast_Kind_For: return sizeof(AstFor);
case Ast_Kind_While: return sizeof(AstIfWhile);
case Ast_Kind_Jump: return sizeof(AstJump);
- case Ast_Kind_Use: return sizeof(AstUse);
case Ast_Kind_Defer: return sizeof(AstDefer);
case Ast_Kind_Switch: return sizeof(AstSwitch);
case Ast_Kind_Switch_Case: return sizeof(AstSwitchCase);
break;
}
- case Ast_Kind_Use:
- C(AstUse, expr);
- break;
-
case Ast_Kind_Directive_Solidify: {
AstDirectiveSolidify* dd = (AstDirectiveSolidify *) nn;
AstDirectiveSolidify* sd = (AstDirectiveSolidify *) node;
break;
}
- case Ast_Kind_Use: {
- if (((AstUse *) node)->expr->kind == Ast_Kind_Package) {
- ent.state = Entity_State_Resolve_Symbols;
- ent.type = Entity_Type_Use_Package;
- } else {
- ent.type = Entity_Type_Use;
- }
-
- ent.use = (AstUse *) node;
- ENTITY_INSERT(ent);
- break;
- }
-
case Ast_Kind_Memres: {
ent.type = Entity_Type_Memory_Reservation_Type;
ent.mem_res = (AstMemRes *) node;
static AstSwitch* parse_switch_stmt(OnyxParser* parser);
static i32 parse_possible_symbol_declaration(OnyxParser* parser, AstNode** ret);
static AstReturn* parse_return_stmt(OnyxParser* parser);
-static AstNode* parse_use_stmt(OnyxParser* parser);
static AstBlock* parse_block(OnyxParser* parser, b32 make_a_new_scope, char* block_name);
static AstNode* parse_statement(OnyxParser* parser);
static void parse_polymorphic_variable(OnyxParser* parser, AstType*** next_insertion);
return return_node;
}
-static b32 parse_use_stmt_internal(OnyxParser* parser, AstUse* use_node) {
- if (consume_token_if_next(parser, '{')) {
- if (next_tokens_are(parser, 2, '*', '}')) {
- consume_tokens(parser, 2);
- return 1;
- }
-
- bh_arr_new(global_heap_allocator, use_node->only, 4);
- while (!consume_token_if_next(parser, '}')) {
- if (parser->hit_unexpected_token) return 0;
-
- QualifiedUse qu;
- qu.as_name = expect_token(parser, Token_Type_Symbol);
- qu.symbol_name = qu.as_name;
-
- if (consume_token_if_next(parser, ':')) {
- expect_token(parser, ':');
- qu.symbol_name = expect_token(parser, Token_Type_Symbol);
- }
-
- bh_arr_push(use_node->only, qu);
-
- if (parser->curr->type != '}')
- expect_token(parser, ',');
- }
- }
-
- return 1;
-}
-
-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 (!use_node->expr) return NULL;
-
- if (!parse_use_stmt_internal(parser, use_node)) return NULL;
-
- if (use_node->expr->kind == Ast_Kind_Package) {
- ENTITY_SUBMIT(use_node);
- return NULL;
-
- } else {
- return (AstNode *) use_node;
- }
-}
-
static AstNode* parse_jump_stmt(OnyxParser* parser, TokenType token_type, JumpType jump_type) {
AstJump* jnode = make_node(AstJump, Ast_Kind_Jump);
jnode->token = expect_token(parser, token_type);
case Token_Type_Keyword_Use: {
needs_semicolon = 0;
- retval = (AstNode *) parse_use_stmt(parser);
+ OnyxToken *use_token = expect_token(parser, Token_Type_Keyword_Use);
+ parse_import_statement(parser, use_token);
+
break;
}
switch ((u16) parser->curr->type) {
case Token_Type_Keyword_Use: {
- AstNode* use_node = parse_use_stmt(parser);
- if (use_node) ENTITY_SUBMIT(use_node);
+ OnyxToken *use_token = expect_token(parser, Token_Type_Keyword_Use);
+ parse_import_statement(parser, use_token);
return;
}
if (!parse_package_name(parser, package_node)) return;
- if (parser->curr->type == '{') {
- AstUse *use_node = make_node(AstUse, Ast_Kind_Use);
- use_node->token = token;
- use_node->expr = (AstTyped *) package_node;
+ AstImport *import_node = make_node(AstImport, Ast_Kind_Import);
+ import_node->flags |= Ast_Flag_Comptime;
+ import_node->token = token;
+ import_node->imported_package = package_node;
+ import_node->also_import_package = 1;
- if (!parse_use_stmt_internal(parser, use_node)) return;
+ if (consume_token_if_next(parser, '{')) {
+ import_node->specified_imports = 1;
+ import_node->also_import_package = 0;
- ENTITY_SUBMIT(use_node);
+ if (consume_token_if_next(parser, Token_Type_Keyword_Package)) {
+ import_node->also_import_package = 1;
+ if (parser->curr->type != '}')
+ expect_token(parser, ',');
+ }
- } else {
- AstImport* import_node = make_node(AstImport, Ast_Kind_Import);
- import_node->flags |= Ast_Flag_Comptime;
- import_node->token = token;
- import_node->imported_package = package_node;
+ if (next_tokens_are(parser, 2, '*', '}')) {
+ consume_tokens(parser, 2);
+ goto import_parsed;
+ }
- ENTITY_SUBMIT(import_node);
+ bh_arr_new(global_heap_allocator, import_node->only, 4);
+ while (!consume_token_if_next(parser, '}')) {
+ if (parser->hit_unexpected_token) return;
+
+ QualifiedImport qi;
+ qi.as_name = expect_token(parser, Token_Type_Symbol);
+ qi.symbol_name = qi.as_name;
+
+ if (consume_token_if_next(parser, ':')) {
+ expect_token(parser, ':');
+ qi.symbol_name = expect_token(parser, Token_Type_Symbol);
+ }
+
+ bh_arr_push(import_node->only, qi);
+
+ if (parser->curr->type != '}')
+ expect_token(parser, ',');
+ }
}
+
+ import_parsed:
+ ENTITY_SUBMIT(import_node);
}
static Package* parse_file_package(OnyxParser* parser) {
static SymresStatus symres_for(AstFor* fornode);
static SymresStatus symres_case(AstSwitchCase *casenode);
static SymresStatus symres_switch(AstSwitch* switchnode);
-static SymresStatus symres_use(AstUse* use);
static SymresStatus symres_directive_solidify(AstDirectiveSolidify** psolid);
static SymresStatus symres_directive_defined(AstDirectiveDefined** pdefined);
static SymresStatus symres_directive_insert(AstDirectiveInsert* insert);
return Symres_Success;
}
-static SymresStatus symres_use(AstUse* use) {
- SYMRES(expression, &use->expr);
-
- AstTyped *use_expr = (AstTyped *) strip_aliases((AstNode *) use->expr);
-
- Scope* used_scope = NULL;
-
- // :EliminatingSymres
- if (use_expr->kind == Ast_Kind_Package) {
- AstPackage* package = (AstPackage *) use_expr;
- SYMRES(package, package);
-
- if (!use->entity) {
- add_entities_for_node(NULL, (AstNode *) use, current_scope, NULL);
- }
-
- package_track_use_package(package->package, use->entity);
- used_scope = package->package->scope;
- }
-
- if (use_expr->kind == Ast_Kind_Foreign_Block) {
- AstForeignBlock* fb = (AstForeignBlock *) use_expr;
- if (fb->entity->state <= Entity_State_Resolve_Symbols) return Symres_Yield_Macro;
-
- used_scope = fb->scope;
- }
-
- if (use_expr->kind == Ast_Kind_Enum_Type) {
- AstEnumType* et = (AstEnumType *) use_expr;
- used_scope = et->scope;
- }
-
- if (use_expr->kind == Ast_Kind_Struct_Type) {
- AstStructType* st = (AstStructType *) use_expr;
- if (!st->scope) return Symres_Success;
-
- used_scope = st->scope;
- }
-
- if (used_scope) {
- if (used_scope == current_scope) return Symres_Success;
-
- if (use->only == NULL) {
- OnyxFilePos pos = { 0 };
- if (use->token != NULL)
- pos = use->token->pos;
-
- scope_include(current_scope, used_scope, pos);
-
- } else {
- bh_arr_each(QualifiedUse, qu, use->only) {
- AstNode* thing = symbol_resolve(used_scope, qu->symbol_name);
- if (thing == NULL) { // :SymresStall
- if (report_unresolved_symbols) {
- onyx_report_error(qu->symbol_name->pos, Error_Critical,
- "The symbol '%b' was not found in the used scope.",
- qu->symbol_name->text, qu->symbol_name->length);
- return Symres_Error;
- } else {
- return Symres_Yield_Macro;
- }
- }
-
- symbol_introduce(current_scope, qu->as_name, thing);
- }
- }
-
- return Symres_Success;
- }
-
- if (use_expr->type_node == NULL && use_expr->type == NULL) goto cannot_use;
-
- // :EliminatingSymres
- AstType* effective_type = use_expr->type_node;
- if (effective_type->kind == Ast_Kind_Pointer_Type)
- effective_type = ((AstPointerType *) effective_type)->elem;
-
- if (effective_type->kind == Ast_Kind_Struct_Type ||
- effective_type->kind == Ast_Kind_Poly_Call_Type) {
-
- if (use_expr->type == NULL)
- use_expr->type = type_build_from_ast(context.ast_alloc, use_expr->type_node);
- if (use_expr->type == NULL) goto cannot_use;
-
- Type* st = use_expr->type;
- if (st->kind == Type_Kind_Pointer)
- st = st->Pointer.elem;
-
- fori (i, 0, shlen(st->Struct.members)) {
- StructMember* value = st->Struct.members[i].value;
- AstFieldAccess* fa = make_field_access(context.ast_alloc, use_expr, value->name);
- symbol_raw_introduce(current_scope, value->name, use->token->pos, (AstNode *) fa);
- }
-
- return Symres_Success;
- }
-
-cannot_use:
- onyx_report_error(use->token->pos, Error_Critical, "Cannot use this because its type is unknown.");
- return Symres_Error;
-}
-
static SymresStatus symres_directive_solidify(AstDirectiveSolidify** psolid) {
AstDirectiveSolidify* solid = *psolid;
SYMRES(local, (AstLocal **) stmt);
break;
- case Ast_Kind_Use:
- if (remove) *remove = 1;
- SYMRES(use, (AstUse *) *stmt);
- break;
-
case Ast_Kind_Import:
if (remove) *remove = 1;
break;
}
static SymresStatus symres_import(AstImport* import) {
- SYMRES(package, import->imported_package);
+ AstPackage* package = import->imported_package;
+ SYMRES(package, package);
+
+ if (import->also_import_package) {
+ symbol_introduce(
+ current_entity->scope,
+ bh_arr_last(package->path),
+ (AstNode *) package);
+ }
+
+ if (import->specified_imports) {
+ package_track_use_package(package->package, import->entity);
- symbol_introduce(
- current_entity->scope,
- bh_arr_last(import->imported_package->path),
- (AstNode *) import->imported_package);
+ Scope *import_scope = package->package->scope;
+ if (import_scope == current_scope) return Symres_Complete;
+
+ // use X { * }
+ if (import->only == NULL) {
+ OnyxFilePos pos = import->token->pos;
+ scope_include(current_scope, import_scope, pos);
+ return Symres_Complete;
+ }
+
+
+ // use X { a, b, c }
+ bh_arr_each(QualifiedImport, qi, import->only) {
+ AstNode* imported = symbol_resolve(import_scope, qi->symbol_name);
+ if (imported == NULL) { // :SymresStall
+ if (report_unresolved_symbols) {
+ // TODO: Change package->name to package->qualified_name when
+ // merged with the documentation generation branch.
+ onyx_report_error(qi->symbol_name->pos, Error_Critical,
+ "The symbol '%b' was not found the package '%s'.",
+ qi->symbol_name->text, qi->symbol_name->length, package->package->name);
+
+ return Symres_Error;
+ } else {
+ return Symres_Yield_Macro;
+ }
+ }
+
+ symbol_introduce(current_scope, qi->as_name, imported);
+ }
+ }
return Symres_Complete;
}
case Entity_Type_Global_Header: ss = symres_global(ent->global); break;
- case Entity_Type_Use_Package:
- case Entity_Type_Use: ss = symres_use(ent->use);
- next_state = Entity_State_Finalized;
- break;
-
case Entity_Type_Import: ss = symres_import(ent->import); break;
#if runtime.runtime != .Custom {
#local default_logger_proc :: (logger: &Default_Logger, level: Log_Level, msg: str, module: str) {
- #import core;
+ use core;
if level < logger.minimum_level do return;
// This cannot be used in a custom runtime, as the other core
// packages are not included.
#if runtime.runtime != .Custom {
- #import core
- #import core.memory
+ use core
+ use core.memory
new :: #match #local {}
package core.conv
-#import core.map
-#import core.string
-#import core.array
-#import core.math
-#import core.io
-#import runtime
+use core.map
+use core.string
+use core.array
+use core.math
+use core.io
+use runtime
#package {
custom_formatters: Map(type_expr, #type (&Format_Output, &Format, rawptr) -> void);
map.init(&custom_parsers, default=null_proc);
#if Enable_Custom_Formatters {
- use runtime.info;
+ use runtime.info {*};
for type_idx: type_table.count {
type := type_table[type_idx];
// If a custom formatter is specified for the type, that is used instead.
// This procedure is generally not used directly; instead, through format or format_va.
format_any :: (output: &Format_Output, formatting: &Format, v: any) {
- use runtime.info;
+ use runtime.info {*};
//
// Dereference the any if the '*' format specifier was given.
return custom_parsers[data_type](target, to_parse, string_allocator);
}
- use runtime.info;
+ use runtime.info {*};
info := get_type_info(data_type);
switch data_type {
package core.encoding.osad
-#import core.io
-#import core.string
-#import core.array
-#import core.memory
-#import runtime
+use core.io
+use core.string
+use core.array
+use core.memory
+use runtime
use runtime {
type_info :: info
package core.io
-#import core
use core
+use core {*}
Stream :: struct {
use vtable : &Stream_Vtable;
package core.math
-#import core
-#import core.intrinsics.wasm
+use core
+use core.intrinsics.wasm
// Things that are useful in any math library:
// - Trigonometry
package core.memory
+use core
+
//
// Re-exports the memory_copy intrinsics. Behaves like memmove() in C.
copy :: core.intrinsics.wasm.memory_copy
// false and are true if one or more of the option values are present.
//
-#import core
-#import core.iter
-#import core.conv
-#import core.string
-#import runtime
-
-use core {printf}
+use core {package, printf}
+use core.iter
+use core.conv
+use core.string
+use runtime
arg_parse :: (c_args: [] cstr, output: any) -> bool {
arg_iter := iter.as_iter(c_args)
|> iter.map(string.from_cstr);
defer arg_iter.close(arg_iter.data);
- use runtime.info;
+ use runtime.info {*};
ptr_type := cast(&Type_Info_Pointer) get_type_info(output.type);
if ptr_type.kind != .Pointer do return false;
#error "Cannot include this file. Platform not supported.";
}
-#import core
-#import runtime
-
-use core
+use core {*}
+use runtime
Socket :: struct {
Handle :: #distinct i32
#error "Cannot include this file. Platform not supported.";
}
-#import core
-#import runtime
-
-use core
+use core {*}
+use runtime
#local fs :: runtime.platform
package runtime
-#import core
-
-use core
+use core {package, *}
use core.intrinsics.onyx { __initialize }
-use platform { __output_string }
+use runtime.platform { __output_string }
//
// Export the __start function from the platform layer.
package runtime.platform
-#import core
-#import runtime
-
use core
+use runtime
use runtime {
__runtime_initialize,
Multi_Threading_Enabled,
package runtime.platform
-#import core
-use core
+#import core {*}
FileData :: #distinct i64
DirectoryData :: #distinct u64
package runtime.platform
-#import core
-#import runtime
-#import main
-
-use core
+use main
+use core {package, *}
use runtime {
+ package,
__runtime_initialize,
Multi_Threading_Enabled,
_thread_start,
package core.string
-#import core
-
-use core
+use core {package, *}
#doc "Generic procedure for turning something into a string."
as_str :: #match -> str {}
package core.sync
-#import runtime
-#import core
-
-use core.intrinsics.atomics
+use runtime
+use core
+use core.intrinsics.atomics {*}
use core.thread { Thread_ID }
//
package core.thread
-#import core
-#import runtime
-
-use core
-use core.intrinsics.atomics
+use runtime
+use core {*}
+use core.intrinsics.atomics {*}
#package {
thread_mutex : sync.Mutex;
package core.time
-#import core
-#import runtime
-use core
+use core {package, *}
+use runtime
Date :: struct {
year: i32;
}
strptime :: (buf_: [] u8, format_: [] u8, tm: &Timestamp) -> bool {
- use core
+ use core {*}
#persist weekdays := str.[ "sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday" ];
#persist monthnames := str.[ "january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december" ];
#load "core/std"
-#import core
-#import runtime
-
-use core
+use runtime
+use core {package, *}
use core.intrinsics.onyx { init }
Color :: enum {
iter.parallel_for(cases, settings.threads, &exec_context) {
// Weird macros mean I have to forward external names
- use core
+ use core {*}
print_color :: print_color;
args: [] str;
-#load "core/std"
-
-#import core
-use core
+use core {package, *}
GameOfSeats :: struct {
width : u32;
#load "core/std"
-#import core
-use core
+use core {package, *}
OverloadsEqual :: interface (t: $T) {
{ T.equals(t, t) } -> bool;
PART :: 2
-#import core
-
-use core
+use core {package, *}
use core.alloc {arena}
num_allocator: Allocator;
-#import core
-use core
+use core {package, *}
PART :: 1
-#import core
-use core
+use core {package, *}
f :: ctx => {
x, y := 123, 456.0f;
-#import core
-use core
+use core {package, *}
q :: (v: &$C, g: (&C) -> $T) {
println(*v);
-#import core
-use core
+use core {package, *}
Foo :: struct {
use vtable: &VTable;
}
{
- use SomeNamespace;
+ // This is no longer a feature, and cannot be used anymore
+ // use SomeNamespace;
- foo();
+ SomeNamespace.foo();
}
}
\ No newline at end of file
-#import core
-use core
+use core {*}
main :: () {
#load "core/std"
-#import core
-use core
+use core {*}
main :: (args: [] cstr) {
println("Hello, World!");
#load "core/std"
-#import core
-use core {println, printf}
+use core {package, println, printf}
some_function :: () -> f32 {
println("In some function!");
#load "core/std"
-#import core
-use core
+use core {package, *}
foo :: () -> (i32, i32) {
return 50, 60;
{
BasicallyANamespace.function_3();
- use BasicallyANamespace;
- function_2();
+ // TODO: Revisit this test case when `use struct` is added.
+ // use BasicallyANamespace;
+ BasicallyANamespace.function_2();
- use SubNamespace;
- function_4();
+ // use SubNamespace;
+ BasicallyANamespace.SubNamespace.function_4();
}
// No types are written throughout this entire program.
//
-#load "core/std"
-
-#import core
-use core
+use core {*}
main :: () {
object := .{
ss: SimpleStruct = SimpleStruct.{ 41, 67, "Steve" };
- use ss;
printf("SimpleStruct<{}, {}>({}, {}, {})\n",
sizeof SimpleStruct,
alignof SimpleStruct,
- cast(u32) age, height, name);
+ cast(u32) ss.age, ss.height, ss.name);
}
test_simple_union :: () {