diff --git a/lang/ast/cond.c b/lang/ast/cond.c index f8711f8..89439f1 100644 --- a/lang/ast/cond.c +++ b/lang/ast/cond.c @@ -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); } diff --git a/lang/ast/cond.h b/lang/ast/cond.h deleted file mode 100644 index bb49068..0000000 --- a/lang/ast/cond.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _AST_COND_H_ -#define _AST_COND_H_ - -#include "ctx.h" -#include "node.h" - -enum cond_group_type { - COND_GROUP_NONE = 0, - COND_GROUP_IF_ELSE, - COND_GROUP_INLINE_IF_ELSE, - COND_GROUP_MATCH, -}; - -struct cond_group_parser_state { - struct parser_state s_base; - enum cond_group_type s_type; - unsigned int s_prev_token; - - struct ivy_ast_cond_node *s_cur_branch; - b_queue s_branches; - - struct ivy_ast_node *s_prev_node; -}; - -#endif \ No newline at end of file diff --git a/lang/ast/expr/stmt.c b/lang/ast/expr/stmt.c index 7f305d2..e696003 100644 --- a/lang/ast/expr/stmt.c +++ b/lang/ast/expr/stmt.c @@ -1,6 +1,5 @@ #include "../node.h" #include "expr.h" -#include "../cond.h" #include #include @@ -35,13 +34,12 @@ struct token_parse_result stmt_parse_if( parser_pop_state(ctx, 0); } - struct cond_group_parser_state *cond - = (struct cond_group_parser_state *)parser_push_state( - ctx, IVY_AST_COND_GROUP, 0); - /* if expr is NULL, this is an if-then-else-end statement, * otherwise, this is an expr-if-else-expr. */ - cond->s_prev_node = expr; + struct cond_group_parser_state *cond + = (struct cond_group_parser_state *)parser_push_state( + ctx, IVY_AST_COND_GROUP, (uintptr_t)expr); + return PARSE_RESULT(IVY_OK, PARSE_REPEAT_TOKEN); }