From 61139ef2073b7cf35c6dd5990fee1a4a65d41661 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Wed, 19 Oct 2022 16:09:31 -0500 Subject: [PATCH] better error handling for using keywords as directives --- compiler/include/lex.h | 2 ++ compiler/src/lex.c | 2 ++ compiler/src/parser.c | 11 +++++++++-- core/container/iter.onyx | 14 ++++++++++++++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/compiler/include/lex.h b/compiler/include/lex.h index df684476..55dccefb 100644 --- a/compiler/include/lex.h +++ b/compiler/include/lex.h @@ -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, diff --git a/compiler/src/lex.c b/compiler/src/lex.c index db01e43d..50576ec1 100644 --- a/compiler/src/lex.c +++ b/compiler/src/lex.c @@ -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 "->", "<-", diff --git a/compiler/src/parser.c b/compiler/src/parser.c index 4d1ed888..f5ad3388 100644 --- a/compiler/src/parser.c +++ b/compiler/src/parser.c @@ -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; } diff --git a/core/container/iter.onyx b/core/container/iter.onyx index 327bcdf2..5e34063a 100644 --- a/core/container/iter.onyx +++ b/core/container/iter.onyx @@ -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 -- 2.25.1