lang: ast: implement parsing of break/continue loop-control statements

This commit is contained in:
2025-09-08 15:55:12 +01:00
parent 84e52b1649
commit bf250179da
6 changed files with 85 additions and 1 deletions

View File

@@ -110,6 +110,23 @@ enum ivy_status arith_push_operand(
b_queue_push_back(&state->s_output_queue, &v->n_entry);
break;
}
case IVY_TOK_KEYWORD: {
struct ivy_ast_node *v = NULL;
switch (tok->t_keyword) {
case IVY_KW_BREAK:
v = ast_node_create(IVY_AST_LOOP_BREAK);
break;
case IVY_KW_CONTINUE:
v = ast_node_create(IVY_AST_LOOP_REPEAT);
break;
default:
return IVY_ERR_BAD_SYNTAX;
}
ivy_ast_node_set_bounds_from_token((struct ivy_ast_node *)v, tok);
b_queue_push_back(&state->s_output_queue, &v->n_entry);
break;
}
default:
return IVY_ERR_BAD_SYNTAX;
}

View File

@@ -78,8 +78,10 @@ struct ast_node_type expr_node_ops = {
.n_keyword_parsers = {
/* statement keywords */
KW_PARSER(FOR, stmt_parse_for),
KW_PARSER(TRY, stmt_parse_try),
KW_PARSER(WHILE, stmt_parse_while),
KW_PARSER(BREAK, stmt_parse_break),
KW_PARSER(CONTINUE, stmt_parse_continue),
KW_PARSER(TRY, stmt_parse_try),
KW_PARSER(MATCH, stmt_parse_match),
KW_PARSER(IF, stmt_parse_if),
KW_PARSER(THEN, stmt_parse_end),

View File

@@ -174,5 +174,9 @@ struct token_parse_result stmt_parse_else(
struct ivy_parser *ctx, struct ivy_token *tok);
struct token_parse_result stmt_parse_end(
struct ivy_parser *ctx, struct ivy_token *tok);
extern struct token_parse_result stmt_parse_break(
struct ivy_parser *ctx, struct ivy_token *tok);
extern struct token_parse_result stmt_parse_continue(
struct ivy_parser *ctx, struct ivy_token *tok);
#endif

View File

@@ -232,3 +232,35 @@ struct token_parse_result stmt_parse_end(
result.r_flags |= PARSE_REPEAT_TOKEN;
return result;
}
struct token_parse_result stmt_parse_break(
struct ivy_parser *ctx, struct ivy_token *tok)
{
struct expr_parser_state *state
= parser_get_state(ctx, struct expr_parser_state);
if (state->s_prev_component != EXPR_CMP_NONE) {
return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0);
}
arith_push_operand(state, tok);
state->s_prev_component = EXPR_CMP_KEYWORD;
return PARSE_RESULT(IVY_OK, 0);
}
struct token_parse_result stmt_parse_continue(
struct ivy_parser *ctx, struct ivy_token *tok)
{
struct expr_parser_state *state
= parser_get_state(ctx, struct expr_parser_state);
if (state->s_prev_component != EXPR_CMP_NONE) {
return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0);
}
arith_push_operand(state, tok);
state->s_prev_component = EXPR_CMP_KEYWORD;
return PARSE_RESULT(IVY_OK, 0);
}

21
lang/ast/loop-control.c Normal file
View File

@@ -0,0 +1,21 @@
#include "ctx.h"
#include "node.h"
#include <blue/object/string.h>
static void to_string(struct ivy_ast_node *node, b_string *str)
{
b_string_append_cstrf(str, "%s", ivy_ast_node_type_to_string(node->n_type));
}
struct ast_node_type loop_break_node_ops = {
.n_to_string = to_string,
.n_state_size = sizeof(struct parser_state),
.n_node_size = sizeof(struct ivy_ast_loop_break_node),
};
struct ast_node_type loop_repeat_node_ops = {
.n_to_string = to_string,
.n_state_size = sizeof(struct parser_state),
.n_node_size = sizeof(struct ivy_ast_loop_repeat_node),
};

View File

@@ -30,6 +30,8 @@ extern struct ast_node_type cond_node_ops;
extern struct ast_node_type match_node_ops;
extern struct ast_node_type while_loop_node_ops;
extern struct ast_node_type for_loop_node_ops;
extern struct ast_node_type loop_break_node_ops;
extern struct ast_node_type loop_repeat_node_ops;
extern struct ast_node_type return_node_ops;
extern struct ast_node_type property_node_ops;
extern struct ast_node_type lambda_node_ops;
@@ -66,6 +68,8 @@ static const struct ast_node_type *node_ops[] = {
[IVY_AST_MATCH] = &match_node_ops,
[IVY_AST_WHILE_LOOP] = &while_loop_node_ops,
[IVY_AST_FOR_LOOP] = &for_loop_node_ops,
[IVY_AST_LOOP_BREAK] = &loop_break_node_ops,
[IVY_AST_LOOP_REPEAT] = &loop_repeat_node_ops,
[IVY_AST_RETURN] = &return_node_ops,
[IVY_AST_PROPERTY] = &property_node_ops,
[IVY_AST_LAMBDA] = &lambda_node_ops,
@@ -121,6 +125,8 @@ enum token_expr_type get_token_expr_type(struct ivy_token *tok)
case IVY_KW_MATCH:
case IVY_KW_FOR:
case IVY_KW_WHILE:
case IVY_KW_BREAK:
case IVY_KW_CONTINUE:
case IVY_KW_TRY:
case IVY_KW_THROW:
return TOK_EXPR_BEGIN;
@@ -357,6 +363,8 @@ const char *ivy_ast_node_type_to_string(enum ivy_ast_node_type v)
ENUM_STR(IVY_AST_IDENT);
ENUM_STR(IVY_AST_FOR_LOOP);
ENUM_STR(IVY_AST_WHILE_LOOP);
ENUM_STR(IVY_AST_LOOP_BREAK);
ENUM_STR(IVY_AST_LOOP_REPEAT);
ENUM_STR(IVY_AST_CASCADE);
ENUM_STR(IVY_AST_COND_GROUP);
ENUM_STR(IVY_AST_MATCH);