From f3cd89c72a8b9fbedaa8ffd7e197ea1fa8664c54 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Fri, 6 Dec 2024 10:01:56 +0000 Subject: [PATCH] lang: ast: implement caret (return) parsing --- lang/ast/expr/arith.c | 39 ++++++++++++++++++++++++++++++++++++- lang/ast/expr/expr.c | 1 + lang/ast/expr/expr.h | 5 +++++ lang/ast/node.c | 3 +++ lang/ast/return.c | 19 ++++++++++++++++++ lang/include/ivy/lang/ast.h | 6 ++++++ 6 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 lang/ast/return.c diff --git a/lang/ast/expr/arith.c b/lang/ast/expr/arith.c index 4c4ad71..d14e4cf 100644 --- a/lang/ast/expr/arith.c +++ b/lang/ast/expr/arith.c @@ -813,10 +813,22 @@ struct token_parse_result arith_parse_semicolon( } enum ivy_status status = begin_cascade_operation(ctx); - + return PARSE_RESULT(status, 0); } +static struct ivy_ast_node *create_return_node(struct ivy_ast_node *val) +{ + struct ivy_ast_return_node *ret + = (struct ivy_ast_return_node *)ast_node_create(IVY_AST_RETURN); + if (!ret) { + return NULL; + } + + ret->n_val = val; + return (struct ivy_ast_node *)ret; +} + struct token_parse_result expr_finalise( struct ivy_parser *ctx, struct expr_parser_state *state, enum ivy_operator_precedence min_precedence, struct ivy_ast_node **result) @@ -840,6 +852,10 @@ struct token_parse_result expr_finalise( return PARSE_RESULT(status, 0); } + if (state->s_return && expr) { + expr = create_return_node(expr); + } + *result = expr; return PARSE_RESULT(IVY_OK, PARSE_REPEAT_TOKEN); } @@ -849,6 +865,11 @@ struct token_parse_result expr_finalise( struct ivy_ast_cascade_node *cascade = expr_finalise_cascade(state); + if (state->s_return && cascade) { + cascade = (struct ivy_ast_cascade_node *)create_return_node( + (struct ivy_ast_node *)cascade); + } + *result = (struct ivy_ast_node *)cascade; return PARSE_RESULT(IVY_OK, flags); } @@ -856,6 +877,12 @@ struct token_parse_result expr_finalise( if (state->s_sub_type == EXPR_SUBTYPE_COMPLEX_MSG) { /* this is the end of a complex message */ struct ivy_ast_msg_node *msg = expr_finalise_complex_msg(state); + + if (state->s_return && msg) { + msg = (struct ivy_ast_msg_node *)create_return_node( + (struct ivy_ast_node *)msg); + } + *result = (struct ivy_ast_node *)msg; return PARSE_RESULT(IVY_OK, 0); } @@ -863,6 +890,12 @@ struct token_parse_result expr_finalise( if (state->s_sub_type == EXPR_SUBTYPE_KEYWORD_MSG) { /* this is the end of a keyword-message */ struct ivy_ast_msg_node *msg = expr_finalise_keyword_msg(state); + + if (state->s_return && msg) { + msg = (struct ivy_ast_msg_node *)create_return_node( + (struct ivy_ast_node *)msg); + } + *result = (struct ivy_ast_node *)msg; return PARSE_RESULT(IVY_OK, flags); } @@ -874,6 +907,10 @@ struct token_parse_result expr_finalise( return PARSE_RESULT(status, 0); } + if (expr && state->s_return) { + expr = create_return_node(expr); + } + *result = expr; return PARSE_RESULT(IVY_OK, flags); } diff --git a/lang/ast/expr/expr.c b/lang/ast/expr/expr.c index 112d66c..d6ccef5 100644 --- a/lang/ast/expr/expr.c +++ b/lang/ast/expr/expr.c @@ -33,6 +33,7 @@ struct ast_node_type expr_node_ops = { SYM_PARSER(RIGHT_PAREN, arith_parse_right_paren), SYM_PARSER(SEMICOLON, arith_parse_semicolon), SYM_PARSER(UNDERSCORE, arith_parse_operand), + SYM_PARSER(CARET, arith_parse_caret), SYM_PARSER(COMMA, arith_parse_comma), SYM_PARSER(DOT, arith_parse_dot), SYM_PARSER(EQUAL_RIGHT_ANGLE, arith_parse_equal_right_angle), diff --git a/lang/ast/expr/expr.h b/lang/ast/expr/expr.h index 2ac0789..88deb2c 100644 --- a/lang/ast/expr/expr.h +++ b/lang/ast/expr/expr.h @@ -47,6 +47,9 @@ struct expr_parser_state { enum expr_type s_type; enum expr_subtype s_sub_type; + /* this is a return statement (prefixed with a caret) */ + bool s_return; + /* for arithmetic expressions, this records whether the previous * component (either a token or parenthesised group of tokens) is an * operator, operand, or message */ @@ -117,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_caret( + struct ivy_parser *ctx, struct ivy_token *tok); extern struct token_parse_result arith_parse_comma( struct ivy_parser *ctx, struct ivy_token *tok); extern struct token_parse_result arith_parse_equal_right_angle( diff --git a/lang/ast/node.c b/lang/ast/node.c index dbd9c96..8af5543 100644 --- a/lang/ast/node.c +++ b/lang/ast/node.c @@ -24,6 +24,7 @@ extern struct ast_node_type cond_group_node_ops; 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 return_node_ops; extern struct ast_node_type discard_node_ops; static const struct ast_node_type *node_ops[] = { @@ -46,6 +47,7 @@ static const struct ast_node_type *node_ops[] = { [IVY_AST_COND] = &cond_node_ops, [IVY_AST_MATCH] = &match_node_ops, [IVY_AST_WHILE_LOOP] = &while_loop_node_ops, + [IVY_AST_RETURN] = &return_node_ops, [IVY_AST_DISCARD] = &discard_node_ops, }; static const size_t nr_node_ops = sizeof node_ops / sizeof node_ops[0]; @@ -243,6 +245,7 @@ const char *ivy_ast_node_type_to_string(enum ivy_ast_node_type v) ENUM_STR(IVY_AST_COND); ENUM_STR(IVY_AST_TUPLE); ENUM_STR(IVY_AST_BLOCK); + ENUM_STR(IVY_AST_RETURN); ENUM_STR(IVY_AST_TYPE_COUNT); default: return ""; diff --git a/lang/ast/return.c b/lang/ast/return.c new file mode 100644 index 0000000..c20f7d1 --- /dev/null +++ b/lang/ast/return.c @@ -0,0 +1,19 @@ +#include "ctx.h" +#include "iterate.h" +#include "node.h" + +static void collect_children( + struct ivy_ast_node *node, struct ivy_ast_node_iterator *iterator) +{ + struct ivy_ast_return_node *ret = (struct ivy_ast_return_node *)node; + + if (ret->n_val) { + ast_node_iterator_enqueue_node(iterator, node, ret->n_val); + } +} + +struct ast_node_type return_node_ops = { + .n_collect_children = collect_children, + .n_state_size = sizeof(struct parser_state), + .n_node_size = sizeof(struct ivy_ast_return_node), +}; diff --git a/lang/include/ivy/lang/ast.h b/lang/include/ivy/lang/ast.h index d69850d..750808a 100644 --- a/lang/include/ivy/lang/ast.h +++ b/lang/include/ivy/lang/ast.h @@ -14,6 +14,7 @@ enum ivy_ast_node_type { IVY_AST_NONE = 0x00, IVY_AST_UNIT, IVY_AST_OP, + IVY_AST_RETURN, IVY_AST_MSG, IVY_AST_CLASS, IVY_AST_MSGH, @@ -71,6 +72,11 @@ struct ivy_ast_op_node { struct ivy_ast_node *n_right; }; +struct ivy_ast_return_node { + struct ivy_ast_node n_base; + struct ivy_ast_node *n_val; +}; + struct ivy_ast_selector_node { struct ivy_ast_node n_base; enum ivy_selector_recipient n_recipient;