From b89c3bedc5e11632e153e2b62bab1e0f29dc7f8e Mon Sep 17 00:00:00 2001 From: Max Wash Date: Thu, 8 May 2025 22:32:23 +0100 Subject: [PATCH] lang: ast: add diag for `do` keyword in inline for-loop --- lang/ast/for.c | 21 +++++++++++++++++++++ lang/diag.c | 8 ++++++++ lang/include/ivy/lang/diag.h | 3 +++ 3 files changed, 32 insertions(+) diff --git a/lang/ast/for.c b/lang/ast/for.c index d1b4cd9..c5507d5 100644 --- a/lang/ast/for.c +++ b/lang/ast/for.c @@ -81,6 +81,27 @@ static struct token_parse_result parse_do( = parser_get_state(ctx, struct for_parser_state); if (state->s_inline) { + struct ivy_diag *diag = parser_push_diag( + ctx, IVY_LANG_E_INCORRECT_INLINE_FOR_LOOP, + IVY_LANG_MSG_DO_UNEXPECTED_IN_INLINE_FOR, tok); + ivy_diag_push_msg( + diag, IVY_LANG_MSG_PREVIOUS_EXPRESSION_IS_FOR_BODY); + const struct ivy_char_cell *x = &state->s_body->n_end; + const struct ivy_char_cell *z = &tok->t_end; + + const struct ivy_diag_amendment a[] = { + IVY_DIAG_ADD(x->c_row, x->c_col + 1, "."), + }; + const size_t nr_a = sizeof a / sizeof a[0]; + + const struct ivy_diag_highlight hl[] = { + IVY_DIAG_HL( + HINT, x->c_row, x->c_col + 1, x->c_row, + x->c_col + 1), + }; + const size_t nr_hl = sizeof hl / sizeof hl[0]; + + ivy_diag_push_snippet(diag, x->c_row, z->c_row, a, nr_a, hl, nr_hl); return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0); } diff --git a/lang/diag.c b/lang/diag.c index bcd1fd6..b2124ef 100644 --- a/lang/diag.c +++ b/lang/diag.c @@ -8,12 +8,20 @@ static const struct ivy_diag_class diag_classes[] = { ERROR_CLASS(IVY_LANG_E_UNRECOGNISED_SYMBOL, "Unrecognised symbol"), + ERROR_CLASS( + IVY_LANG_E_INCORRECT_INLINE_FOR_LOOP, + "Incorrect inline for-loop"), }; static const size_t nr_diag_classes = sizeof diag_classes / sizeof diag_classes[0]; static const struct ivy_diag_msg diag_msg[] = { MSG(IVY_LANG_MSG_UNKNOWN_SYMBOL_ENCOUNTERED, "encountered a symbol that is not part of the Ivy syntax."), + MSG(IVY_LANG_MSG_DO_UNEXPECTED_IN_INLINE_FOR, + "`[yellow]do[reset]` is not used in inline for-loops."), + MSG(IVY_LANG_MSG_PREVIOUS_EXPRESSION_IS_FOR_BODY, + "the previous expression is used as the for-loop body. perhaps you " + "forgot a [blue]statement separator[reset]?"), }; static const size_t nr_diag_msg = sizeof diag_msg / sizeof diag_msg[0]; diff --git a/lang/include/ivy/lang/diag.h b/lang/include/ivy/lang/diag.h index d6e3209..eda974c 100644 --- a/lang/include/ivy/lang/diag.h +++ b/lang/include/ivy/lang/diag.h @@ -8,11 +8,14 @@ struct ivy_diag_ctx; enum ivy_lang_diag_code { IVY_LANG_E_NONE = 0, IVY_LANG_E_UNRECOGNISED_SYMBOL, + IVY_LANG_E_INCORRECT_INLINE_FOR_LOOP, }; enum ivy_lang_diag_msg { IVY_LANG_MSG_NONE = 0, IVY_LANG_MSG_UNKNOWN_SYMBOL_ENCOUNTERED, + IVY_LANG_MSG_DO_UNEXPECTED_IN_INLINE_FOR, + IVY_LANG_MSG_PREVIOUS_EXPRESSION_IS_FOR_BODY, }; IVY_API enum ivy_status ivy_lang_diag_ctx_init(struct ivy_diag_ctx *ctx);