diff --git a/lang/ast/expr/arith.c b/lang/ast/expr/arith.c index 5a4c0d2..91fe4a8 100644 --- a/lang/ast/expr/arith.c +++ b/lang/ast/expr/arith.c @@ -985,6 +985,27 @@ struct token_parse_result arith_parse_dot( return expr_finalise_and_return(ctx, state); } +struct token_parse_result arith_parse_bang( + struct ivy_parser *ctx, struct ivy_token *tok) +{ + struct expr_parser_state *state + = parser_get_state(ctx, struct expr_parser_state); + + if (state->s_type != EXPR_TYPE_ARITH) { + return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0); + } + + if (state->s_paren_depth > 0) { + /* end-of-expression with mismatched parentheses */ + return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0); + } + + state->s_prev_token = IVY_SYM_BANG; + struct token_parse_result result = expr_finalise_and_return(ctx, state); + result.r_flags = PARSE_REPEAT_TOKEN; + return result; +} + struct token_parse_result arith_parse_caret( struct ivy_parser *ctx, struct ivy_token *tok) { diff --git a/lang/ast/expr/expr.c b/lang/ast/expr/expr.c index 68a4af6..bce7c6d 100644 --- a/lang/ast/expr/expr.c +++ b/lang/ast/expr/expr.c @@ -36,6 +36,7 @@ struct ast_node_type expr_node_ops = { SYM_PARSER(CARET, arith_parse_caret), SYM_PARSER(COMMA, arith_parse_comma), SYM_PARSER(DOT, arith_parse_dot), + SYM_PARSER(BANG, arith_parse_bang), SYM_PARSER(EQUAL_RIGHT_ANGLE, arith_parse_equal_right_angle), }, .n_keyword_parsers = { diff --git a/lang/ast/expr/expr.h b/lang/ast/expr/expr.h index d62c60a..6359ba7 100644 --- a/lang/ast/expr/expr.h +++ b/lang/ast/expr/expr.h @@ -120,6 +120,8 @@ extern struct token_parse_result arith_parse_semicolon( struct ivy_parser *ctx, struct ivy_token *tok); extern struct token_parse_result arith_parse_dot( struct ivy_parser *ctx, struct ivy_token *tok); +extern struct token_parse_result arith_parse_bang( + struct ivy_parser *ctx, struct ivy_token *tok); extern struct token_parse_result arith_parse_caret( struct ivy_parser *ctx, struct ivy_token *tok); extern struct token_parse_result arith_parse_comma(