From 7418b54223cf1e1fef7389de873243e68c09ac11 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Thu, 28 Apr 2022 15:42:09 -0500 Subject: [PATCH] bugfixes and removing arbitrary restrictions --- core/conv.onyx | 4 ++-- include/astnodes.h | 1 + src/astnodes.c | 16 +++++++++++++ src/checker.c | 12 +--------- src/parser.c | 35 +++++++++++++++-------------- src/polymorph.h | 23 ++++++++++++++++++- src/symres.c | 5 ++++- tests/aoc-2020/day7.onyx | 2 +- tests/baked_parameters.onyx | 2 +- tests/operator_overload.onyx | 4 ++-- tests/poly_structs_with_values.onyx | 2 +- 11 files changed, 69 insertions(+), 37 deletions(-) diff --git a/core/conv.onyx b/core/conv.onyx index bc514bc5..dfe9871a 100644 --- a/core/conv.onyx +++ b/core/conv.onyx @@ -6,8 +6,8 @@ Enable_Custom_Formatters :: true 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 () { diff --git a/include/astnodes.h b/include/astnodes.h index 9b4d76dd..d5433347 100644 --- a/include/astnodes.h +++ b/include/astnodes.h @@ -1675,6 +1675,7 @@ AstNode* polymorphic_proc_try_solidify(AstFunction* pp, bh_arr(AstPolySolution) 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); diff --git a/src/astnodes.c b/src/astnodes.c index ec2386f9..862b1726 100644 --- a/src/astnodes.c +++ b/src/astnodes.c @@ -1303,3 +1303,19 @@ b32 static_if_resolution(AstIf* static_if) { 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 diff --git a/src/checker.c b/src/checker.c index 3279919c..f788ddd6 100644 --- a/src/checker.c +++ b/src/checker.c @@ -603,17 +603,7 @@ CheckStatus check_call(AstCall** pcall) { 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; } diff --git a/src/parser.c b/src/parser.c index 348415b6..cf0b5b79 100644 --- a/src/parser.c +++ b/src/parser.c @@ -54,6 +54,7 @@ static AstReturn* parse_return_stmt(OnyxParser* parser); 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); @@ -534,6 +535,12 @@ static AstTyped* parse_factor(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); @@ -619,7 +626,7 @@ static AstTyped* parse_factor(OnyxParser* parser) { 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, @@ -1805,7 +1812,7 @@ static AstType* parse_type(OnyxParser* parser) { 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 != ')') @@ -1831,21 +1838,15 @@ static AstType* parse_type(OnyxParser* parser) { 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; } diff --git a/src/polymorph.h b/src/polymorph.h index 34b4ced4..d7974ada 100644 --- a/src/polymorph.h +++ b/src/polymorph.h @@ -262,6 +262,17 @@ static PolySolveResult solve_poly_type(AstNode* target, AstType* type_expr, Type 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; @@ -337,6 +348,13 @@ static PolySolveResult solve_poly_type(AstNode* target, AstType* type_expr, Type 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; @@ -397,6 +415,9 @@ static AstTyped* lookup_param_in_arguments(AstFunction* func, AstPolyParam* para 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)) { @@ -1011,7 +1032,7 @@ Type* polymorphic_struct_lookup(AstPolyStructType* ps_type, bh_arr(AstPolySoluti } 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)); diff --git a/src/symres.c b/src/symres.c index c2cf26de..503073a9 100644 --- a/src/symres.c +++ b/src/symres.c @@ -186,7 +186,10 @@ static SymresStatus symres_type(AstType** type) { 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); diff --git a/tests/aoc-2020/day7.onyx b/tests/aoc-2020/day7.onyx index 434e70fb..c5be6ba6 100644 --- a/tests/aoc-2020/day7.onyx +++ b/tests/aoc-2020/day7.onyx @@ -5,7 +5,7 @@ reader :: package core.string.reader BagGraph :: struct { nodes : [..] ^BagNode; - node_map : map.Map(str, ^BagNode); + node_map : map.Map(str, #type ^BagNode); } BagNode :: struct { diff --git a/tests/baked_parameters.onyx b/tests/baked_parameters.onyx index 41ff1e83..f0325ac3 100644 --- a/tests/baked_parameters.onyx +++ b/tests/baked_parameters.onyx @@ -12,7 +12,7 @@ alloc_slice :: ($T: type_expr, N: i32) -> [] T { 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); diff --git a/tests/operator_overload.onyx b/tests/operator_overload.onyx index c929cabe..2bf51ab6 100644 --- a/tests/operator_overload.onyx +++ b/tests/operator_overload.onyx @@ -51,8 +51,8 @@ Vec :: struct (T: type_expr, N: i32) { 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; diff --git a/tests/poly_structs_with_values.onyx b/tests/poly_structs_with_values.onyx index 2cdcac92..9fd5eeb4 100644 --- a/tests/poly_structs_with_values.onyx +++ b/tests/poly_structs_with_values.onyx @@ -8,7 +8,7 @@ main :: (args: [] cstr) { 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; -- 2.25.1