OnyxFilePos polymorphic_error_loc;
ConstraintContext constraints;
+ bh_arr(AstType *) polymorphic_argument_types;
+ bh_arr(AstPolySolution) polymorphic_arguments;
+
b32 pending_type_is_valid : 1;
b32 is_union : 1;
b32 is_packed : 1;
+ b32 ready_to_build_type : 1;
};
struct AstStructMember {
AstTyped_base;
CHECK(expression, &range->low);
CHECK(expression, &range->high);
+ builtin_range_type_type = type_build_from_ast(context.ast_alloc, builtin_range_type);
+ if (builtin_range_type_type == NULL) YIELD(range->token->pos, "Waiting for 'range' structure to be built.");
+
Type* expected_range_type = builtin_range_type_type;
StructMember smem;
if (s_node->entity_defaults && s_node->entity_defaults->state < Entity_State_Check_Types)
YIELD(s_node->token->pos, "Waiting for struct member defaults to pass symbol resolution.");
+ if (s_node->polymorphic_argument_types) {
+ assert(s_node->polymorphic_arguments);
+
+ fori (i, 0, (i64) bh_arr_length(s_node->polymorphic_argument_types)) {
+ Type *arg_type = type_build_from_ast(context.ast_alloc, s_node->polymorphic_argument_types[i]);
+ if (arg_type == NULL) YIELD(s_node->polymorphic_argument_types[i]->token->pos, "Waiting to build type for polymorph argument.");
+
+ // nocheckin this is wrong...
+ if (s_node->polymorphic_arguments[i].value) {
+ TYPE_CHECK(&s_node->polymorphic_arguments[i].value, arg_type) {
+ ERROR_(s_node->polymorphic_arguments[i].value->token->pos, "Expected value of type %s, got %s.",
+ type_get_name(arg_type),
+ type_get_name(s_node->polymorphic_arguments[i].value->type));
+ }
+ }
+ }
+ }
+
if (s_node->constraints.constraints) {
s_node->constraints.produce_errors = (s_node->flags & Ast_Flag_Header_Check_No_Error) == 0;
}
// NOTE: fills in the pending_type.
+ s_node->ready_to_build_type = 1;
type_build_from_ast(context.ast_alloc, (AstType *) s_node);
if (s_node->pending_type == NULL || !s_node->pending_type_is_valid)
YIELD(s_node->token->pos, "Waiting for type to be constructed.");
i32 i = 0;
bh_arr_each(AstPolySolution, sln, slns) {
sln->poly_sym = (AstNode *) &ps_type->poly_params[i];
-
- PolySolutionKind expected_kind = PSK_Undefined;
- if ((AstNode *) ps_type->poly_params[i].type_node == (AstNode *) &basic_type_type_expr) {
- expected_kind = PSK_Type;
- } else {
- expected_kind = PSK_Value;
- }
-
- if (sln->kind != expected_kind) {
- if (expected_kind == PSK_Type)
- onyx_report_error(pos, Error_Critical, "Expected type expression for %d%s argument.", i + 1, bh_num_suffix(i + 1));
-
- if (expected_kind == PSK_Value)
- onyx_report_error(pos, Error_Critical, "Expected value expression of type '%s' for %d%s argument.",
- type_get_name(ps_type->poly_params[i].type),
- i + 1, bh_num_suffix(i + 1));
-
- return NULL;
- }
-
- if (sln->kind == PSK_Value) {
- resolve_expression_type(sln->value);
-
- if ((sln->value->flags & Ast_Flag_Comptime) == 0) {
- onyx_report_error(pos, Error_Critical,
- "Expected compile-time known argument for '%b'.",
- sln->poly_sym->token->text,
- sln->poly_sym->token->length);
- return NULL;
- }
-
- if (!types_are_compatible(sln->value->type, ps_type->poly_params[i].type)) {
- onyx_report_error(pos, Error_Critical, "Expected compile-time argument of type '%s', got '%s'.",
- type_get_name(ps_type->poly_params[i].type),
- type_get_name(sln->value->type));
- return NULL;
- }
- }
-
i++;
}
AstStructType* concrete_struct = (AstStructType *) ast_clone(context.ast_alloc, ps_type->base_struct);
concrete_struct->polymorphic_error_loc = pos;
BH_MASK_SET(concrete_struct->flags, !error_if_failed, Ast_Flag_Header_Check_No_Error);
- shput(ps_type->concrete_structs, unique_key, concrete_struct);
+
+ i64 arg_count = bh_arr_length(ps_type->poly_params);
+ bh_arr_new(global_heap_allocator, concrete_struct->polymorphic_argument_types, arg_count);
+ bh_arr_set_length(concrete_struct->polymorphic_argument_types, arg_count);
+ concrete_struct->polymorphic_arguments = bh_arr_copy(global_heap_allocator, slns);
+
+ fori (i, 0, (i64) bh_arr_length(ps_type->poly_params)) {
+ concrete_struct->polymorphic_argument_types[i] = (AstType *) ast_clone(context.ast_alloc, ps_type->poly_params[i].type_node);
+ }
+
+ shput(ps_type->concrete_structs, unique_key, concrete_struct);
add_entities_for_node(NULL, (AstNode *) concrete_struct, sln_scope, NULL);
return NULL;
}
scope_enter(s_node->scope);
}
+ if (s_node->polymorphic_argument_types) {
+ assert(s_node->polymorphic_arguments);
+
+ SymresStatus ss = Symres_Success, result;
+ fori (i, 0, (i64) bh_arr_length(s_node->polymorphic_argument_types)) {
+ result = symres_type(&s_node->polymorphic_argument_types[i]);
+ if (result > ss) ss = result;
+
+ if (s_node->polymorphic_arguments[i].value) {
+ result = symres_expression(&s_node->polymorphic_arguments[i].value);
+ if (result > ss) ss = result;
+ }
+ }
+ }
+
if (s_node->constraints.constraints) {
bh_arr_each(AstConstraint *, constraint, s_node->constraints.constraints) {
SYMRES(constraint, *constraint);
if (pst_node->scope == NULL) {
pst_node->scope = scope_create(context.ast_alloc, pst_node->entity->scope, pst_node->token->pos);
}
-
- bh_arr_each(AstPolyStructParam, param, pst_node->poly_params) {
- SYMRES(type, ¶m->type_node);
- param->type = type_build_from_ast(context.ast_alloc, param->type_node);
- if (param->type == NULL) {
- if (context.cycle_detected) {
- onyx_report_error(param->token->pos, Error_Waiting_On, "Waiting for parameter type to be known.");
- return Symres_Error;
- } else {
- return Symres_Yield_Macro;
- }
- }
- }
break;
}
// :EliminatingSymres
SYMRES(type, &builtin_range_type);
(*expr)->type_node = builtin_range_type;
-
- // NOTE: This is a weird place to put this so maybe put it somewhere else eventually
- // - brendanfh 2020/09/04
- builtin_range_type_type = type_build_from_ast(context.ast_alloc, builtin_range_type);
break;
case Ast_Kind_Function:
AstStructType* s_node = (AstStructType *) type_node;
if (s_node->stcache != NULL) return s_node->stcache;
if (s_node->pending_type != NULL && s_node->pending_type_is_valid) return s_node->pending_type;
+ if (!s_node->ready_to_build_type) return NULL;
Type* s_type;
if (s_node->pending_type == NULL) {
bh_buffer_grow(&table_buffer, table_buffer.length + size);
u8* buffer = table_buffer.data + table_buffer.length;
- emit_raw_data(module, buffer, sln->value);
- table_buffer.length += size;
- break;
+ if (emit_raw_data_(module, buffer, sln->value)) {
+ table_buffer.length += size;
+ break;
+ }
+
+ // fallthrough
}
default: {
BagGraph :: struct {
nodes : [..] ^BagNode;
- node_map : map.Map(str, #type ^BagNode);
+ node_map : map.Map(str, ^BagNode);
}
BagNode :: struct {