#include "../node.h" #include "expr.h" #include #include #include #include struct token_parse_result stmt_parse_for( struct ivy_parser *ctx, struct ivy_token *tok) { struct expr_parser_state *state = parser_get_state(ctx, struct expr_parser_state); if (state->s_terminator == IVY_KW_FOR) { /* treat this as a statement terminator. */ struct token_parse_result result = expr_finalise_and_return(ctx, state); result.r_flags |= PARSE_REPEAT_TOKEN; return result; } if (state->s_sub_type == EXPR_SUBTYPE_KEYWORD_ARG) { /* keyword messages have a higher precedence than inline * conditionals, so treat this as a statement terminator. */ struct token_parse_result result = expr_finalise_and_return(ctx, state); result.r_flags |= PARSE_REPEAT_TOKEN; return result; } struct ivy_ast_node *expr = NULL; struct token_parse_result result = expr_finalise(ctx, state, IVY_PRECEDENCE_IF_ELSE, &expr); if (result.r_status != IVY_OK) { return result; } state->s_prev_token = IVY_KW_FOR; if (b_queue_empty(&state->s_operator_stack) && b_queue_empty(&state->s_output_queue)) { parser_pop_state(ctx, 0); } /* if expr is NULL, this is an if-then-else-end statement, * otherwise, this is an expr-if-else-expr. */ parser_push_state(ctx, IVY_AST_FOR_LOOP, (uintptr_t)expr); return PARSE_RESULT(IVY_OK, PARSE_REPEAT_TOKEN); } struct token_parse_result stmt_parse_while( struct ivy_parser *ctx, struct ivy_token *tok) { struct expr_parser_state *state = parser_get_state(ctx, struct expr_parser_state); if (state->s_sub_type == EXPR_SUBTYPE_KEYWORD_ARG) { /* keyword messages have a higher precedence than inline * conditionals, so treat this as a statement terminator. */ struct token_parse_result result = expr_finalise_and_return(ctx, state); result.r_flags |= PARSE_REPEAT_TOKEN; return result; } struct ivy_ast_node *expr = NULL; struct token_parse_result result = expr_finalise(ctx, state, IVY_PRECEDENCE_IF_ELSE, &expr); if (result.r_status != IVY_OK) { return result; } state->s_prev_token = IVY_KW_WHILE; if (b_queue_empty(&state->s_operator_stack) && b_queue_empty(&state->s_output_queue)) { parser_pop_state(ctx, 0); } /* if expr is NULL, this is an if-then-else-end statement, * otherwise, this is an expr-if-else-expr. */ parser_push_state(ctx, IVY_AST_WHILE_LOOP, (uintptr_t)expr); return PARSE_RESULT(IVY_OK, PARSE_REPEAT_TOKEN); } struct token_parse_result stmt_parse_match( 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_OPERAND || state->s_prev_component == EXPR_CMP_MSG) { /* match statements are operands. */ return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0); } struct ivy_ast_node *expr = NULL; struct token_parse_result result = expr_finalise(ctx, state, IVY_PRECEDENCE_IF_ELSE, &expr); if (result.r_status != IVY_OK) { return result; } state->s_prev_token = IVY_KW_MATCH; if (b_queue_empty(&state->s_operator_stack) && b_queue_empty(&state->s_output_queue)) { parser_pop_state(ctx, 0); } /* if expr is NULL, this is an if-then-else-end statement, * otherwise, this is an expr-if-else-expr. */ struct cond_group_parser_state *cond = (struct cond_group_parser_state *)parser_push_state( ctx, IVY_AST_MATCH, 0); return PARSE_RESULT(IVY_OK, PARSE_REPEAT_TOKEN); } struct token_parse_result stmt_parse_if( struct ivy_parser *ctx, struct ivy_token *tok) { struct expr_parser_state *state = parser_get_state(ctx, struct expr_parser_state); if (state->s_terminator == IVY_KW_IF) { /* treat this as a statement terminator. */ struct token_parse_result result = expr_finalise_and_return(ctx, state); result.r_flags |= PARSE_REPEAT_TOKEN; return result; } if (state->s_sub_type == EXPR_SUBTYPE_KEYWORD_ARG) { /* keyword messages have a higher precedence than inline * conditionals, so treat this as a statement terminator. */ struct token_parse_result result = expr_finalise_and_return(ctx, state); result.r_flags |= PARSE_REPEAT_TOKEN; return result; } struct ivy_ast_node *expr = NULL; struct token_parse_result result = expr_finalise(ctx, state, IVY_PRECEDENCE_IF_ELSE, &expr); if (result.r_status != IVY_OK) { return result; } state->s_prev_token = IVY_KW_IF; if (b_queue_empty(&state->s_operator_stack) && b_queue_empty(&state->s_output_queue)) { parser_pop_state(ctx, 0); } /* if expr is NULL, this is an if-then-else-end statement, * otherwise, this is an expr-if-else-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); } struct token_parse_result stmt_parse_then( struct ivy_parser *ctx, struct ivy_token *tok) { struct expr_parser_state *state = parser_get_state(ctx, struct expr_parser_state); /* treat this as a statement terminator. */ struct token_parse_result result = expr_finalise_and_return(ctx, state); result.r_flags |= PARSE_REPEAT_TOKEN; return result; } struct token_parse_result stmt_parse_else( struct ivy_parser *ctx, struct ivy_token *tok) { struct expr_parser_state *state = parser_get_state(ctx, struct expr_parser_state); /* treat this as a statement terminator. */ struct token_parse_result result = expr_finalise_and_return(ctx, state); result.r_flags |= PARSE_REPEAT_TOKEN; return result; } struct token_parse_result stmt_parse_end( struct ivy_parser *ctx, struct ivy_token *tok) { struct expr_parser_state *state = parser_get_state(ctx, struct expr_parser_state); /* treat this as a statement terminator. */ struct token_parse_result result = expr_finalise_and_return(ctx, state); result.r_flags |= PARSE_REPEAT_TOKEN; return result; }