better error handling for using keywords as directives
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 19 Oct 2022 21:09:31 +0000 (16:09 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Wed, 19 Oct 2022 21:09:31 +0000 (16:09 -0500)
compiler/include/lex.h
compiler/src/lex.c
compiler/src/parser.c
core/container/iter.onyx

index df6844763b3ab1449ce39c3424aac4855017fc0e..55dccefb2c8cab4300587e51822e617e0643199a 100644 (file)
@@ -14,6 +14,7 @@ typedef enum TokenType {
 
     Token_Type_Comment              = 258,
 
+    Token_Type_Keyword_Start,
     Token_Type_Keyword_Package,
     Token_Type_Keyword_Struct,
     Token_Type_Keyword_Enum,
@@ -39,6 +40,7 @@ typedef enum TokenType {
     Token_Type_Keyword_Macro,
     Token_Type_Keyword_Interface,
     Token_Type_Keyword_Where,
+    Token_Type_Keyword_End,
 
     Token_Type_Right_Arrow,
     Token_Type_Left_Arrow,
index db01e43da411f9f00fd332f14e201f8e6f686dca..50576ec1380ab29d0e0bd8161a620ab83665cc53 100644 (file)
@@ -12,6 +12,7 @@ static const char* token_type_names[] = {
 
     "TOKEN_TYPE_COMMENT",
 
+    "", // start
     "package",
     "struct",
     "enum",
@@ -37,6 +38,7 @@ static const char* token_type_names[] = {
     "macro",
     "interface",
     "where",
+    "", // end
 
     "->",
     "<-",
index 4d1ed8886043f23bc35604fb26c60939173c1e6f..f5ad33887192c6c8b707dfee49ba2c8bb91fcc9c 100644 (file)
@@ -3369,9 +3369,16 @@ static void parse_top_level_statement(OnyxParser* parser) {
             }
             else {
                 OnyxToken* directive_token = expect_token(parser, '#');
-                OnyxToken* symbol_token = expect_token(parser, Token_Type_Symbol);
+                OnyxToken* symbol_token = parser->curr;
+                consume_token(parser);
+
+                onyx_report_error(directive_token->pos, Error_Critical, "Unknown directive '#%b'.", symbol_token->text, symbol_token->length);
+
+                if (symbol_token->type > Token_Type_Keyword_Start && symbol_token->type < Token_Type_Keyword_End) {
+                    onyx_report_error(directive_token->pos, Error_Critical, "Did you mean the keyword, '%s'?",
+                        token_name(symbol_token->type));
+                }
 
-                onyx_report_error(directive_token->pos, Error_Critical, "unknown directive '#%b'.", symbol_token->text, symbol_token->length);
                 return;
             }
 
index 327bcdf2f3faa58c2eb0340b7fd5893e00b4c4da..5e34063aedc25722312a3e800979231d32215ac3 100644 (file)
@@ -675,6 +675,20 @@ comp :: macro (i: $I/Iterable, value: Code) => {
 }
 
 
+//
+// Maybe at some point an alternate allocator would be good
+// for this? For now, I think the temporary allocator is sufficient.
+generator :: (ctx: ^$Ctx, gen: (^Ctx) -> ($T, bool)) -> Iterator(T) {
+    v := raw_alloc(context.temp_allocator, sizeof Ctx);
+    core.memory.copy(v, ctx, sizeof Ctx);
+
+    return .{
+        data = v,
+        next = gen
+    };
+}
+
+
 #if runtime.Multi_Threading_Enabled {
     #local sync :: core.sync