made variable name in for loops optional
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 29 Nov 2021 20:00:26 +0000 (14:00 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 29 Nov 2021 20:00:26 +0000 (14:00 -0600)
src/checker.c
src/parser.c
tests/interfaces.onyx
tests/persist_locals.onyx

index fecad0160d9dfa47c1b207c9dca22fa15d0ba573..03da8f7503eac6c5ab458094bd077f062fd553f7 100644 (file)
@@ -211,10 +211,15 @@ CheckStatus check_for(AstFor* fornode) {
     Type* iter_type = fornode->iter->type;
     if (iter_type == NULL) YIELD(fornode->token->pos, "Waiting for iteration expression type to be known.");
 
+    OnyxFilePos error_loc = fornode->var->token->pos;
+    if (error_loc.filename == NULL) {
+        error_loc = fornode->token->pos;
+    }
+
     fornode->loop_type = For_Loop_Invalid;
     if (types_are_compatible(iter_type, &basic_types[Basic_Kind_I32])) {
         if (fornode->by_pointer) {
-            ERROR(fornode->var->token->pos, "Cannot iterate by pointer over a range.");
+            ERROR(error_loc, "Cannot iterate by pointer over a range.");
         }
 
         AstNumLit* low_0    = make_int_literal(context.ast_alloc, 0);
@@ -228,7 +233,7 @@ CheckStatus check_for(AstFor* fornode) {
     }
     else if (types_are_compatible(iter_type, builtin_range_type_type)) {
         if (fornode->by_pointer) {
-            ERROR(fornode->var->token->pos, "Cannot iterate by pointer over a range.");
+            ERROR(error_loc, "Cannot iterate by pointer over a range.");
         }
 
         // NOTE: Blindly copy the first range member's type which will
@@ -253,7 +258,7 @@ CheckStatus check_for(AstFor* fornode) {
     }
     else if (iter_type->kind == Type_Kind_VarArgs) {
         if (fornode->by_pointer) {
-            ERROR_(fornode->var->token->pos, "Cannot iterate by pointer over '%s'.", type_get_name(iter_type));
+            ERROR_(error_loc, "Cannot iterate by pointer over '%s'.", type_get_name(iter_type));
         }
 
         fornode->var->type = iter_type->VarArgs.elem;
@@ -269,7 +274,7 @@ CheckStatus check_for(AstFor* fornode) {
     }
     else if (type_struct_constructed_from_poly_struct(iter_type, builtin_iterator_type)) {
         if (fornode->by_pointer) {
-            ERROR(fornode->var->token->pos, "Cannot iterate by pointer over an iterator.");
+            ERROR(error_loc, "Cannot iterate by pointer over an iterator.");
         }
 
         // HACK: This assumes the Iterator type only has a single type argument.
@@ -281,7 +286,7 @@ CheckStatus check_for(AstFor* fornode) {
         fornode->var->flags |= Ast_Flag_Cannot_Take_Addr;
 
     if (fornode->loop_type == For_Loop_Invalid) {
-        ERROR_(fornode->iter->token->pos,
+        ERROR_(error_loc,
                 "Cannot iterate over a '%s'.",
                 type_get_name(iter_type));
     }
index 99a319b92da59be186c2790617103e11eb88ed43..bfe4a920d1746fcc407f8af69500b784586e536c 100644 (file)
@@ -748,7 +748,7 @@ static AstTyped* parse_factor(OnyxParser* parser) {
 
 //              This could be a cool feature where you can write:
 //
-//              foo(x, y) {
+//              foo(x, y) #{
 //                  // ...
 //              }
 //
@@ -1111,12 +1111,22 @@ static AstFor* parse_for_stmt(OnyxParser* parser) {
         for_node->by_pointer = 1;
     }
 
-    OnyxToken* local_sym = expect_token(parser, Token_Type_Symbol);
-    AstLocal* var_node = make_local(parser->allocator, local_sym, NULL);
+    if (next_tokens_are(parser, 2, Token_Type_Symbol, ':')) {
+        OnyxToken* local_sym = expect_token(parser, Token_Type_Symbol);
+        AstLocal* var_node = make_local(parser->allocator, local_sym, NULL);
 
-    for_node->var = var_node;
+        for_node->var = var_node;
+
+        expect_token(parser, ':');
+    } else {
+        // HACK
+        static char it_name[] = "it ";
+        static OnyxToken it_token = { Token_Type_Symbol, 2, it_name, { 0 } };
+
+        AstLocal* var_node = make_local(parser->allocator, &it_token, NULL);
+        for_node->var = var_node;
+    }
 
-    expect_token(parser, ':');
     for_node->iter = parse_expression(parser, 1);
     for_node->stmt = parse_block(parser, 1, NULL);
 
index f07fe6cdda50122755fdc848047207edd36b05dc..586e7c664634ecce878be5a6fed4748bd4fc5f9e 100644 (file)
@@ -74,13 +74,13 @@ consume :: macro (x: $T) -> #auto where iter.Iterable(T) {
         // Iterator over pointers get dereferenced
         macro (iter: Iterator(^$T)) -> [..] T {
             arr := array.make(T);
-            for it: iter do arr << *it;
+            for iter do arr << *it;
             return arr;
         },
 
         macro (iter: Iterator($T)) -> [..] T {
             arr := array.make(T);
-            for it: iter do arr << it;
+            for iter do arr << it;
             return arr;
         },
     }
index d3e9c40776b20c26d1e2eaccd0f039ef696e8e2d..8e9108fa49443df4a10e97f58b446152fc0c061e 100644 (file)
@@ -28,9 +28,7 @@ foo :: (x: i32) -> i32 {
 
 cached_fib :: (n: u64) -> u64 {
     #persist cache : map.Map(u64, u64);
-    if cache.hashes.data == null {
-        map.init(^cache);
-    }
+    _ :: #init () { map.init(^cache); };
 
     if n <= 1 do return n;