'typeof' bugfixes and added quick functions (=>)
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 23 Aug 2021 12:55:03 +0000 (07:55 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 23 Aug 2021 12:55:03 +0000 (07:55 -0500)
bin/onyx
src/onyxchecker.c
src/onyxclone.c
src/onyxparser.c

index dcc66d87ec88b434b61b2127f01e166884245602..1873432ac0305919d7fd731d517657bdf0ed8bd2 100755 (executable)
Binary files a/bin/onyx and b/bin/onyx differ
index f17d73543b6ca27f34ab897b0485bd73df2c4941..f326877862a54d87d8c23a904f620ec8eec63324 100644 (file)
@@ -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;
 
index 4c08c4ba66735f6e8fcc33d93e7b73c5fb51092b..63b9a46d61ad5f71b157d2d8f01cf672390e3395 100644 (file)
@@ -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);
index fd52bb483f69ee1d137d7e8ab8baaa3e3d6c810e..aedca557b468d28b1b520084db87b34843a33eea 100644 (file)
@@ -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);