CheckStatus check_function_header(AstFunction* func);
CheckStatus check_memres_type(AstMemRes* memres);
CheckStatus check_memres(AstMemRes* memres);
-CheckStatus check_type(AstType* type);
+CheckStatus check_type(AstType** ptype);
CheckStatus check_insert_directive(AstDirectiveInsert** pinsert);
CheckStatus check_do_block(AstDoBlock** pdoblock);
CheckStatus check_constraint(AstConstraint *constraint);
static inline void fill_in_type(AstTyped* node) {
if (node->type == NULL) {
- if (check_type(node->type_node) > Check_Errors_Start) return;
+ if (check_type(&node->type_node) > Check_Errors_Start) return;
node->type = type_build_from_ast(context.ast_alloc, node->type_node);
}
pt->elem = (AstType *) expr;
pt->__unused = aof->next;
*paof = (AstAddressOf *) pt;
- CHECK(type, (AstType *) pt);
+ CHECK(type, (AstType **) &pt);
return Check_Success;
}
return Check_Success;
}
}
+
+ AstNode* n = try_symbol_raw_resolve_from_type(field->expr->type, field->field);
AstType* type_node = field->expr->type->ast_type;
- AstNode* n = try_symbol_raw_resolve_from_node((AstNode *) type_node, field->field);
+ if (!n) n = try_symbol_raw_resolve_from_node((AstNode *) type_node, field->field);
+
if (n) {
*pfield = (AstFieldAccess *) n;
return Check_Success;
}
CheckStatus check_size_of(AstSizeOf* so) {
- CHECK(type, so->so_ast_type);
+ CHECK(type, &so->so_ast_type);
so->so_type = type_build_from_ast(context.ast_alloc, so->so_ast_type);
if (so->so_type == NULL)
}
CheckStatus check_align_of(AstAlignOf* ao) {
- CHECK(type, ao->ao_ast_type);
+ CHECK(type, &ao->ao_ast_type);
ao->ao_type = type_build_from_ast(context.ast_alloc, ao->ao_ast_type);
if (ao->ao_type == NULL)
// This is to ensure that the type will exist when compiling. For example, a poly-call type
// would have to wait for the entity to pass through, which the code generation does not know
// about.
- CHECK(type, (AstType *) expr);
+ CHECK(type, (AstType **) pexpr);
+ expr = *pexpr;
// Don't try to construct a polystruct ahead of time because you can't.
if (expr->kind != Ast_Kind_Poly_Struct_Type) {
AstTyped* typed_stmt = (AstTyped *) stmt;
fill_in_type(typed_stmt);
if (typed_stmt->type_node != NULL && typed_stmt->type == NULL) {
- CHECK(type, typed_stmt->type_node);
+ CHECK(type, &typed_stmt->type_node);
if (!node_is_type((AstNode *) typed_stmt->type_node)) {
ERROR(stmt->token->pos, "Local's type is not a type.");
bh_arr_each(AstStructMember *, smem, s_node->members) {
if ((*smem)->type_node != NULL) {
- CHECK(type, (*smem)->type_node);
+ CHECK(type, &(*smem)->type_node);
}
if ((*smem)->type_node == NULL && (*smem)->initial_value != NULL) {
// If the function has the no_error flag, then the type node should have it set too.
// This allows for polymorphic structures with constraints to fail gracefully.
local->type_node->flags |= (func->flags & Ast_Flag_Header_Check_No_Error);
- CHECK(type, local->type_node);
+ CHECK(type, &local->type_node);
}
fill_in_type((AstTyped *) local);
}
}
- if (func->return_type != NULL) CHECK(type, func->return_type);
+ if (func->return_type != NULL) CHECK(type, &func->return_type);
if (func->constraints.constraints != NULL) {
func->constraints.produce_errors = (func->flags & Ast_Flag_Header_Check_No_Error) == 0;
}
CheckStatus check_memres_type(AstMemRes* memres) {
- CHECK(type, memres->type_node);
+ CHECK(type, &memres->type_node);
fill_in_type((AstTyped *) memres);
if (memres->type_node && !memres->type) YIELD(memres->token->pos, "Waiting for global type to be constructed.");
return Check_Success;
return Check_Success;
}
-CheckStatus check_type(AstType* type) {
- if (type == NULL) return Check_Success;
-
+CheckStatus check_type(AstType** ptype) {
+ if (ptype == NULL || *ptype == NULL) return Check_Success;
+
+ AstType* type = *ptype;
AstType* original_type = type;
while (type->kind == Ast_Kind_Type_Alias)
type = ((AstTypeAlias *) type)->to;
break;
}
- case Ast_Kind_Pointer_Type: CHECK(type, ((AstPointerType *) type)->elem); break;
- case Ast_Kind_Slice_Type: CHECK(type, ((AstSliceType *) type)->elem); break;
- case Ast_Kind_DynArr_Type: CHECK(type, ((AstDynArrType *) type)->elem); break;
- case Ast_Kind_VarArg_Type: CHECK(type, ((AstVarArgType *) type)->elem); break;
+ case Ast_Kind_Pointer_Type: CHECK(type, &((AstPointerType *) type)->elem); break;
+ case Ast_Kind_Slice_Type: CHECK(type, &((AstSliceType *) type)->elem); break;
+ case Ast_Kind_DynArr_Type: CHECK(type, &((AstDynArrType *) type)->elem); break;
+ case Ast_Kind_VarArg_Type: CHECK(type, &((AstVarArgType *) type)->elem); break;
case Ast_Kind_Function_Type: {
AstFunctionType* ftype = (AstFunctionType *) type;
- CHECK(type, ftype->return_type);
+ CHECK(type, &ftype->return_type);
if (ftype->param_count > 0) {
fori (i, 0, (i64) ftype->param_count) {
- CHECK(type, ftype->params[i]);
+ CHECK(type, &ftype->params[i]);
}
}
break;
case Ast_Kind_Type_Compound: {
AstCompoundType* ctype = (AstCompoundType *) type;
- bh_arr_each(AstType *, type, ctype->types) CHECK(type, *type);
+ bh_arr_each(AstType *, type, ctype->types) CHECK(type, type);
break;
}
break;
}
+
+ case Ast_Kind_Field_Access: {
+ CHECK(field_access, (AstFieldAccess **) ptype);
+ type = *ptype;
+ original_type = type;
+
+ if (!node_is_type((AstNode *) type)) {
+ ERROR_(original_type->token->pos, "This field access did not resolve to be a type. It resolved to be a '%s'.", onyx_ast_node_kind_string(type->kind));
+ }
+ break;
+ }
}
type = original_type;
if (ent->type_alias->kind == Ast_Kind_Struct_Type)
cs = check_struct((AstStructType *) ent->type_alias);
else
- cs = check_type(ent->type_alias);
+ cs = check_type(&ent->type_alias);
break;
case Entity_Type_File_Contents:
return result;
}
+AstNode* try_symbol_raw_resolve_from_type(Type *type, char* symbol) {
+ while (type->kind == Type_Kind_Pointer) {
+ type = type->Pointer.elem;
+ }
+
+ if (type->kind == Type_Kind_Struct) {
+ if (type->Struct.poly_sln == NULL) return NULL;
+
+ bh_arr_each(AstPolySolution, sln, type->Struct.poly_sln) {
+ if (token_text_equals(sln->poly_sym->token, symbol)) {
+ if (sln->kind == PSK_Type) {
+ AstTypeRawAlias* alias = onyx_ast_node_new(context.ast_alloc, sizeof(AstTypeRawAlias), Ast_Kind_Type_Raw_Alias);
+ alias->type = &basic_types[Basic_Kind_Type_Index];
+ alias->to = sln->type;
+ return (AstNode *) alias;
+
+ } else {
+ return (AstNode *) sln->value;
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+
void scope_clear(Scope* scope) {
sh_new_arena(scope->symbols);
}
b32 permanent = location != NULL;
if (func_name == NULL) func_name = "UNKNOWN FUNCTION";
+ if (error) error->rank = Error_Critical;
+
bh_arr(AstArgument *) arg_arr = (bh_arr(AstArgument *)) args->values;
i32 arg_count = get_argument_buffer_size(func_type, args);
if (tm == TYPE_MATCH_YIELD) return tm;
if (tm == TYPE_MATCH_FAILED) {
if (error != NULL) {
- error->pos = arg_arr[arg_pos]->token->pos,
+ error->pos = arg_arr[arg_pos]->token->pos;
error->text = bh_aprintf(global_heap_allocator,
"The procedure '%s' expects a value of type '%s' for %d%s parameter, got '%s'.",
func_name,
}
case Ast_Kind_Poly_Struct_Type: {
- AstStructType* stype = ((AstPolyStructType *) node)->base_struct;
+ AstPolyStructType* pstype = (AstPolyStructType *) node;
+ AstStructType* stype = pstype->base_struct;
u32 dist;
- return find_closest_symbol_in_scope(stype->scope, sym, &dist);
- }
+ char *closest = find_closest_symbol_in_scope(stype->scope, sym, &dist);
- case Ast_Kind_Poly_Call_Type: {
- AstPolyCallType* pcall = (AstPolyCallType *) node;
-
- u32 dist = 0x7fffffff;
- char *closest = NULL;
-
- Type *type = type_build_from_ast(context.ast_alloc, (AstType *) pcall);
- assert(type);
+ bh_arr_each(AstPolyStructParam, param, pstype->poly_params) {
+ token_toggle_end(param->token);
+ u32 d = levenshtein_distance(param->token->text, sym);
- bh_arr_each(StructMember *, mem, type->Struct.memarr) {
- u32 d = levenshtein_distance((*mem)->name, sym);
if (d < dist) {
dist = d;
- closest = (*mem)->name;
+ closest = bh_strdup(context.ast_alloc, param->token->text);
}
+ token_toggle_end(param->token);
}
return closest;
}
+
+ case Ast_Kind_Poly_Call_Type: {
+ AstPolyCallType* pcall = (AstPolyCallType *) node;
+ return find_closest_symbol_in_node(pcall->callee, sym);
+ }
}
return NULL;