100 lines
2.4 KiB
C
100 lines
2.4 KiB
C
#include "ctx.h"
|
|
|
|
#include <ivy/lang/ast.h>
|
|
|
|
bool parse_if(struct ivy_parser *parser, struct ivy_ast_node **out)
|
|
{
|
|
if (!parse_keyword(parser, IVY_KW_IF)) {
|
|
parse_trace(parser, "expected `if` keyword");
|
|
return false;
|
|
}
|
|
|
|
struct ivy_ast_cond_group_node *cond_group
|
|
= create_node(IVY_AST_COND_GROUP);
|
|
struct ivy_ast_cond_node *cond = create_node(IVY_AST_COND);
|
|
|
|
if (!parse_expr(parser, EXPR_PARSE_STOP_LEFT_BRACKET, &cond->n_cond)) {
|
|
parse_trace(parser, "invalid if predicate");
|
|
return false;
|
|
}
|
|
|
|
if (!parse_block(parser, &cond->n_body)) {
|
|
parse_trace(parser, "invalid if body");
|
|
return false;
|
|
}
|
|
|
|
fx_queue_push_back(&cond_group->n_branches, &cond->n_base.n_entry);
|
|
|
|
bool ok = true;
|
|
while (1) {
|
|
struct ivy_ast_node *branch_pred = NULL;
|
|
struct ivy_ast_node *branch_block = NULL;
|
|
if (parse_keyword(parser, IVY_KW_ELIF)) {
|
|
if (!parse_expr(
|
|
parser, EXPR_PARSE_STOP_LEFT_BRACKET,
|
|
&branch_pred)) {
|
|
parse_trace(
|
|
parser,
|
|
"invalid elif branch predicate");
|
|
ok = false;
|
|
break;
|
|
}
|
|
} else if (!parse_keyword(parser, IVY_KW_ELSE)) {
|
|
break;
|
|
}
|
|
|
|
if (!parse_block(parser, &branch_block)) {
|
|
parse_trace(parser, "invalid branch body");
|
|
ok = false;
|
|
break;
|
|
}
|
|
|
|
struct ivy_ast_cond_node *cond = create_node(IVY_AST_COND);
|
|
cond->n_cond = branch_pred;
|
|
cond->n_body = branch_block;
|
|
fx_queue_push_back(&cond_group->n_branches, &cond->n_base.n_entry);
|
|
|
|
if (!branch_pred) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
*out = generic_node(cond_group);
|
|
return true;
|
|
}
|
|
|
|
bool parse_if_inline(
|
|
struct ivy_parser *parser, struct ivy_ast_node *body,
|
|
struct ivy_ast_node **out)
|
|
{
|
|
if (!parse_keyword(parser, IVY_KW_IF)) {
|
|
parse_trace(parser, "expected `if` keyword");
|
|
return false;
|
|
}
|
|
|
|
struct ivy_ast_cond_group_node *cond_group
|
|
= create_node(IVY_AST_COND_GROUP);
|
|
struct ivy_ast_cond_node *cond = create_node(IVY_AST_COND);
|
|
cond->n_body = body;
|
|
|
|
if (!parse_expr(parser, EXPR_PARSE_NORMAL, &cond->n_cond)) {
|
|
parse_trace(parser, "invalid if predicate");
|
|
return false;
|
|
}
|
|
|
|
fx_queue_push_back(&cond_group->n_branches, &cond->n_base.n_entry);
|
|
|
|
if (parse_keyword(parser, IVY_KW_ELSE)) {
|
|
struct ivy_ast_cond_node *cond = create_node(IVY_AST_COND);
|
|
if (!parse_expr(parser, EXPR_PARSE_NORMAL, &cond->n_body)) {
|
|
parse_trace(parser, "invalid else body");
|
|
return false;
|
|
}
|
|
|
|
fx_queue_push_back(&cond_group->n_branches, &cond->n_base.n_entry);
|
|
}
|
|
|
|
*out = generic_node(cond_group);
|
|
return true;
|
|
}
|