Map :: struct (K: type_expr, V: type_expr) {
hashes : [..] i32;
- entries : [..] MapEntry(K, V);
+ entries : [..] Entry(K, V);
// The value provided by `map.get`, if nothing was found.
default_value : V;
-}
-MapEntry :: struct (K: type_expr, V: type_expr) {
- next : i32;
- key : K;
- value : V;
+ Entry :: struct (K: type_expr, V: type_expr) {
+ next : i32;
+ key : K;
+ value : V;
+ }
}
make :: ($Key: type_expr, $Value: type_expr, default: Value = 0, hash_count: i32 = 16) -> Map(Key, Value) {
return;
}
- entry : MapEntry(K, V);
+ entry : Map.Entry(K, V);
entry.key = key;
entry.value = value;
entry.next = hashes[lr.hash_index];
s_node->flags |= Ast_Flag_Type_Is_Resolved;
- // FIX: This is probably wrong for the long term.
- if (s_node->scope) s_node->scope->parent = curr_scope;
-
{
bh_table(i32) mem_set;
bh_table_init(global_heap_allocator, mem_set, bh_arr_length(s_node->members));
bh_table_free(mem_set);
}
+ if (s_node->scope) {
+ // FIX: This is probably wrong for the long term.
+ s_node->scope->parent = curr_scope;
+
+ scope_enter(s_node->scope);
+ }
+
fori (i, 0, bh_arr_length(s_node->members)) {
AstStructMember *member = s_node->members[i];
if (!node_is_type((AstNode *) member->type_node)) {
onyx_report_error(member->token->pos, "Member type is not a type.");
- return type;
+ goto struct_symres_done;
}
if (member->flags & Ast_Flag_Struct_Mem_Used) {
onyx_report_error(member->token->pos,
"Can only 'use' members of struct type, got '%s'.",
onyx_ast_node_kind_string(used->kind));
-
- return type;
+ goto struct_symres_done;
}
}
}
}
+struct_symres_done:
+ if (s_node->scope) scope_leave();
return type;
}
symres_expression(&(*fa)->expr);
if ((*fa)->expr == NULL) return;
- // CLEANUP: There are way to many cases here that a too similar.
- // It should be easy to clean all of these up. Also, I think that when
- // that happens, it might be even easier to allow for 'use'ing members
- // that are pointers to structures.
-
- if ((*fa)->expr->kind == Ast_Kind_Package) {
- AstPackage* package = (AstPackage *) (*fa)->expr;
- AstNode* n = symbol_resolve(package->package->scope, (*fa)->token);
- if (n) {
- // NOTE: not field access
- *fa = (AstFieldAccess *) n;
- return;
- }
- }
-
- if ((*fa)->expr->kind == Ast_Kind_Enum_Type) {
- AstEnumType* etype = (AstEnumType *) (*fa)->expr;
- AstNode* n = symbol_resolve(etype->scope, (*fa)->token);
- if (n) {
- // NOTE: not field access
- *fa = (AstFieldAccess *) n;
- return;
- }
- }
-
- if ((*fa)->expr->kind == Ast_Kind_Struct_Type) {
- AstStructType* stype = (AstStructType *) (*fa)->expr;
- AstNode* n = symbol_resolve(stype->scope, (*fa)->token);
- if (n) {
- // Note: not field access
- *fa = (AstFieldAccess *) n;
- return;
- }
- }
-
- if ((*fa)->expr->kind == Ast_Kind_Poly_Struct_Type) {
- AstStructType* stype = ((AstPolyStructType *) (*fa)->expr)->base_struct;
- AstNode* n = symbol_resolve(stype->scope, (*fa)->token);
- if (n) {
- // Note: not field access
- *fa = (AstFieldAccess *) n;
- return;
- }
- }
+ AstNode* resolution = try_symbol_resolve_from_node((AstNode *) (*fa)->expr, (*fa)->token);
+ if (resolution) *((AstNode **) fa) = resolution;
}
static void symres_compound(AstCompound* compound) {
return res;
}
+AstNode* try_symbol_resolve_from_node(AstNode* node, OnyxToken* token) {
+ if (node->kind == Ast_Kind_Type_Raw_Alias)
+ node = (AstNode *) ((AstTypeRawAlias *) node)->to->ast_type;
+
+ if (node->kind == Ast_Kind_Type_Alias)
+ node = (AstNode *) ((AstTypeAlias *) node)->to;
+
+ // A single pointer can be dereferenced to lookup symbols in struct.
+ if (node->kind == Ast_Kind_Pointer_Type)
+ node = (AstNode *) ((AstPointerType *) node)->elem;
+
+ if (!node) return NULL;
+
+ switch (node->kind) {
+ case Ast_Kind_Package: {
+ AstPackage* package = (AstPackage *) node;
+ return symbol_resolve(package->package->scope, token);
+ }
+
+ case Ast_Kind_Enum_Type: {
+ AstEnumType* etype = (AstEnumType *) node;
+ return symbol_resolve(etype->scope, token);
+ }
+
+ case Ast_Kind_Struct_Type: {
+ AstStructType* stype = (AstStructType *) node;
+ return symbol_resolve(stype->scope, token);
+ }
+
+ case Ast_Kind_Poly_Struct_Type: {
+ AstStructType* stype = ((AstPolyStructType *) node)->base_struct;
+ return symbol_resolve(stype->scope, token);
+ }
+ }
+
+ return NULL;
+}
+
void scope_clear(Scope* scope) {
bh_table_clear(scope->symbols);
}