lang: ast: implement parsing of break/continue loop-control statements
This commit is contained in:
@@ -110,6 +110,23 @@ enum ivy_status arith_push_operand(
|
|||||||
b_queue_push_back(&state->s_output_queue, &v->n_entry);
|
b_queue_push_back(&state->s_output_queue, &v->n_entry);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case IVY_TOK_KEYWORD: {
|
||||||
|
struct ivy_ast_node *v = NULL;
|
||||||
|
switch (tok->t_keyword) {
|
||||||
|
case IVY_KW_BREAK:
|
||||||
|
v = ast_node_create(IVY_AST_LOOP_BREAK);
|
||||||
|
break;
|
||||||
|
case IVY_KW_CONTINUE:
|
||||||
|
v = ast_node_create(IVY_AST_LOOP_REPEAT);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return IVY_ERR_BAD_SYNTAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
ivy_ast_node_set_bounds_from_token((struct ivy_ast_node *)v, tok);
|
||||||
|
b_queue_push_back(&state->s_output_queue, &v->n_entry);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return IVY_ERR_BAD_SYNTAX;
|
return IVY_ERR_BAD_SYNTAX;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,8 +78,10 @@ struct ast_node_type expr_node_ops = {
|
|||||||
.n_keyword_parsers = {
|
.n_keyword_parsers = {
|
||||||
/* statement keywords */
|
/* statement keywords */
|
||||||
KW_PARSER(FOR, stmt_parse_for),
|
KW_PARSER(FOR, stmt_parse_for),
|
||||||
KW_PARSER(TRY, stmt_parse_try),
|
|
||||||
KW_PARSER(WHILE, stmt_parse_while),
|
KW_PARSER(WHILE, stmt_parse_while),
|
||||||
|
KW_PARSER(BREAK, stmt_parse_break),
|
||||||
|
KW_PARSER(CONTINUE, stmt_parse_continue),
|
||||||
|
KW_PARSER(TRY, stmt_parse_try),
|
||||||
KW_PARSER(MATCH, stmt_parse_match),
|
KW_PARSER(MATCH, stmt_parse_match),
|
||||||
KW_PARSER(IF, stmt_parse_if),
|
KW_PARSER(IF, stmt_parse_if),
|
||||||
KW_PARSER(THEN, stmt_parse_end),
|
KW_PARSER(THEN, stmt_parse_end),
|
||||||
|
|||||||
@@ -174,5 +174,9 @@ struct token_parse_result stmt_parse_else(
|
|||||||
struct ivy_parser *ctx, struct ivy_token *tok);
|
struct ivy_parser *ctx, struct ivy_token *tok);
|
||||||
struct token_parse_result stmt_parse_end(
|
struct token_parse_result stmt_parse_end(
|
||||||
struct ivy_parser *ctx, struct ivy_token *tok);
|
struct ivy_parser *ctx, struct ivy_token *tok);
|
||||||
|
extern struct token_parse_result stmt_parse_break(
|
||||||
|
struct ivy_parser *ctx, struct ivy_token *tok);
|
||||||
|
extern struct token_parse_result stmt_parse_continue(
|
||||||
|
struct ivy_parser *ctx, struct ivy_token *tok);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -232,3 +232,35 @@ struct token_parse_result stmt_parse_end(
|
|||||||
result.r_flags |= PARSE_REPEAT_TOKEN;
|
result.r_flags |= PARSE_REPEAT_TOKEN;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct token_parse_result stmt_parse_break(
|
||||||
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
||||||
|
{
|
||||||
|
struct expr_parser_state *state
|
||||||
|
= parser_get_state(ctx, struct expr_parser_state);
|
||||||
|
|
||||||
|
if (state->s_prev_component != EXPR_CMP_NONE) {
|
||||||
|
return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
arith_push_operand(state, tok);
|
||||||
|
state->s_prev_component = EXPR_CMP_KEYWORD;
|
||||||
|
|
||||||
|
return PARSE_RESULT(IVY_OK, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct token_parse_result stmt_parse_continue(
|
||||||
|
struct ivy_parser *ctx, struct ivy_token *tok)
|
||||||
|
{
|
||||||
|
struct expr_parser_state *state
|
||||||
|
= parser_get_state(ctx, struct expr_parser_state);
|
||||||
|
|
||||||
|
if (state->s_prev_component != EXPR_CMP_NONE) {
|
||||||
|
return PARSE_RESULT(IVY_ERR_BAD_SYNTAX, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
arith_push_operand(state, tok);
|
||||||
|
state->s_prev_component = EXPR_CMP_KEYWORD;
|
||||||
|
|
||||||
|
return PARSE_RESULT(IVY_OK, 0);
|
||||||
|
}
|
||||||
|
|||||||
21
lang/ast/loop-control.c
Normal file
21
lang/ast/loop-control.c
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#include "ctx.h"
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
|
#include <blue/object/string.h>
|
||||||
|
|
||||||
|
static void to_string(struct ivy_ast_node *node, b_string *str)
|
||||||
|
{
|
||||||
|
b_string_append_cstrf(str, "%s", ivy_ast_node_type_to_string(node->n_type));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ast_node_type loop_break_node_ops = {
|
||||||
|
.n_to_string = to_string,
|
||||||
|
.n_state_size = sizeof(struct parser_state),
|
||||||
|
.n_node_size = sizeof(struct ivy_ast_loop_break_node),
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ast_node_type loop_repeat_node_ops = {
|
||||||
|
.n_to_string = to_string,
|
||||||
|
.n_state_size = sizeof(struct parser_state),
|
||||||
|
.n_node_size = sizeof(struct ivy_ast_loop_repeat_node),
|
||||||
|
};
|
||||||
@@ -30,6 +30,8 @@ extern struct ast_node_type cond_node_ops;
|
|||||||
extern struct ast_node_type match_node_ops;
|
extern struct ast_node_type match_node_ops;
|
||||||
extern struct ast_node_type while_loop_node_ops;
|
extern struct ast_node_type while_loop_node_ops;
|
||||||
extern struct ast_node_type for_loop_node_ops;
|
extern struct ast_node_type for_loop_node_ops;
|
||||||
|
extern struct ast_node_type loop_break_node_ops;
|
||||||
|
extern struct ast_node_type loop_repeat_node_ops;
|
||||||
extern struct ast_node_type return_node_ops;
|
extern struct ast_node_type return_node_ops;
|
||||||
extern struct ast_node_type property_node_ops;
|
extern struct ast_node_type property_node_ops;
|
||||||
extern struct ast_node_type lambda_node_ops;
|
extern struct ast_node_type lambda_node_ops;
|
||||||
@@ -66,6 +68,8 @@ static const struct ast_node_type *node_ops[] = {
|
|||||||
[IVY_AST_MATCH] = &match_node_ops,
|
[IVY_AST_MATCH] = &match_node_ops,
|
||||||
[IVY_AST_WHILE_LOOP] = &while_loop_node_ops,
|
[IVY_AST_WHILE_LOOP] = &while_loop_node_ops,
|
||||||
[IVY_AST_FOR_LOOP] = &for_loop_node_ops,
|
[IVY_AST_FOR_LOOP] = &for_loop_node_ops,
|
||||||
|
[IVY_AST_LOOP_BREAK] = &loop_break_node_ops,
|
||||||
|
[IVY_AST_LOOP_REPEAT] = &loop_repeat_node_ops,
|
||||||
[IVY_AST_RETURN] = &return_node_ops,
|
[IVY_AST_RETURN] = &return_node_ops,
|
||||||
[IVY_AST_PROPERTY] = &property_node_ops,
|
[IVY_AST_PROPERTY] = &property_node_ops,
|
||||||
[IVY_AST_LAMBDA] = &lambda_node_ops,
|
[IVY_AST_LAMBDA] = &lambda_node_ops,
|
||||||
@@ -121,6 +125,8 @@ enum token_expr_type get_token_expr_type(struct ivy_token *tok)
|
|||||||
case IVY_KW_MATCH:
|
case IVY_KW_MATCH:
|
||||||
case IVY_KW_FOR:
|
case IVY_KW_FOR:
|
||||||
case IVY_KW_WHILE:
|
case IVY_KW_WHILE:
|
||||||
|
case IVY_KW_BREAK:
|
||||||
|
case IVY_KW_CONTINUE:
|
||||||
case IVY_KW_TRY:
|
case IVY_KW_TRY:
|
||||||
case IVY_KW_THROW:
|
case IVY_KW_THROW:
|
||||||
return TOK_EXPR_BEGIN;
|
return TOK_EXPR_BEGIN;
|
||||||
@@ -357,6 +363,8 @@ const char *ivy_ast_node_type_to_string(enum ivy_ast_node_type v)
|
|||||||
ENUM_STR(IVY_AST_IDENT);
|
ENUM_STR(IVY_AST_IDENT);
|
||||||
ENUM_STR(IVY_AST_FOR_LOOP);
|
ENUM_STR(IVY_AST_FOR_LOOP);
|
||||||
ENUM_STR(IVY_AST_WHILE_LOOP);
|
ENUM_STR(IVY_AST_WHILE_LOOP);
|
||||||
|
ENUM_STR(IVY_AST_LOOP_BREAK);
|
||||||
|
ENUM_STR(IVY_AST_LOOP_REPEAT);
|
||||||
ENUM_STR(IVY_AST_CASCADE);
|
ENUM_STR(IVY_AST_CASCADE);
|
||||||
ENUM_STR(IVY_AST_COND_GROUP);
|
ENUM_STR(IVY_AST_COND_GROUP);
|
||||||
ENUM_STR(IVY_AST_MATCH);
|
ENUM_STR(IVY_AST_MATCH);
|
||||||
|
|||||||
Reference in New Issue
Block a user