From: Brendan Hansen Date: Fri, 31 Jul 2020 01:37:10 +0000 (-0500) Subject: a 'do' statement is now allowed anywhere a single statement block would be X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=540285e23fbfd63117921172047c255db1ef2736;p=onyx.git a 'do' statement is now allowed anywhere a single statement block would be --- diff --git a/docs/plan b/docs/plan index c1ce3901..ebb99d2f 100644 --- a/docs/plan +++ b/docs/plan @@ -140,6 +140,8 @@ HOW: [ ] Hex literals + [ ] All code paths return correct value + [ ] #file_contents [ ] #initialize structs diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index 60e592fe..ccfcb592 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -276,7 +276,7 @@ struct AstContinue { AstNode_base; u64 count; }; // Structure Nodes struct AstBlock { AstNode_base; AstNode *body; Scope *scope; }; -struct AstWhile { AstNode_base; AstTyped *cond; AstNode *stmt; }; +struct AstWhile { AstNode_base; AstTyped *cond; AstBlock *stmt; }; struct AstDefer { AstNode_base; AstNode *stmt; }; struct AstFor { AstNode_base; @@ -289,14 +289,14 @@ struct AstFor { AstTyped *start, *end, *step; - AstNode *stmt; + AstBlock *stmt; }; struct AstIf { AstNode_base; AstTyped *cond; - AstNode* true_stmt; - AstNode* false_stmt; + AstBlock *true_stmt; + AstBlock *false_stmt; }; // Type Nodes diff --git a/include/onyxlex.h b/include/onyxlex.h index e122fda3..d7c4f468 100644 --- a/include/onyxlex.h +++ b/include/onyxlex.h @@ -29,6 +29,7 @@ typedef enum TokenType { Token_Type_Keyword_Sizeof, Token_Type_Keyword_Alignof, Token_Type_Keyword_Defer, + Token_Type_Keyword_Do, Token_Type_Right_Arrow, Token_Type_Left_Arrow, diff --git a/onyx b/onyx index 3cab3d48..c72c7889 100755 Binary files a/onyx and b/onyx differ diff --git a/progs/alloc.onyx b/progs/alloc.onyx index f5899f07..56fdf7ef 100644 --- a/progs/alloc.onyx +++ b/progs/alloc.onyx @@ -59,7 +59,7 @@ heap_init :: proc { } heap_alloc :: proc (size_: u32, align: u32) -> rawptr { - if size_ == 0 return null; + if size_ == 0 do return null; size := size_ + sizeof heap_block; if size % align != 0 { @@ -91,7 +91,7 @@ heap_alloc :: proc (size_: u32, align: u32) -> rawptr { return cast(rawptr) (cast(u32) ret + sizeof heap_block); } - new_pages :: (size - heap_state.remaining_space) >> 16; + new_pages :: ((size - heap_state.remaining_space) >> 16) + 1; if memory_grow(new_pages) == -1 { // out of memory return null; @@ -121,7 +121,7 @@ heap_free :: proc (ptr: rawptr) { } heap_alloc_proc :: proc (data: rawptr, aa: AllocAction, size: u32, align: u32, oldptr: rawptr) -> rawptr { - if aa == AllocAction.Alloc return heap_alloc(size, align); + if aa == AllocAction.Alloc do return heap_alloc(size, align); if aa == AllocAction.Free { heap_free(oldptr); return null; diff --git a/progs/alloc_test.onyx b/progs/alloc_test.onyx index f6d6dea7..e5cf6d5b 100644 --- a/progs/alloc_test.onyx +++ b/progs/alloc_test.onyx @@ -6,10 +6,10 @@ use package printing deferred_example :: proc -> i32 { arr := cast([] i32) malloc(sizeof [8] i32); - defer if cast(rawptr) arr != null mfree(arr); + defer if cast(rawptr) arr != null do mfree(arr); - for i: 0, 8 arr[i] = i * i; - for i: 0, 8 print(arr[i]); + for i: 0, 8 do arr[i] = i * i; + for i: 0, 8 do print(arr[i]); return arr[1] + arr[7]; } @@ -21,16 +21,16 @@ proc #export "main" { print(deferred_example()); first := cast([] i32) malloc(sizeof [4] i32); - for i: 0, 4 first[i] = i * 2; + for i: 0, 4 do first[i] = i * 2; second := cast([] f32) malloc(sizeof [24] f32); - for i: 0, 24 second[i] = cast(f32) i; + for i: 0, 24 do second[i] = cast(f32) i; print(cast(u32) first); print(cast(u32) second); - for i: 0, 4 print(first[i]); - for i: 0, 24 print(second[i]); + for i: 0, 4 do print(first[i]); + for i: 0, 24 do print(second[i]); mfree(first); diff --git a/progs/print_funcs.onyx b/progs/print_funcs.onyx index 15f17cbb..d368c5f7 100644 --- a/progs/print_funcs.onyx +++ b/progs/print_funcs.onyx @@ -12,19 +12,19 @@ PrintableArray :: struct { } print_i32arr :: proc (arr: [] i32, len: i32) { - for i: 0, len print(arr[i]); + for i: 0, len do print(arr[i]); } print_i64arr :: proc (arr: [] i64, len: i32) { - for i: 0, len print(arr[i]); + for i: 0, len do print(arr[i]); } print_f32arr :: proc (arr: [] f32, len: i32) { - for i: 0, len print(arr[i]); + for i: 0, len do print(arr[i]); } print_f64arr :: proc (arr: [] f64, len: i32) { - for i: 0, len print(arr[i]); + for i: 0, len do print(arr[i]); } // NOTE: print null-terminated string @@ -37,7 +37,7 @@ print_str :: proc (str: ^u8) { } print_str_len :: proc (str: [] u8, len: i32) { - for i: 0, len print(cast(i32) str[i]); + for i: 0, len do print(cast(i32) str[i]); } print :: proc #overloaded { diff --git a/src/onyxchecker.c b/src/onyxchecker.c index 63bf046e..baea6318 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -65,8 +65,8 @@ CHECK(if, AstIf* ifnode) { return 1; } - if (ifnode->true_stmt) if (check_statement(ifnode->true_stmt)) return 1; - if (ifnode->false_stmt) if (check_statement(ifnode->false_stmt)) return 1; + if (ifnode->true_stmt) if (check_statement((AstNode *) ifnode->true_stmt)) return 1; + if (ifnode->false_stmt) if (check_statement((AstNode *) ifnode->false_stmt)) return 1; return 0; } @@ -81,7 +81,7 @@ CHECK(while, AstWhile* whilenode) { return 1; } - return check_statement(whilenode->stmt); + return check_block(whilenode->stmt); } CHECK(for, AstFor* fornode) { @@ -116,7 +116,7 @@ CHECK(for, AstFor* fornode) { } - if (check_statement(fornode->stmt)) return 1; + if (check_block(fornode->stmt)) return 1; return 0; } diff --git a/src/onyxlex.c b/src/onyxlex.c index a08b46e8..9546f7bd 100644 --- a/src/onyxlex.c +++ b/src/onyxlex.c @@ -27,6 +27,7 @@ static const char* token_type_names[] = { "sizeof", "alignof", "defer", + "do", "->", "<-", @@ -164,6 +165,7 @@ OnyxToken* onyx_get_token(OnyxTokenizer* tokenizer) { LITERAL_TOKEN("sizeof", 1, Token_Type_Keyword_Sizeof); LITERAL_TOKEN("alignof", 1, Token_Type_Keyword_Alignof); LITERAL_TOKEN("defer", 1, Token_Type_Keyword_Defer); + LITERAL_TOKEN("do", 1, Token_Type_Keyword_Do); LITERAL_TOKEN("true", 1, Token_Type_Literal_True); LITERAL_TOKEN("false", 1, Token_Type_Literal_False); LITERAL_TOKEN("->", 0, Token_Type_Right_Arrow); diff --git a/src/onyxparser.c b/src/onyxparser.c index 17903d2c..7702fd91 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -512,7 +512,7 @@ static AstIf* parse_if_stmt(OnyxParser* parser) { expect_token(parser, Token_Type_Keyword_If); AstTyped* cond = parse_expression(parser); - AstNode* true_stmt = parse_statement(parser); + AstBlock* true_stmt = parse_block(parser); AstIf* if_node = make_node(AstIf, Ast_Kind_If); AstIf* root_if = if_node; @@ -526,20 +526,20 @@ static AstIf* parse_if_stmt(OnyxParser* parser) { AstIf* elseif_node = make_node(AstIf, Ast_Kind_If); cond = parse_expression(parser); - true_stmt = parse_statement(parser); + true_stmt = parse_block(parser); elseif_node->cond = cond; if (true_stmt != NULL) elseif_node->true_stmt = true_stmt; - if_node->false_stmt = (AstNode *) elseif_node; + if_node->false_stmt = (AstBlock *) elseif_node; if_node = elseif_node; } if (parser->curr->type == Token_Type_Keyword_Else) { consume_token(parser); - AstNode* false_stmt = parse_statement(parser); + AstBlock* false_stmt = parse_block(parser); if (false_stmt != NULL) if_node->false_stmt = false_stmt; } @@ -552,7 +552,7 @@ static AstWhile* parse_while_stmt(OnyxParser* parser) { OnyxToken* while_token = expect_token(parser, Token_Type_Keyword_While); AstTyped* cond = parse_expression(parser); - AstNode* stmt = parse_statement(parser); + AstBlock* stmt = parse_block(parser); AstWhile* while_node = make_node(AstWhile, Ast_Kind_While); while_node->token = while_token; @@ -582,7 +582,7 @@ static AstFor* parse_for_stmt(OnyxParser* parser) { for_node->step = parse_expression(parser); } - for_node->stmt = parse_statement(parser); + for_node->stmt = parse_block(parser); return for_node; } @@ -681,6 +681,7 @@ static AstNode* parse_statement(OnyxParser* parser) { case '{': case Token_Type_Empty_Block: + case Token_Type_Keyword_Do: needs_semicolon = 0; retval = (AstNode *) parse_block(parser); break; @@ -785,6 +786,17 @@ static AstBlock* parse_block(OnyxParser* parser) { return block; } + if (parser->curr->type == Token_Type_Keyword_Do) { + consume_token(parser); + block->body = parse_statement(parser); + return block; + } + + if (parser->curr->type != '{') { + expect_token(parser, '{'); + find_token(parser, '}'); + return block; + } expect_token(parser, '{'); AstNode** next = &block->body; diff --git a/src/onyxsymres.c b/src/onyxsymres.c index 0e9dca68..3015662b 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -273,13 +273,13 @@ static void symres_if(AstIf* ifnode) { // // The declaration will cause a problem but semantically the above // doesn't make sense. - if (ifnode->true_stmt != NULL) symres_statement(ifnode->true_stmt); - if (ifnode->false_stmt != NULL) symres_statement(ifnode->false_stmt); + if (ifnode->true_stmt != NULL) symres_statement((AstNode *) ifnode->true_stmt); + if (ifnode->false_stmt != NULL) symres_statement((AstNode *) ifnode->false_stmt); } static void symres_while(AstWhile* whilenode) { symres_expression(&whilenode->cond); - symres_statement(whilenode->stmt); + symres_block(whilenode->stmt); } static void symres_for(AstFor* fornode) { @@ -293,7 +293,7 @@ static void symres_for(AstFor* fornode) { symres_expression(&fornode->end); if (fornode->step) symres_expression(&fornode->step); - symres_statement(fornode->stmt); + symres_block(fornode->stmt); scope_leave(); } diff --git a/src/onyxwasm.c b/src/onyxwasm.c index c1d963aa..4bd78cc9 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -498,24 +498,20 @@ COMPILE_FUNC(if, AstIf* if_node) { bh_arr_push(mod->structured_jump_target, 0); if (if_node->true_stmt) { - if (if_node->true_stmt->kind == Ast_Kind_Block) { - forll (AstNode, stmt, ((AstBlock *) if_node->true_stmt)->body, next) { - compile_statement(mod, &code, stmt); - } - } else { - compile_statement(mod, &code, if_node->true_stmt); + forll (AstNode, stmt, if_node->true_stmt->body, next) { + compile_statement(mod, &code, stmt); } } if (if_node->false_stmt) { WI(WI_ELSE); - if (if_node->false_stmt->kind == Ast_Kind_Block) { + if (if_node->false_stmt->kind == Ast_Kind_If) { + compile_if(mod, &code, (AstIf *) if_node->false_stmt); + } else { forll (AstNode, stmt, ((AstBlock *) if_node->false_stmt)->body, next) { compile_statement(mod, &code, stmt); } - } else { - compile_statement(mod, &code, if_node->false_stmt); } } @@ -541,12 +537,8 @@ COMPILE_FUNC(while, AstWhile* while_node) { bh_arr_push(mod->structured_jump_target, 1); bh_arr_push(mod->structured_jump_target, 2); - if (while_node->stmt->kind == Ast_Kind_Block) { - forll (AstNode, stmt, ((AstBlock *) while_node->stmt)->body, next) { - compile_statement(mod, &code, stmt); - } - } else { - compile_statement(mod, &code, while_node->stmt); + forll (AstNode, stmt, while_node->stmt->body, next) { + compile_statement(mod, &code, stmt); } compile_deferred_stmts(mod, &code, (AstNode *) while_node); @@ -581,12 +573,8 @@ COMPILE_FUNC(for, AstFor* for_node) { WI(WI_I32_GE_S); WID(WI_COND_JUMP, 0x01); - if (for_node->stmt->kind == Ast_Kind_Block) { - forll (AstNode, stmt, ((AstBlock *) for_node->stmt)->body, next) { - compile_statement(mod, &code, stmt); - } - } else { - compile_statement(mod, &code, for_node->stmt); + forll (AstNode, stmt, for_node->stmt->body, next) { + compile_statement(mod, &code, stmt); } if (for_node->step == NULL)