map :: package core.map
string :: package core.string
- custom_formatters: Map(type_expr, (^Format_Output, ^Format, rawptr) -> void);
- custom_parsers : Map(type_expr, (rawptr, str, Allocator) -> bool);
+ custom_formatters: Map(type_expr, #type (^Format_Output, ^Format, rawptr) -> void);
+ custom_parsers : Map(type_expr, #type (rawptr, str, Allocator) -> bool);
}
custom_formatters_initialized :: #init () {
AstFunction* polymorphic_proc_build_only_header(AstFunction* pp, PolyProcLookupMethod pp_lookup, ptr actual);
AstFunction* polymorphic_proc_build_only_header_with_slns(AstFunction* pp, bh_arr(AstPolySolution) slns, b32 error_if_failed);
b32 potentially_convert_function_to_polyproc(AstFunction *func);
+AstPolyCallType* convert_call_to_polycall(AstCall* call);
void add_overload_option(bh_arr(OverloadOption)* poverloads, u64 precedence, AstTyped* overload);
AstTyped* find_matching_overload_by_arguments(bh_arr(OverloadOption) overloads, Arguments* args);
return value != 0;
}
+
+AstPolyCallType* convert_call_to_polycall(AstCall* call) {
+ // HACK HACK HACK
+ AstPolyCallType *pct = onyx_ast_node_new(context.ast_alloc, sizeof(AstPolyCallType), Ast_Kind_Poly_Call_Type);
+ pct->token = call->token;
+ pct->__unused = call->next;
+ pct->callee = (AstType *) call->callee;
+ pct->params = (AstNode **) call->args.values;
+ bh_arr_each(AstNode *, pp, pct->params) {
+ if ((*pp)->kind == Ast_Kind_Argument) {
+ *pp = (AstNode *) (*(AstArgument **) pp)->value;
+ }
+ }
+
+ return pct;
+}
\ No newline at end of file
if (call->kind == Ast_Kind_Call) {
AstNode* callee = strip_aliases((AstNode *) call->callee);
if (callee->kind == Ast_Kind_Poly_Struct_Type) {
- // HACK HACK HACK
- AstPolyCallType *pct = onyx_ast_node_new(context.ast_alloc, sizeof(AstPolyCallType), Ast_Kind_Poly_Call_Type);
- pct->token = call->token;
- pct->__unused = call->next;
- pct->callee = (AstType *) callee;
- pct->params = (AstNode **) call->args.values;
- bh_arr_each(AstNode *, pp, pct->params) {
- *pp = (AstNode *) (*(AstArgument **) pp)->value;
- }
-
- *pcall = (AstCall *) pct;
+ *pcall = (AstCall *) convert_call_to_polycall(call);
CHECK(expression, (AstTyped **) pcall);
return Check_Success;
}
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);
static AstType* parse_type(OnyxParser* parser);
static AstTypeOf* parse_typeof(OnyxParser* parser);
static AstStructType* parse_struct(OnyxParser* parser);
break;
}
+ case '$': {
+ AstType **tmp = (AstType **) &retval;
+ parse_polymorphic_variable(parser, &tmp);
+ break;
+ }
+
case '#': {
if (parse_possible_directive(parser, "file_contents")) {
AstFileContents* fc = make_node(AstFileContents, Ast_Kind_File_Contents);
poly_var->token = expect_token(parser, Token_Type_Symbol);
expect_token(parser, '=');
- AstType* poly_type = parse_type(parser);
+ AstType* poly_type = (AstType *) parse_expression(parser, 0);
bh_arr_push(solid->known_polyvars, ((AstPolySolution) {
.kind = PSK_Undefined,
while (!consume_token_if_next(parser, ')')) {
if (parser->hit_unexpected_token) break;
- AstNode* t = (AstNode *) parse_type(parser);
+ AstNode* t = (AstNode *) parse_expression(parser, 0);
bh_arr_push(params, t);
if (parser->curr->type != ')')
break;
}
- case '#': {
- // :ValueDirectiveHack
- if (parse_possible_directive(parser, "value")) {
- // It is very weird to put these here.
- case Token_Type_Literal_Integer:
- case Token_Type_Literal_String:
- case Token_Type_Literal_Float:
- case Token_Type_Literal_True:
- case Token_Type_Literal_False:
- case '-':
- *next_insertion = (AstType *) parse_expression(parser, 0);
- next_insertion = NULL;
- break;
- }
-
+ //
+ // I don't think any of these cases are necesary any more?
+ case Token_Type_Literal_Integer:
+ case Token_Type_Literal_String:
+ case Token_Type_Literal_Float:
+ case Token_Type_Literal_True:
+ case Token_Type_Literal_False:
+ case '-': {
+ *next_insertion = (AstType *) parse_expression(parser, 0);
next_insertion = NULL;
break;
}
break;
}
+ case Ast_Kind_Address_Of: {
+ if (elem.actual->kind != Type_Kind_Pointer) break;
+
+ bh_arr_push(elem_queue, ((PolySolveElem) {
+ .type_expr = (AstType *) ((AstAddressOf *) elem.type_expr)->expr,
+ .kind = PSK_Type,
+ .actual = elem.actual->Pointer.elem,
+ }));
+ break;
+ }
+
case Ast_Kind_Array_Type: {
if (elem.actual->kind != Type_Kind_Array) break;
break;
}
+ case Ast_Kind_Call: {
+ AstPolyCallType *pct = convert_call_to_polycall((AstCall *) elem.type_expr);
+ elem.type_expr = (AstType *) pct;
+
+ // fallthrough
+ }
+
case Ast_Kind_Poly_Call_Type: {
if (elem.actual->kind != Type_Kind_Struct) break;
if (bh_arr_length(elem.actual->Struct.poly_sln) != bh_arr_length(((AstPolyCallType *) elem.type_expr)->params)) break;
bh_arr(AstTyped *) arg_arr = args->values;
bh_arr(AstNamedValue *) named_values = args->named_values;
+ if ((i32) param->idx < 0)
+ return NULL;
+
// NOTE: This check is safe because currently the arguments given without a name
// always map to the beginning indidies of the argument array.
if (param->idx >= (u64) bh_arr_length(arg_arr)) {
}
if (bh_arr_length(slns) != bh_arr_length(ps_type->poly_params)) {
- onyx_report_error(pos, Error_Critical, "Wrong number of arguments for '%s'. Expected %d, got %d",
+ onyx_report_error(pos, Error_Critical, "Wrong number of arguments for '%s'. Expected %d, got %d.",
ps_type->name,
bh_arr_length(ps_type->poly_params),
bh_arr_length(slns));
case Ast_Kind_Poly_Struct_Type: {
AstPolyStructType* pst_node = (AstPolyStructType *) *type;
- pst_node->scope = scope_create(context.ast_alloc, pst_node->entity->scope, pst_node->token->pos);
+
+ 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);
BagGraph :: struct {
nodes : [..] ^BagNode;
- node_map : map.Map(str, ^BagNode);
+ node_map : map.Map(str, #type ^BagNode);
}
BagNode :: struct {
return .{ data, N };
}
-count_to_30 :: #solidify count_to { N = #value 30 };
+count_to_30 :: #solidify count_to { N = 30 };
main :: (args: [] cstr) {
count_to(5);
return res;
}
-join :: (a: Vec($T, $N), b: Vec(T, $M)) -> Vec(T, #value N + M) {
- out : Vec(T, #value N + M);
+join :: (a: Vec($T, $N), b: Vec(T, $M)) -> Vec(T, N + M) {
+ out : Vec(T, N + M);
for i: 0 .. N do out.data[i] = a.data[i];
for i: 0 .. M do out.data[i + N] = b.data[i];
return out;
y : [N] f32;
}
- nps : NewPolyStruct(i32, #value 4);
+ nps : NewPolyStruct(i32, 4);
for ^x: nps.x do *x = 12345;
for ^y: nps.y do *y = 67890;