lang: ast: implement parsing of f-strings

This commit is contained in:
2024-12-06 13:46:58 +00:00
parent 2bd3e96427
commit 94c10dfbb2
5 changed files with 151 additions and 18 deletions

View File

@@ -416,6 +416,29 @@ enum ivy_status expr_finalise_arith(
return IVY_OK; return IVY_OK;
} }
struct token_parse_result arith_parse_fstring(
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_STMT) {
return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0);
}
if (state->s_prev_component == EXPR_CMP_OPERAND) {
return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0);
}
state->s_type = EXPR_TYPE_ARITH;
state->s_prev_component = EXPR_CMP_OPERAND;
state->s_prev_token = tok->t_type;
parser_push_state(ctx, IVY_AST_FSTRING, 0);
return PARSE_RESULT(IVY_OK, 0);
}
struct token_parse_result arith_parse_operand( struct token_parse_result arith_parse_operand(
struct ivy_parser *ctx, struct ivy_token *tok) struct ivy_parser *ctx, struct ivy_token *tok)
{ {
@@ -601,6 +624,47 @@ struct token_parse_result arith_parse_left_paren(
return PARSE_RESULT(IVY_OK, 0); return PARSE_RESULT(IVY_OK, 0);
} }
struct token_parse_result arith_parse_right_paren(
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 && state->s_sub_type == EXPR_SUBTYPE_NONE) {
return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0);
}
state->s_prev_token = IVY_SYM_RIGHT_PAREN;
return expr_finalise_and_return(ctx, state);
}
struct token_parse_result arith_parse_left_brace(
struct ivy_parser *ctx, struct ivy_token *tok)
{
return PARSE_RESULT(IVY_ERR_NOT_SUPPORTED, 0);
}
struct token_parse_result arith_parse_right_brace(
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_SYM_RIGHT_BRACE) {
state->s_prev_token = IVY_SYM_RIGHT_BRACE;
struct token_parse_result result = expr_finalise_and_return(ctx, state);
result.r_flags = PARSE_REPEAT_TOKEN;
return result;
}
return PARSE_RESULT(IVY_ERR_NOT_SUPPORTED, 0);
}
static struct ivy_ast_selector_node *keyword_selector_from_label_list(b_queue *labels) static struct ivy_ast_selector_node *keyword_selector_from_label_list(b_queue *labels)
{ {
struct ivy_ast_selector_node *sel struct ivy_ast_selector_node *sel
@@ -693,24 +757,6 @@ static struct ivy_ast_msg_node *expr_finalise_complex_msg(
return msg; return msg;
} }
struct token_parse_result arith_parse_right_paren(
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 && state->s_sub_type == EXPR_SUBTYPE_NONE) {
return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0);
}
state->s_prev_token = IVY_SYM_RIGHT_PAREN;
return expr_finalise_and_return(ctx, state);
}
static enum ivy_status begin_cascade_operation(struct ivy_parser *ctx) static enum ivy_status begin_cascade_operation(struct ivy_parser *ctx)
{ {
struct expr_parser_state *state struct expr_parser_state *state

View File

@@ -26,12 +26,15 @@ struct ast_node_type expr_node_ops = {
TOK_PARSER(DOUBLE, arith_parse_operand), TOK_PARSER(DOUBLE, arith_parse_operand),
TOK_PARSER(ATOM, arith_parse_operand), TOK_PARSER(ATOM, arith_parse_operand),
TOK_PARSER(STRING, arith_parse_operand), TOK_PARSER(STRING, arith_parse_operand),
TOK_PARSER(STR_START, arith_parse_fstring),
TOK_PARSER(SYMBOL, arith_parse_operator), TOK_PARSER(SYMBOL, arith_parse_operator),
TOK_PARSER(LABEL, arith_parse_label), TOK_PARSER(LABEL, arith_parse_label),
}, },
.n_symbol_parsers = { .n_symbol_parsers = {
SYM_PARSER(LEFT_PAREN, arith_parse_left_paren), SYM_PARSER(LEFT_PAREN, arith_parse_left_paren),
SYM_PARSER(RIGHT_PAREN, arith_parse_right_paren), SYM_PARSER(RIGHT_PAREN, arith_parse_right_paren),
SYM_PARSER(LEFT_BRACE, arith_parse_left_brace),
SYM_PARSER(RIGHT_BRACE, arith_parse_right_brace),
SYM_PARSER(SEMICOLON, arith_parse_semicolon), SYM_PARSER(SEMICOLON, arith_parse_semicolon),
SYM_PARSER(UNDERSCORE, arith_parse_operand), SYM_PARSER(UNDERSCORE, arith_parse_operand),
SYM_PARSER(CARET, arith_parse_caret), SYM_PARSER(CARET, arith_parse_caret),

View File

@@ -106,6 +106,8 @@ extern enum ivy_status arith_add_child(
extern struct token_parse_result arith_parse_ident( extern struct token_parse_result arith_parse_ident(
struct ivy_parser *ctx, struct ivy_token *tok); struct ivy_parser *ctx, struct ivy_token *tok);
extern struct token_parse_result arith_parse_fstring(
struct ivy_parser *ctx, struct ivy_token *tok);
extern struct token_parse_result arith_parse_operand( extern struct token_parse_result arith_parse_operand(
struct ivy_parser *ctx, struct ivy_token *tok); struct ivy_parser *ctx, struct ivy_token *tok);
extern struct token_parse_result arith_parse_operator( extern struct token_parse_result arith_parse_operator(
@@ -116,6 +118,10 @@ extern struct token_parse_result arith_parse_left_paren(
struct ivy_parser *ctx, struct ivy_token *tok); struct ivy_parser *ctx, struct ivy_token *tok);
extern struct token_parse_result arith_parse_right_paren( extern struct token_parse_result arith_parse_right_paren(
struct ivy_parser *ctx, struct ivy_token *tok); struct ivy_parser *ctx, struct ivy_token *tok);
extern struct token_parse_result arith_parse_left_brace(
struct ivy_parser *ctx, struct ivy_token *tok);
extern struct token_parse_result arith_parse_right_brace(
struct ivy_parser *ctx, struct ivy_token *tok);
extern struct token_parse_result arith_parse_semicolon( extern struct token_parse_result arith_parse_semicolon(
struct ivy_parser *ctx, struct ivy_token *tok); struct ivy_parser *ctx, struct ivy_token *tok);
extern struct token_parse_result arith_parse_dot( extern struct token_parse_result arith_parse_dot(

View File

@@ -20,6 +20,7 @@ extern struct ast_node_type int_node_ops;
extern struct ast_node_type double_node_ops; extern struct ast_node_type double_node_ops;
extern struct ast_node_type atom_node_ops; extern struct ast_node_type atom_node_ops;
extern struct ast_node_type string_node_ops; extern struct ast_node_type string_node_ops;
extern struct ast_node_type fstring_node_ops;
extern struct ast_node_type cascade_node_ops; extern struct ast_node_type cascade_node_ops;
extern struct ast_node_type cond_group_node_ops; extern struct ast_node_type cond_group_node_ops;
extern struct ast_node_type cond_node_ops; extern struct ast_node_type cond_node_ops;
@@ -45,6 +46,7 @@ static const struct ast_node_type *node_ops[] = {
[IVY_AST_DOUBLE] = &double_node_ops, [IVY_AST_DOUBLE] = &double_node_ops,
[IVY_AST_ATOM] = &atom_node_ops, [IVY_AST_ATOM] = &atom_node_ops,
[IVY_AST_STRING] = &string_node_ops, [IVY_AST_STRING] = &string_node_ops,
[IVY_AST_FSTRING] = &fstring_node_ops,
[IVY_AST_CASCADE] = &cascade_node_ops, [IVY_AST_CASCADE] = &cascade_node_ops,
[IVY_AST_COND_GROUP] = &cond_group_node_ops, [IVY_AST_COND_GROUP] = &cond_group_node_ops,
[IVY_AST_COND] = &cond_node_ops, [IVY_AST_COND] = &cond_node_ops,

View File

@@ -1,7 +1,83 @@
#include "ctx.h" #include "ctx.h"
#include "expr/expr.h"
#include "node.h" #include "node.h"
struct token_parse_result parse_string(
struct ivy_parser *ctx, struct ivy_token *tok)
{
struct parser_state *state = parser_get_state_generic(ctx);
struct ivy_ast_fstring_node *parent = (struct ivy_ast_fstring_node *)state->s_node;
struct ivy_ast_string_node *child = (struct ivy_ast_string_node *)ast_node_create(IVY_AST_STRING);
if (!child) {
return PARSE_RESULT(IVY_ERR_NO_MEMORY, 0);
}
child->n_value = tok;
b_queue_push_back(&parent->n_value, &child->n_base.n_entry);
return PARSE_RESULT(IVY_OK, 0);
}
struct token_parse_result parse_left_brace(
struct ivy_parser *ctx, struct ivy_token *tok)
{
struct expr_parser_state *expr = (struct expr_parser_state *)parser_push_state(ctx, IVY_AST_EXPR, 0);
expr->s_terminator = IVY_SYM_RIGHT_BRACE;
return PARSE_RESULT(IVY_OK, 0);
}
struct token_parse_result parse_right_brace(
struct ivy_parser *ctx, struct ivy_token *tok)
{
return PARSE_RESULT(IVY_OK, 0);
}
struct token_parse_result parse_str_end(
struct ivy_parser *ctx, struct ivy_token *tok)
{
parser_pop_state(ctx, STATE_ADD_NODE_TO_PARENT);
return PARSE_RESULT(IVY_OK, 0);
}
static enum ivy_status add_child(
struct parser_state *parent, struct ivy_ast_node *child)
{
struct ivy_ast_fstring_node *str
= (struct ivy_ast_fstring_node *)parent->s_node;
b_queue_push_back(&str->n_value, &child->n_entry);
return IVY_OK;
}
static void collect_children(
struct ivy_ast_node *node, struct ivy_ast_node_iterator *iterator)
{
struct ivy_ast_fstring_node *str = (struct ivy_ast_fstring_node *)node;
b_queue_iterator it = {0};
b_queue_foreach (&it, &str->n_value) {
struct ivy_ast_node *child
= b_unbox(struct ivy_ast_node, it.entry, n_entry);
ast_node_iterator_enqueue_node(iterator, node, child);
}
}
struct ast_node_type string_node_ops = { struct ast_node_type string_node_ops = {
.n_state_size = sizeof(struct parser_state), .n_state_size = sizeof(struct parser_state),
.n_node_size = sizeof(struct ivy_ast_string_node), .n_node_size = sizeof(struct ivy_ast_string_node),
}; };
struct ast_node_type fstring_node_ops = {
.n_add_child = add_child,
.n_collect_children = collect_children,
.n_state_size = sizeof(struct parser_state),
.n_node_size = sizeof(struct ivy_ast_fstring_node),
.n_token_parsers = {
TOK_PARSER(STRING, parse_string),
TOK_PARSER(STR_END, parse_str_end),
},
.n_symbol_parsers = {
SYM_PARSER(LEFT_BRACE, parse_left_brace),
SYM_PARSER(RIGHT_BRACE, parse_right_brace),
},
};