From: Brendan Hansen Date: Mon, 23 Aug 2021 12:55:03 +0000 (-0500) Subject: 'typeof' bugfixes and added quick functions (=>) X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=a30de48c9370eba453815b1272d027f359c407de;p=onyx.git 'typeof' bugfixes and added quick functions (=>) --- diff --git a/bin/onyx b/bin/onyx index dcc66d87..1873432a 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/src/onyxchecker.c b/src/onyxchecker.c index f17d7354..f3268778 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -361,7 +361,7 @@ CheckStatus check_switch(AstSwitch* switchnode) { } resolve_expression_type((*value)); - promote_numlit_to_larger((AstNumLit *) (*value)); + // promote_numlit_to_larger((AstNumLit *) (*value)); if (add_case_to_switch_statement(switchnode, ((AstNumLit *) (*value))->value.l, sc->block, sc->block->token->pos)) return Check_Error; @@ -1581,6 +1581,7 @@ CheckStatus check_method_call(AstBinaryOp** mcall) { CheckStatus check_size_of(AstSizeOf* so) { fill_in_array_count(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) return Check_Yield_Macro; @@ -1592,6 +1593,7 @@ CheckStatus check_size_of(AstSizeOf* so) { CheckStatus check_align_of(AstAlignOf* ao) { fill_in_array_count(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) return Check_Yield_Macro; @@ -1966,6 +1968,10 @@ CheckStatus check_struct(AstStructType* s_node) { if (s_node->entity_defaults && s_node->entity_defaults->state < Entity_State_Check_Types) return Check_Yield_Macro; bh_arr_each(AstStructMember *, smem, s_node->members) { + if ((*smem)->type_node != NULL) { + CHECK(type, (*smem)->type_node); + } + if ((*smem)->type_node == NULL && (*smem)->initial_value != NULL) { CHECK(expression, &(*smem)->initial_value); @@ -2122,6 +2128,7 @@ CheckStatus check_function_header(AstFunction* func) { } CheckStatus check_memres_type(AstMemRes* memres) { + CHECK(type, memres->type_node); fill_in_type((AstTyped *) memres); if (memres->type_node && !memres->type) return Check_Yield_Macro; return Check_Success; @@ -2159,6 +2166,8 @@ CheckStatus check_memres(AstMemRes* memres) { } CheckStatus check_type(AstType* type) { + if (type == NULL) return Check_Success; + while (type->kind == Ast_Kind_Type_Alias) type = ((AstTypeAlias *) type)->to; diff --git a/src/onyxclone.c b/src/onyxclone.c index 4c08c4ba..63b9a46d 100644 --- a/src/onyxclone.c +++ b/src/onyxclone.c @@ -246,6 +246,8 @@ AstNode* ast_clone(bh_allocator a, void* n) { ((AstIfWhile *) nn)->assignment->left = (AstTyped *) ((AstIfWhile *) nn)->local; ((AstIfWhile *) nn)->cond = (AstTyped *) ast_clone(a, ((AstIfWhile *) node)->cond); + //fallthrough + case Ast_Kind_Static_If: ((AstIfWhile *) nn)->true_stmt = (AstBlock *) ast_clone(a, ((AstIfWhile *) node)->true_stmt); ((AstIfWhile *) nn)->false_stmt = (AstBlock *) ast_clone(a, ((AstIfWhile *) node)->false_stmt); diff --git a/src/onyxparser.c b/src/onyxparser.c index fd52bb48..aedca557 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -62,6 +62,7 @@ static AstStructType* parse_struct(OnyxParser* parser); static void parse_function_params(OnyxParser* parser, AstFunction* func); static b32 parse_possible_directive(OnyxParser* parser, const char* dir); static b32 parse_possible_function_definition(OnyxParser* parser, AstTyped** ret); +static b32 parse_possible_quick_function_definition(OnyxParser* parser, AstTyped** ret); static AstFunction* parse_function_definition(OnyxParser* parser, OnyxToken* token); static AstTyped* parse_global_declaration(OnyxParser* parser); static AstEnumType* parse_enum_declaration(OnyxParser* parser); @@ -315,6 +316,7 @@ static AstTyped* parse_factor(OnyxParser* parser) { switch ((u16) parser->curr->type) { case '(': { if (parse_possible_function_definition(parser, &retval)) break; + if (parse_possible_quick_function_definition(parser, &retval)) break; consume_token(parser); retval = parse_compound_expression(parser, 0); @@ -2113,16 +2115,6 @@ static AstFunction* parse_function_definition(OnyxParser* parser, OnyxToken* tok } static b32 parse_possible_function_definition(OnyxParser* parser, AstTyped** ret) { - #if 0 - if (parser->curr->type == Token_Type_Keyword_Proc) { - OnyxToken* proc_token = expect_token(parser, Token_Type_Keyword_Proc); - onyx_report_warning(proc_token->pos, "Warning: 'proc' is a deprecated keyword."); - AstFunction* func_node = parse_function_definition(parser, proc_token); - *ret = (AstTyped *) func_node; - return 1; - } - #endif - if (parser->curr->type == '(') { OnyxToken* matching_paren = find_matching_paren(parser->curr); if (matching_paren == NULL) return 0; @@ -2156,6 +2148,122 @@ static b32 parse_possible_function_definition(OnyxParser* parser, AstTyped** ret return 0; } +static b32 parse_possible_quick_function_definition(OnyxParser* parser, AstTyped** ret) { + if (parser->curr->type != '(') return 0; + + OnyxToken* matching_paren = find_matching_paren(parser->curr); + if (matching_paren == NULL) return 0; + + // :LinearTokenDependent + OnyxToken* token_after_paren = matching_paren + 1; + if (token_after_paren->type != '=' || (token_after_paren + 1)->type != '>') + return 0; + + OnyxToken* proc_token = expect_token(parser, '('); + + bh_arr(OnyxToken*) params=NULL; + bh_arr_new(global_heap_allocator, params, 4); + + while (parser->curr->type != ')') { + if (parser->hit_unexpected_token) return 0; + + bh_arr_push(params, expect_token(parser, Token_Type_Symbol)); + + if (parser->curr->type != ')') { + expect_token(parser, ','); + } + } + + expect_token(parser, ')'); + expect_token(parser, '='); + expect_token(parser, '>'); + + bh_arr(AstNode*) poly_params=NULL; + bh_arr_new(global_heap_allocator, poly_params, bh_arr_length(params)); + bh_arr_each(OnyxToken*, param, params) { + char text[512]; + memset(text, 0, 512); + strncat(text, "__type_", 511); + token_toggle_end(*param); + strncat(text, (*param)->text, 511); + token_toggle_end(*param); + + OnyxToken* new_token = bh_alloc(parser->allocator, sizeof(OnyxToken)); + new_token->type = Token_Type_Symbol; + new_token->length = 7 + (*param)->length; + new_token->text = bh_strdup(parser->allocator, text); + new_token->pos = (*param)->pos; + + AstNode* type_node = make_symbol(parser->allocator, new_token); + bh_arr_push(poly_params, type_node); + } + + AstFunction* func_node = make_node(AstFunction, Ast_Kind_Function); + AstPolyProc* poly_proc = make_node(AstPolyProc, Ast_Kind_Polymorphic_Proc); + + bh_arr_new(global_heap_allocator, func_node->params, bh_arr_length(params)); + fori (i, 0, bh_arr_length(params)) { + AstLocal* param_local = make_local(parser->allocator, params[i], (AstType *) poly_params[i]); + param_local->kind = Ast_Kind_Param; + + bh_arr_push(func_node->params, ((AstParam) { + .local = param_local, + .default_value = NULL, + + .vararg_kind = 0, + .use_processed = 0, + })); + } + + AstBlock* body_block; + AstType* return_type; + + if (parser->curr->type == '{') { + body_block = parse_block(parser, 1); + return_type = (AstType *) &basic_type_void; + + } else { + AstTyped* body = parse_expression(parser, 0); + + AstReturn* return_node = make_node(AstReturn, Ast_Kind_Return); + return_node->token = body->token; + return_node->expr = body; + + body_block = make_node(AstBlock, Ast_Kind_Block); + body_block->token = body->token; + body_block->body = (AstNode *) return_node; + + AstTypeOf* return_type_of = make_node(AstTypeOf, Ast_Kind_Typeof); + return_type_of->token = body->token; + return_type_of->expr = body; + return_type = (AstType *) return_type_of; + } + + func_node->token = proc_token; + func_node->body = body_block; + func_node->return_type = (AstType *) return_type; + + poly_proc->token = proc_token; + bh_arr_new(global_heap_allocator, poly_proc->poly_params, bh_arr_length(params)); + fori (i, 0, bh_arr_length(params)) { + bh_arr_push(poly_proc->poly_params, ((AstPolyParam) { + .kind = PSK_Type, + .idx = i, + .poly_sym = poly_params[i], + .type_expr = (AstType *) poly_params[i], + .type = NULL, + })); + } + poly_proc->base_func = func_node; + + ENTITY_SUBMIT(poly_proc); + *ret = (AstTyped *) poly_proc; + + bh_arr_free(params); + bh_arr_free(poly_params); + return 1; +} + static AstTyped* parse_global_declaration(OnyxParser* parser) { AstGlobal* global_node = make_node(AstGlobal, Ast_Kind_Global); global_node->token = expect_token(parser, Token_Type_Keyword_Global);