From: Brendan Hansen Date: Sat, 9 Jan 2021 05:11:22 +0000 (-0600) Subject: cleaned up type parsing X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=0ca3a85e56434fa5e05403b9b04719659c0ebc03;p=onyx.git cleaned up type parsing --- diff --git a/bin/onyx b/bin/onyx index 797a3f47..34b974eb 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/onyx.exe b/onyx.exe index 14ae3406..6b23601b 100644 Binary files a/onyx.exe and b/onyx.exe differ diff --git a/src/onyxparser.c b/src/onyxparser.c index a35f11b3..a70b4eba 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -1415,158 +1415,170 @@ static AstType* parse_type(OnyxParser* parser) { while (1) { if (parser->hit_unexpected_token) return root; - if (parser->curr->type == '^') { - AstPointerType* new = make_node(AstPointerType, Ast_Kind_Pointer_Type); - new->flags |= Basic_Flag_Pointer; - new->token = expect_token(parser, '^'); - *next_insertion = (AstType *) new; - next_insertion = &new->elem; - } - - else if (parser->curr->type == '[') { - AstType *new; - OnyxToken *open_bracket = expect_token(parser, '['); + switch (parser->curr->type) { + case '^': { + AstPointerType* new = make_node(AstPointerType, Ast_Kind_Pointer_Type); + new->flags |= Basic_Flag_Pointer; + new->token = expect_token(parser, '^'); + + *next_insertion = (AstType *) new; + next_insertion = &new->elem; + break; + } - if (parser->curr->type == ']') { - new = make_node(AstSliceType, Ast_Kind_Slice_Type); - new->token = open_bracket; + case '[': { + AstType *new; + OnyxToken *open_bracket = expect_token(parser, '['); - } else if (parser->curr->type == Token_Type_Dot_Dot) { - new = make_node(AstDynArrType, Ast_Kind_DynArr_Type); - new->token = open_bracket; - consume_token(parser); + if (parser->curr->type == ']') { + new = make_node(AstSliceType, Ast_Kind_Slice_Type); + new->token = open_bracket; - } else { - new = make_node(AstArrayType, Ast_Kind_Array_Type); - new->token = open_bracket; + } else if (parser->curr->type == Token_Type_Dot_Dot) { + new = make_node(AstDynArrType, Ast_Kind_DynArr_Type); + new->token = open_bracket; + consume_token(parser); - if (parser->curr->type == '$') { - AstType** insertion = (AstType **) &((AstArrayType *) new)->count_expr; - parse_polymorphic_variable(parser, &insertion); } else { - ((AstArrayType *) new)->count_expr = parse_expression(parser); + new = make_node(AstArrayType, Ast_Kind_Array_Type); + new->token = open_bracket; + + if (parser->curr->type == '$') { + AstType** insertion = (AstType **) &((AstArrayType *) new)->count_expr; + parse_polymorphic_variable(parser, &insertion); + } else { + ((AstArrayType *) new)->count_expr = parse_expression(parser); + } } - } - expect_token(parser, ']'); - *next_insertion = (AstType *) new; - next_insertion = &((AstSliceType *) new)->elem; - } + expect_token(parser, ']'); + *next_insertion = (AstType *) new; + next_insertion = &((AstSliceType *) new)->elem; + break; + } - else if (parser->curr->type == Token_Type_Keyword_Proc) { - OnyxToken* proc_token = expect_token(parser, Token_Type_Keyword_Proc); + case Token_Type_Keyword_Proc: { + OnyxToken* proc_token = expect_token(parser, Token_Type_Keyword_Proc); - bh_arr(AstType *) params = NULL; - bh_arr_new(global_scratch_allocator, params, 4); - bh_arr_set_length(params, 0); + bh_arr(AstType *) params = NULL; + bh_arr_new(global_scratch_allocator, params, 4); + bh_arr_set_length(params, 0); - expect_token(parser, '('); - while (parser->curr->type != ')') { - if (parser->hit_unexpected_token) return root; + expect_token(parser, '('); + while (parser->curr->type != ')') { + if (parser->hit_unexpected_token) return root; - AstType* param_type = parse_type(parser); - bh_arr_push(params, param_type); + if ((parser->curr + 1)->type == ':') { + expect_token(parser, Token_Type_Symbol); + expect_token(parser, ':'); + } - if (parser->curr->type != ')') - expect_token(parser, ','); - } - consume_token(parser); + AstType* param_type = parse_type(parser); + bh_arr_push(params, param_type); - AstType* return_type = (AstType *) &basic_type_void; - if (parser->curr->type == Token_Type_Right_Arrow) { + if (parser->curr->type != ')') + expect_token(parser, ','); + } consume_token(parser); - return_type = parse_type(parser); - } - i64 param_count = bh_arr_length(params); - AstFunctionType* new = onyx_ast_node_new(parser->allocator, - sizeof(AstFunctionType) + sizeof(AstType*) * param_count, - Ast_Kind_Function_Type); - new->token = proc_token; - new->param_count = param_count; - new->return_type = return_type; + AstType* return_type = (AstType *) &basic_type_void; + if (parser->curr->type == Token_Type_Right_Arrow) { + consume_token(parser); + return_type = parse_type(parser); + } - if (param_count > 0) - fori (i, 0, param_count) new->params[i] = params[i]; + i64 param_count = bh_arr_length(params); + AstFunctionType* new = onyx_ast_node_new(parser->allocator, + sizeof(AstFunctionType) + sizeof(AstType*) * param_count, + Ast_Kind_Function_Type); + new->token = proc_token; + new->param_count = param_count; + new->return_type = return_type; - *next_insertion = (AstType *) new; - next_insertion = NULL; - } + if (param_count > 0) + fori (i, 0, param_count) new->params[i] = params[i]; - else if (parser->curr->type == '$') { - parse_polymorphic_variable(parser, &next_insertion); - } + *next_insertion = (AstType *) new; + next_insertion = NULL; + break; + } - else if (parser->curr->type == Token_Type_Symbol) { - AstNode* symbol_node = make_node(AstNode, Ast_Kind_Symbol); - symbol_node->token = expect_token(parser, Token_Type_Symbol); + case '$': { + parse_polymorphic_variable(parser, &next_insertion); + break; + } - *next_insertion = (AstType *) symbol_node; + case Token_Type_Symbol: { + AstNode* symbol_node = make_node(AstNode, Ast_Kind_Symbol); + symbol_node->token = expect_token(parser, Token_Type_Symbol); - while (parser->curr->type == '.') { - consume_token(parser); - AstFieldAccess* field = make_node(AstFieldAccess, Ast_Kind_Field_Access); - field->token = expect_token(parser, Token_Type_Symbol); - field->expr = (AstTyped *) *next_insertion; + *next_insertion = (AstType *) symbol_node; - *next_insertion = (AstType *) field; - } + while (parser->curr->type == '.') { + consume_token(parser); + AstFieldAccess* field = make_node(AstFieldAccess, Ast_Kind_Field_Access); + field->token = expect_token(parser, Token_Type_Symbol); + field->expr = (AstTyped *) *next_insertion; - if (parser->curr->type == '(') { - OnyxToken* paren_token = expect_token(parser, '('); + *next_insertion = (AstType *) field; + } - bh_arr(AstNode *) params = NULL; - bh_arr_new(global_heap_allocator, params, 2); + if (parser->curr->type == '(') { + OnyxToken* paren_token = expect_token(parser, '('); - while (parser->curr->type != ')') { - if (parser->hit_unexpected_token) break; + bh_arr(AstNode *) params = NULL; + bh_arr_new(global_heap_allocator, params, 2); - AstNode* t = (AstNode *) parse_type(parser); - bh_arr_push(params, t); + while (parser->curr->type != ')') { + if (parser->hit_unexpected_token) break; - if (parser->curr->type != ')') - expect_token(parser, ','); - } - expect_token(parser, ')'); + AstNode* t = (AstNode *) parse_type(parser); + bh_arr_push(params, t); - AstPolyCallType* pc_type = make_node(AstPolyCallType, Ast_Kind_Poly_Call_Type); - pc_type->token = paren_token; - pc_type->callee = *next_insertion; - pc_type->params = params; + if (parser->curr->type != ')') + expect_token(parser, ','); + } + expect_token(parser, ')'); - *next_insertion = (AstType *) pc_type; - } + AstPolyCallType* pc_type = make_node(AstPolyCallType, Ast_Kind_Poly_Call_Type); + pc_type->token = paren_token; + pc_type->callee = *next_insertion; + pc_type->params = params; - next_insertion = NULL; - } + *next_insertion = (AstType *) pc_type; + } - else if (parser->curr->type == Token_Type_Keyword_Struct) { - AstStructType* s_node = parse_struct(parser); - *next_insertion = (AstType *) s_node; - next_insertion = NULL; - } + next_insertion = NULL; + break; + } - else if (parse_possible_directive(parser, "value")) { - // :ValueDirectiveHack - *next_insertion = (AstType *) parse_expression(parser); - next_insertion = NULL; - break; - } + case Token_Type_Keyword_Struct: { + AstStructType* s_node = parse_struct(parser); + *next_insertion = (AstType *) s_node; + next_insertion = NULL; + break; + } - else if (parser->curr->type == '<') { - // :TypeValueInterchange - expect_token(parser, '<'); - *next_insertion = (AstType *) parse_expression(parser); - next_insertion = NULL; - expect_token(parser, '>'); + 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: + *next_insertion = (AstType *) parse_expression(parser); + next_insertion = NULL; + break; + } - break; - } + } - else { - onyx_report_error(parser->curr->pos, "unexpected token '%b'.", parser->curr->text, parser->curr->length); - consume_token(parser); - break; + default: + onyx_report_error(parser->curr->pos, "unexpected token '%b'.", parser->curr->text, parser->curr->length); + consume_token(parser); + break; } if (next_insertion == NULL) break; diff --git a/src/onyxutils.c b/src/onyxutils.c index 47a3407a..3912ffae 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -885,8 +885,9 @@ AstStructType* polymorphic_struct_lookup(AstPolyStructType* ps_type, bh_arr(AstP bh_table_init(global_heap_allocator, ps_type->concrete_structs, 16); } - if (bh_arr_length(slns) < bh_arr_length(ps_type->poly_params)) { - onyx_report_error(pos, "Not enough arguments for polymorphic struct creation. Expected %d, got %d", + if (bh_arr_length(slns) != bh_arr_length(ps_type->poly_params)) { + onyx_report_error(pos, "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/tests/poly_structs_with_values.onyx b/tests/poly_structs_with_values.onyx index 7ca5541b..40394fa9 100644 --- a/tests/poly_structs_with_values.onyx +++ b/tests/poly_structs_with_values.onyx @@ -24,7 +24,7 @@ main :: proc (args: [] cstr) { str_member : str = default; } - swd := .{ x = 1234 }; + swd := .{ x = 1234 }; println(swd.x); println(swd.str_member); poly_match(swd);