* Added println to core library; print followed by a newline.
* Added tests/ folder and runtests.sh which will compile and execute the programs in the
folder and test against their expected output.
+* #private_file for specifying symbols at the file scope
Removals:
Changes:
+* BREAKING: 'use package' now places included symbols at the file scope, not package scope.
* Switched to using TCC as the primary compiler, while maintaining support for GCC.
* boolean literals are compile time known so they can be used at top level.
// Private symbols
//
-#private
+#private_file
I32MapLookupResult :: struct {
hash_index : i32 = -1;
entry_index : i32 = -1;
entry_prev : i32 = -1;
}
-#private
+#private_file
i32map_lookup :: proc (use imap: ^I32Map($T), key: i32) -> I32MapLookupResult {
lr := I32MapLookupResult.{};
// Private symbols
//
-#private
+#private_file
PtrMapLookupResult :: struct {
hash_index : i32 = -1;
entry_index : i32 = -1;
entry_prev : i32 = -1;
}
-#private
+#private_file
ptrmap_lookup :: proc (use pmap: ^PtrMap, key: rawptr) -> PtrMapLookupResult {
lr := PtrMapLookupResult.{};
Ast_Flag_Const = BH_BIT(3),
Ast_Flag_Comptime = BH_BIT(4),
Ast_Flag_Private_Package = BH_BIT(5),
+ Ast_Flag_Private_File = BH_BIT(6),
// Global flags
- Ast_Flag_Global_Stack_Top = BH_BIT(6),
- Ast_Flag_Global_Stack_Base = BH_BIT(7),
+ Ast_Flag_Global_Stack_Top = BH_BIT(7),
+ Ast_Flag_Global_Stack_Base = BH_BIT(8),
// Function flags
- Ast_Flag_Inline = BH_BIT(8),
- Ast_Flag_Intrinsic = BH_BIT(9),
- Ast_Flag_Function_Used = BH_BIT(10),
- Ast_Flag_No_Stack = BH_BIT(11),
+ Ast_Flag_Inline = BH_BIT(9),
+ Ast_Flag_Intrinsic = BH_BIT(10),
+ Ast_Flag_Function_Used = BH_BIT(11),
+ Ast_Flag_No_Stack = BH_BIT(12),
// Expression flags
- Ast_Flag_Expr_Ignored = BH_BIT(12),
- Ast_Flag_Param_Use = BH_BIT(13),
- Ast_Flag_Address_Taken = BH_BIT(14),
+ Ast_Flag_Expr_Ignored = BH_BIT(13),
+ Ast_Flag_Param_Use = BH_BIT(14),
+ Ast_Flag_Address_Taken = BH_BIT(15),
// Type flags
- Ast_Flag_Type_Is_Resolved = BH_BIT(15),
+ Ast_Flag_Type_Is_Resolved = BH_BIT(16),
// Enum flags
- Ast_Flag_Enum_Is_Flags = BH_BIT(16),
+ Ast_Flag_Enum_Is_Flags = BH_BIT(17),
// Struct flags
- Ast_Flag_Struct_Is_Union = BH_BIT(17),
+ Ast_Flag_Struct_Is_Union = BH_BIT(18),
- Ast_Flag_No_Clone = BH_BIT(18),
+ Ast_Flag_No_Clone = BH_BIT(19),
- Ast_Flag_Cannot_Take_Addr = BH_BIT(19),
+ Ast_Flag_Cannot_Take_Addr = BH_BIT(20),
- Ast_Flag_Arg_Is_VarArg = BH_BIT(20),
+ Ast_Flag_Arg_Is_VarArg = BH_BIT(21),
- Ast_Flag_Struct_Mem_Used = BH_BIT(21),
+ Ast_Flag_Struct_Mem_Used = BH_BIT(22),
} AstFlags;
typedef enum UnaryOp {
typedef struct Entity {
EntityType type;
Package *package;
+ Scope *scope;
union {
AstUsePackage *use_package;
struct Package {
char *name;
- bh_arr(Package *) unqualified_uses;
-
Scope *scope;
- Scope *include_scope;
Scope *private_scope;
};
ProgramInfo *program;
Package *package;
+ Scope *file_scope;
// NOTE: not used since all tokens are lexed before parsing starts
OnyxTokenizer *tokenizer;
AstKind nkind = node->kind;
ent.package = n->package;
+ ent.scope = n->scope;
switch (nkind) {
case Ast_Kind_Function: {
static void add_node_to_process(OnyxParser* parser, AstNode* node) {
bh_arr_push(parser->results.nodes_to_process, ((NodeToProcess) {
.package = parser->package,
- .scope = parser->package->scope,
+ .scope = parser->file_scope,
.node = node,
}));
}
// 'use' <string>
// <symbol> :: <expr>
static AstNode* parse_top_level_statement(OnyxParser* parser) {
- b32 is_private = 0;
+ AstFlags private_kind = 0;
if (parse_possible_directive(parser, "private")) {
- is_private = 1;
+ private_kind = Ast_Flag_Private_Package;
+ }
+
+ else if (parse_possible_directive(parser, "private_file")) {
+ private_kind = Ast_Flag_Private_File;
}
switch ((u16) parser->curr->type) {
AstTyped* node = parse_top_level_expression(parser);
- if (is_private)
- node->flags |= Ast_Flag_Private_Package;
+ node->flags |= private_kind;
if (node->kind == Ast_Kind_Function) {
AstFunction* func = (AstFunction *) node;
}
}
- if (is_private)
- memres->flags |= Ast_Flag_Private_Package;
+ memres->flags |= private_kind;
add_node_to_process(parser, (AstNode *) memres);
parser->package = package;
}
+ parser->file_scope = scope_create(parser->allocator, parser->package->private_scope);
+
AstUsePackage* implicit_use_builtin = make_node(AstUsePackage, Ast_Kind_Use_Package);
implicit_use_builtin->package = (AstPackage *) &builtin_package_node;
add_node_to_process(parser, (AstNode *) implicit_use_builtin);
case Ast_Kind_Include_Folder:
bh_arr_push(parser->results.includes, (AstInclude *) curr_stmt);
break;
+
case Ast_Kind_Binding: {
if (((AstBinding *) curr_stmt)->node->flags & Ast_Flag_Private_Package) {
symbol_introduce(parser->package->private_scope,
((AstBinding *) curr_stmt)->token,
((AstBinding *) curr_stmt)->node);
+
+ } else if (((AstBinding *) curr_stmt)->node->flags & Ast_Flag_Private_File) {
+ symbol_introduce(parser->file_scope,
+ ((AstBinding *) curr_stmt)->token,
+ ((AstBinding *) curr_stmt)->node);
+
} else {
symbol_introduce(parser->package->scope,
((AstBinding *) curr_stmt)->token,
pac_node->package = p;
pac_node->token = package->alias;
- symbol_introduce(semstate.curr_package->include_scope, package->alias, (AstNode *) pac_node);
+ symbol_introduce(semstate.curr_scope, package->alias, (AstNode *) pac_node);
}
if (package->only != NULL) {
return;
}
- symbol_introduce(semstate.curr_package->include_scope, (*alias)->alias, thing);
+ symbol_introduce(semstate.curr_scope, (*alias)->alias, thing);
}
}
if (package->alias == NULL && package->only == NULL) {
- b32 already_included = 0;
- bh_arr_each(Package *, included_package, semstate.curr_package->unqualified_uses) {
- if (*included_package == p) {
- already_included = 1;
- break;
- }
- }
-
- if (already_included) return;
-
- scope_include(semstate.curr_package->include_scope, p->scope);
-
- bh_arr_push(semstate.curr_package->unqualified_uses, p);
+ scope_include(semstate.curr_scope, p->scope);
}
}
bh_arr_each(Entity, entity, semstate.program->entities) {
if (entity->package) {
- scope_enter(entity->package->private_scope);
+ scope_enter(entity->scope);
semstate.curr_package = entity->package;
}
memcpy(pac_name, package_name, strlen(package_name) + 1);
package->name = pac_name;
- package->include_scope = scope_create(alloc, parent_scope);
- package->scope = scope_create(alloc, package->include_scope);
+ package->scope = scope_create(alloc, parent_scope);
package->private_scope = scope_create(alloc, package->scope);
- package->unqualified_uses = NULL;
- bh_arr_new(global_heap_allocator, package->unqualified_uses, 4);
bh_table_put(Package *, prog->packages, pac_name, package);