added some robustness and better errors
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 5 Sep 2020 14:11:07 +0000 (09:11 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 5 Sep 2020 14:11:07 +0000 (09:11 -0500)
docs/plan
include/onyxastnodes.h
onyx
progs/poly_test.onyx
src/onyxchecker.c
src/onyxparser.c
src/onyxwasm.c

index a765769419c7afbc409caec54f9e3a702dfa0e7e..8b0c0b6272edb2f6afc8dad99196f2eb7c990b9f 100644 (file)
--- a/docs/plan
+++ b/docs/plan
@@ -230,7 +230,7 @@ HOW:
             - This looks very simple
             - I think all the infrastructure is there for this
 
-        [ ] data structure based iteration
+        [X] data structure based iteration
             - Currently, I do not plan on having custom iterators. This may very well change in the near future.
             - For now, a for loop will be reimagined to look like:
                 for val: iterable ...
index 599a5adbc78532b849429179db9feaf1bd74fe68..4ec59f57f2887457f2bb9a7d0a89254e6f8114ea 100644 (file)
@@ -177,6 +177,8 @@ typedef enum AstFlags {
     Ast_Flag_Struct_Is_Union   = BH_BIT(17),
 
     Ast_Flag_No_Clone          = BH_BIT(18),
+
+    Ast_Flag_Cannot_Take_Addr  = BH_BIT(19),
 } AstFlags;
 
 typedef enum UnaryOp {
diff --git a/onyx b/onyx
index 93ad2c335c45c7618426304e61a2e7c2f379f783..4bf58d112dfa464587c19338e2baab937a0090ad 100755 (executable)
Binary files a/onyx and b/onyx differ
index f966ab9ba4d1a0e2df892667eb23e12def1f9a25..f682285bfffbed4b0d866206388af4e940f94b67 100644 (file)
@@ -94,7 +94,24 @@ print_v2 :: proc (v: V2) #add_overload print {
     print(")");
 }
 
+switch_demo :: proc {
+    switch a := 4; a {
+        case 4, 5, 6 {
+            print("a was 4, 5, or 6\n");
+            fallthrough fallthrough;
+        }
+
+        case 10 do print("a was 10\n");
+
+        case #default {
+            print("a was something else.\n");
+        }
+    }
+}
+
 main :: proc (args: [] cstring) {
+    switch_demo();
+
     res := compose(5, proc (x: i32) -> i32 do return x * 3;,
                       proc (x: i32) -> i32 do return x + 5;);
     print(res);
index d2f1f51a3891bb4e0aa80f50a7ec93d2dd64f062..56e63db0ec2c66a00191776371731eab22eaade1 100644 (file)
@@ -113,6 +113,7 @@ b32 check_for(AstFor* fornode) {
         // NOTE: Blindly copy the first range member's type which will
         // be the low value.                - brendanfh 2020/09/04
         fornode->var->type = builtin_range_type_type->Struct.memarr[0]->type;
+        fornode->var->flags |= Ast_Flag_Cannot_Take_Addr;
         fornode->loop_type = For_Loop_Range;
 
     }
@@ -142,6 +143,9 @@ b32 check_for(AstFor* fornode) {
         fornode->loop_type = For_Loop_DynArr;
     }
 
+    if (fornode->by_pointer)
+        fornode->var->flags |= Ast_Flag_Cannot_Take_Addr;
+
     if (!can_iterate) {
         onyx_report_error(fornode->iter->token->pos,
                 "Cannot iterate over a '%s'.",
@@ -807,11 +811,12 @@ b32 check_struct_literal(AstStructLiteral* sl) {
 b32 check_address_of(AstAddressOf* aof) {
     if (check_expression(&aof->expr)) return 1;
 
-    if (aof->expr->kind != Ast_Kind_Array_Access
+    if ((aof->expr->kind != Ast_Kind_Array_Access
             && aof->expr->kind != Ast_Kind_Dereference
             && aof->expr->kind != Ast_Kind_Field_Access
             && aof->expr->kind != Ast_Kind_Memres
-            && aof->expr->kind != Ast_Kind_Local) {
+            && aof->expr->kind != Ast_Kind_Local)
+            || (aof->expr->flags & Ast_Flag_Cannot_Take_Addr) != 0) {
         onyx_report_error(aof->token->pos, "Cannot take the address of value.");
         return 1;
     }
index fe9c353d91504ec3f1ed87ff42d721906572ef3c..9fa2a706143474bfb0785201ae20d0df87558a81 100644 (file)
@@ -897,7 +897,11 @@ static AstSwitch* parse_switch_stmt(OnyxParser* parser) {
 
         if (parse_possible_directive(parser, "default")) {
             switch_node->default_case = parse_block(parser);
-            continue;
+
+            if (parser->curr->type != '}') {
+                onyx_report_error(parser->curr->pos, "The #default case must be the last case in a switch statement.\n");
+            }
+            break;
         }
 
         AstTyped* value = parse_expression(parser);
index 9661f1d6e48dfe71d5ea7d197bf06fc73ba658c6..bddcf32e0c9d4486c727a2bed4296212b3aadac0 100644 (file)
@@ -420,15 +420,17 @@ EMIT_FUNC(block, AstBlock* block, b32 generate_block_headers) {
     *pcode = code;
 }
 
-EMIT_FUNC(structured_jump, i32 jump_count, JumpType jump) {
+EMIT_FUNC(structured_jump, AstJump* jump) {
     bh_arr(WasmInstruction) code = *pcode;
 
     static const u8 wants[Jump_Type_Count] = { 1, 2, 3 };
 
     i32 labelidx = 0;
-    u8 wanted = wants[jump];
+    u8 wanted = wants[jump->jump];
     b32 success = 0;
 
+    u32 jump_count = jump->count;
+
     i32 len = bh_arr_length(mod->structured_jump_target) - 1;
     for (u8* t = &bh_arr_last(mod->structured_jump_target); len >= 0; len--, t--) {
         if (*t == wanted) jump_count--;
@@ -446,7 +448,7 @@ EMIT_FUNC(structured_jump, i32 jump_count, JumpType jump) {
         if (bh_arr_last(code).type != WI_JUMP)
             WID(WI_JUMP, labelidx);
     } else {
-        assert(("Invalid structured jump", 0));
+        onyx_report_error(jump->token->pos, "Invalid structured jump.");
     }
 
     *pcode = code;
@@ -461,7 +463,7 @@ EMIT_FUNC(statement, AstNode* stmt) {
         case Ast_Kind_While:      emit_while(mod, &code, (AstIfWhile *) stmt); break;
         case Ast_Kind_For:        emit_for(mod, &code, (AstFor *) stmt); break;
         case Ast_Kind_Switch:     emit_switch(mod, &code, (AstSwitch *) stmt); break;
-        case Ast_Kind_Jump:       emit_structured_jump(mod, &code, ((AstJump *) stmt)->count, ((AstJump *) stmt)->jump); break;
+        case Ast_Kind_Jump:       emit_structured_jump(mod, &code, (AstJump *) stmt); break;
         case Ast_Kind_Block:      emit_block(mod, &code, (AstBlock *) stmt, 1); break;
         case Ast_Kind_Defer:      emit_defer(mod, &code, (AstDefer *) stmt); break;
         default:                  emit_expression(mod, &code, (AstTyped *) stmt); break;