#include "ctx.h" #include 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; }