Files

102 lines
2.2 KiB
C
Raw Permalink Normal View History

#include "ctx.h"
#include <ivy/lang/ast.h>
static bool parse_dynamic_package(
struct ivy_parser *parser, struct ivy_ast_node *expr,
struct ivy_ast_node **out)
{
if (!parse_keyword(parser, IVY_KW_FOR)) {
parse_trace(
parser,
"expected `for` after package comprehension "
"expression");
return false;
}
struct ivy_ast_pkg_dynamic_node *pkg = create_node(IVY_AST_PKG_DYNAMIC);
pkg->n_transform = expr;
if (!parse_expr(parser, EXPR_PARSE_STOP_KW_IN, &pkg->n_item)) {
parse_trace(parser, "invalid package comprehension item");
return false;
}
if (!parse_keyword(parser, IVY_KW_IN)) {
parse_trace(
parser,
"expected `in` after package comprehension item");
return false;
}
if (!parse_expr(parser, EXPR_PARSE_NORMAL, &pkg->n_item)) {
parse_trace(parser, "invalid package comprehension container");
return false;
}
if (!parse_symbol(parser, IVY_SYM_RIGHT_BRACE)) {
parse_trace(
parser,
"expected `}` after package comprehension container");
return false;
}
*out = generic_node(pkg);
return true;
}
bool parse_package(struct ivy_parser *parser, struct ivy_ast_node **out)
{
if (!parse_symbol(parser, IVY_SYM_LEFT_BRACE)) {
parse_trace(parser, "expected `{`");
return false;
}
struct ivy_ast_node *item = NULL;
if (!parse_expr(
parser, EXPR_PARSE_STOP_COMMA | EXPR_PARSE_STOP_KW_CONTROL,
&item)) {
parse_trace(parser, "invalid package item");
return false;
}
if (peek_keyword(parser, IVY_KW_FOR)) {
return parse_dynamic_package(parser, item, out);
}
struct ivy_ast_pkg_static_node *pkg = create_node(IVY_AST_PKG_STATIC);
if (item) {
fx_queue_push_back(&pkg->n_items, &item->n_entry);
}
bool ok = true;
while (ok) {
parse_linefeed(parser);
if (parse_symbol(parser, IVY_SYM_RIGHT_BRACE)) {
break;
}
if (!parse_symbol(parser, IVY_SYM_COMMA)) {
parse_trace(
parser,
"expected `,` or `}` after package item");
ok = false;
break;
}
if (!parse_expr(
parser,
EXPR_PARSE_STOP_COMMA | EXPR_PARSE_STOP_KW_CONTROL,
&item)) {
parse_trace(parser, "invalid package item");
return false;
}
fx_queue_push_back(&pkg->n_items, &item->n_entry);
}
*out = generic_node(pkg);
return true;
}