diff --git a/lang/ast/match.c b/lang/ast/match.c index bbb47d7..d98de0a 100644 --- a/lang/ast/match.c +++ b/lang/ast/match.c @@ -132,12 +132,15 @@ static struct token_parse_result parse_arrow( state->s_prev_token = IVY_SYM_EQUAL_RIGHT_ANGLE; /* the next component is the branch body */ +#if 0 struct expr_parser_state *expr = (struct expr_parser_state *)parser_push_state( ctx, IVY_AST_EXPR, 0); expr_add_terminator(expr, IVY_KW_END); + expr_add_terminator(expr, IVY_SYM_COMMA); expr->s_subexpr_depth = 1; +#endif return PARSE_RESULT(IVY_OK, 0); } @@ -199,6 +202,46 @@ static struct token_parse_result parse_end( return PARSE_RESULT(IVY_OK, 0); } +static struct token_parse_result parse_block( + struct ivy_parser *ctx, struct ivy_token *tok) +{ + struct match_parser_state *state + = parser_get_state(ctx, struct match_parser_state); + + if (state->s_prev_token != IVY_SYM_EQUAL_RIGHT_ANGLE) { + return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0); + } + + struct block_parser_state *block + = (struct block_parser_state *)parser_push_state( + ctx, IVY_AST_BLOCK, 0); + + return PARSE_RESULT(IVY_OK, 0); +} + +static struct token_parse_result parse_expr( + struct ivy_parser *ctx, struct ivy_token *tok) +{ + struct match_parser_state *state + = parser_get_state(ctx, struct match_parser_state); + + if (state->s_prev_token != IVY_SYM_EQUAL_RIGHT_ANGLE) { + return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0); + } + + struct expr_parser_state *expr + = (struct expr_parser_state *)parser_push_state( + ctx, IVY_AST_EXPR, 0); + + if (tok->t_type != IVY_TOK_KEYWORD) { + expr_add_terminator(expr, IVY_KW_END); + } + + expr_add_terminator(expr, IVY_SYM_COMMA); + expr->s_subexpr_depth = 1; + return PARSE_RESULT(IVY_OK, PARSE_REPEAT_TOKEN); +} + static enum ivy_status add_child( struct parser_state *parent, struct ivy_ast_node *child) { @@ -233,10 +276,12 @@ struct ast_node_type match_node_ops = { .n_collect_children = match_collect_children, .n_state_size = sizeof(struct match_parser_state), .n_node_size = sizeof(struct ivy_ast_match_node), + .n_expr_parser = parse_expr, .n_keyword_parsers = { KW_PARSER(MATCH, parse_match), KW_PARSER(IN, parse_in), KW_PARSER(END, parse_end), + KW_PARSER(DO, parse_block), }, .n_symbol_parsers = { SYM_PARSER(EQUAL_RIGHT_ANGLE, parse_arrow), diff --git a/lang/codegen/codegen.h b/lang/codegen/codegen.h index 69da1c7..0450e16 100644 --- a/lang/codegen/codegen.h +++ b/lang/codegen/codegen.h @@ -50,6 +50,7 @@ enum code_generator_type { CODE_GENERATOR_FOR_LOOP, CODE_GENERATOR_WHILE_LOOP, CODE_GENERATOR_CASCADE, + CODE_GENERATOR_MATCH, }; enum code_generator_scope_type { diff --git a/lang/codegen/expr.c b/lang/codegen/expr.c index ab0add1..d441998 100644 --- a/lang/codegen/expr.c +++ b/lang/codegen/expr.c @@ -277,6 +277,14 @@ static struct code_generator_result gen_for_loop( return CODEGEN_RESULT_OK(CODEGEN_R_REPEAT_NODE); } +static struct code_generator_result gen_match( + struct ivy_codegen *gen, struct code_generator_state *state, + struct ivy_ast_node *node, size_t depth) +{ + codegen_push_generator(gen, CODE_GENERATOR_MATCH, 0, NULL); + return CODEGEN_RESULT_OK(CODEGEN_R_REPEAT_NODE); +} + #if 0 static struct code_generator_result gen_var_ref( struct ivy_codegen *gen, struct code_generator_state *state, @@ -725,5 +733,6 @@ struct code_generator expr_generator = { NODE_CODEGEN(IDENT, gen_var_reference), NODE_CODEGEN(COND_GROUP, gen_cond_group), NODE_CODEGEN(FOR_LOOP, gen_for_loop), + NODE_CODEGEN(MATCH, gen_match), }, }; diff --git a/lang/codegen/match.c b/lang/codegen/match.c new file mode 100644 index 0000000..e17f92b --- /dev/null +++ b/lang/codegen/match.c @@ -0,0 +1,86 @@ +#include "codegen.h" + +#include +#include +#include + +struct match_codegen_state { + struct code_generator_state s_base; +}; + +static struct code_generator_result gen_expr( + struct ivy_codegen *gen, struct code_generator_state *state, + struct ivy_ast_node *node, size_t depth) +{ + struct match_codegen_state *match = (struct match_codegen_state *)state; + + codegen_push_generator(gen, CODE_GENERATOR_EXPR, 0, NULL); + return CODEGEN_RESULT_OK(CODEGEN_R_REPEAT_NODE); +} + +static struct code_generator_result gen_match( + struct ivy_codegen *gen, struct code_generator_state *state, + struct ivy_ast_node *node, size_t depth) +{ + return CODEGEN_RESULT_OK(0); +} + +static struct code_generator_result gen_block( + struct ivy_codegen *gen, struct code_generator_state *state, + struct ivy_ast_node *node, size_t depth) +{ + struct match_codegen_state *match = (struct match_codegen_state *)state; + struct mie_func *func = mie_builder_get_current_func(gen->c_builder); + + codegen_push_generator(gen, CODE_GENERATOR_BLOCK, 0, NULL); + return CODEGEN_RESULT_OK(0); +} + +static struct code_generator_result gen_discard( + struct ivy_codegen *gen, struct code_generator_state *state, + struct ivy_ast_node *node, size_t depth) +{ + struct match_codegen_state *match = (struct match_codegen_state *)state; + return CODEGEN_RESULT_OK(0); +} + +static enum ivy_status state_init( + struct ivy_codegen *gen, struct code_generator_state *state, + uintptr_t argv, void *argp) +{ + struct match_codegen_state *match = (struct match_codegen_state *)state; + + return IVY_OK; +} + +static enum ivy_status state_fini( + struct ivy_codegen *gen, struct code_generator_state *state, + struct code_generator_value *result) +{ + struct match_codegen_state *match = (struct match_codegen_state *)state; + return IVY_OK; +} + +static struct code_generator_result value_received( + struct ivy_codegen *gen, struct code_generator_state *state, + struct code_generator_value *value) +{ + struct match_codegen_state *match = (struct match_codegen_state *)state; + struct mie_func *func = mie_builder_get_current_func(gen->c_builder); + + return CODEGEN_RESULT_OK(0); +} + +struct code_generator match_generator = { + .g_type = CODE_GENERATOR_FOR_LOOP, + .g_state_size = sizeof(struct match_codegen_state), + .g_state_init = state_init, + .g_state_fini = state_fini, + .g_value_received = value_received, + .g_expr_generator = gen_expr, + .g_node_generators = { + NODE_CODEGEN(MATCH, gen_match), + NODE_CODEGEN(BLOCK, gen_block), + NODE_CODEGEN(DISCARD, gen_discard), + }, +};