lang: ast: re-factor condition group parser

this parser now only handles if-else statements, and uses the state init callback argument to receive any pre-existing inline expressions
This commit is contained in:
2024-12-04 21:02:55 +00:00
parent a34b9c3710
commit 0bb4a4284c
3 changed files with 27 additions and 52 deletions

View File

@@ -1,11 +1,22 @@
#include "cond.h"
#include "block.h"
#include "expr/expr.h"
struct cond_group_parser_state {
struct parser_state s_base;
bool s_inline;
unsigned int s_prev_token;
struct ivy_ast_cond_node *s_cur_branch;
b_queue s_branches;
struct ivy_ast_node *s_prev_node;
};
static void init_state(struct ivy_parser *ctx, struct parser_state *sp, uintptr_t arg)
{
struct cond_group_parser_state *state
= (struct cond_group_parser_state *)sp;
state->s_prev_node = (struct ivy_ast_node *)arg;
}
struct token_parse_result parse_if(
@@ -26,11 +37,11 @@ struct token_parse_result parse_if(
if (state->s_prev_node) {
/* this is an inline if-else */
state->s_type = COND_GROUP_INLINE_IF_ELSE;
state->s_inline = true;
state->s_cur_branch->n_body = state->s_prev_node;
state->s_prev_node = NULL;
} else {
state->s_type = COND_GROUP_IF_ELSE;
state->s_inline = false;
}
struct expr_parser_state *expr
@@ -63,7 +74,6 @@ static enum ivy_status flush_current_branch(struct cond_group_parser_state *stat
struct token_parse_result parse_then(struct ivy_parser *ctx, struct ivy_token *tok)
{
enum ivy_status status;
struct cond_group_parser_state *state
= parser_get_state(ctx, struct cond_group_parser_state);
@@ -71,7 +81,7 @@ struct token_parse_result parse_then(struct ivy_parser *ctx, struct ivy_token *t
return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0);
}
if (state->s_type != COND_GROUP_IF_ELSE) {
if (state->s_inline) {
return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0);
}
@@ -89,7 +99,7 @@ struct token_parse_result parse_then(struct ivy_parser *ctx, struct ivy_token *t
/* next component will be a block. */
struct block_parser_state *block
= (struct expr_parser_state *)parser_push_state(
= (struct block_parser_state *)parser_push_state(
ctx, IVY_AST_BLOCK, 0);
/* set the sub-expression depth to be non-zero so the expression parser doesn't consume the expression separator. */
block->s_terminator = IVY_KW_END;
@@ -108,8 +118,7 @@ struct token_parse_result parse_else(struct ivy_parser *ctx, struct ivy_token *t
return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0);
}
switch (state->s_type) {
case COND_GROUP_IF_ELSE:
if (!state->s_inline) {
/* previous component was either an expression or a block, and is the if branch body. */
if (!state->s_prev_node) {
return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0);
@@ -128,8 +137,7 @@ struct token_parse_result parse_else(struct ivy_parser *ctx, struct ivy_token *t
}
/* next component should either be an if keyword or a block. */
break;
case COND_GROUP_INLINE_IF_ELSE:
} else {
/* previous component was the if-condition. */
if (!state->s_prev_node) {
return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0);
@@ -153,9 +161,6 @@ struct token_parse_result parse_else(struct ivy_parser *ctx, struct ivy_token *t
ctx, IVY_AST_EXPR, 0);
/* set the sub-expression depth to be non-zero so the expression parser doesn't consume the expression separator. */
expr->s_subexpr_depth = 1;
break;
default:
return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0);
}
state->s_prev_token = IVY_KW_ELSE;
@@ -182,8 +187,7 @@ static enum ivy_status finalise_cond_group(struct cond_group_parser_state* state
struct ivy_ast_cond_group_node *group
= (struct ivy_ast_cond_group_node *)state->s_base.s_node;
switch (state->s_type) {
case COND_GROUP_INLINE_IF_ELSE:
if (state->s_inline) {
/* we have just reached the end of either the 'if' or the 'else' expression. */
if (!state->s_cur_branch) {
/* not currently parsing a conditional branch. */
@@ -209,7 +213,7 @@ static enum ivy_status finalise_cond_group(struct cond_group_parser_state* state
group->n_branches = state->s_branches;
state->s_branches = B_QUEUE_INIT;
return IVY_OK;
case COND_GROUP_IF_ELSE:
} else {
/* we have just reached the 'end' keyword. */
if (!state->s_cur_branch) {
/* not currently parsing a conditional branch. */
@@ -228,8 +232,6 @@ static enum ivy_status finalise_cond_group(struct cond_group_parser_state* state
group->n_branches = state->s_branches;
state->s_branches = B_QUEUE_INIT;
return IVY_OK;
default:
return IVY_ERR_NOT_SUPPORTED;
}
}
@@ -239,7 +241,7 @@ struct token_parse_result parse_punct_terminator(
struct cond_group_parser_state *state
= parser_get_state(ctx, struct cond_group_parser_state);
if (state->s_type != COND_GROUP_INLINE_IF_ELSE) {
if (!state->s_inline) {
/* only inline conditional can be ended with punctuation. */
return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0);
}
@@ -258,8 +260,8 @@ struct token_parse_result parse_end(struct ivy_parser *ctx, struct ivy_token *to
struct cond_group_parser_state *state
= parser_get_state(ctx, struct cond_group_parser_state);
if (state->s_type == COND_GROUP_INLINE_IF_ELSE) {
/* inline if-else must be terminateed with punctuation. */
if (state->s_inline) {
/* inline if-else must be terminated with punctuation. */
return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0);
}