lang: ast: implement caret (return) parsing

This commit is contained in:
2024-12-06 10:01:56 +00:00
parent d1855afc05
commit f3cd89c72a
6 changed files with 72 additions and 1 deletions

View File

@@ -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);
}

View File

@@ -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),

View File

@@ -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(

View File

@@ -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 "";

19
lang/ast/return.c Normal file
View File

@@ -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),
};

View File

@@ -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;