void pgf_print_symbol(PgfSymbol sym, GuWriter *wtr, GuExn *err) { switch (gu_variant_tag(sym)) { case PGF_SYMBOL_CAT: { PgfSymbolCat* scat = gu_variant_data(sym); gu_printf(wtr, err, "<%d,%d>", scat->d, scat->r); break; } case PGF_SYMBOL_KS: { PgfSymbolKS* sks = gu_variant_data(sym); pgf_print_tokens(sks->tokens, wtr, err); break; } case PGF_SYMBOL_KP: { PgfSymbolKP* skp = gu_variant_data(sym); gu_puts("pre {", wtr, err); pgf_print_tokens(skp->default_form, wtr, err); for (size_t i = 0; i < skp->n_forms; i++) { gu_puts("; ", wtr, err); pgf_print_tokens(skp->forms[i].form, wtr, err); gu_puts(" / ", wtr, err); size_t n_prefixes = gu_list_length(skp->forms[i].prefixes); for (size_t j = 0; j < n_prefixes; j++) { if (j > 0) gu_putc(' ', wtr, err); GuString prefix = gu_list_index(skp->forms[i].prefixes, j); gu_putc('"', wtr, err); gu_string_write(prefix, wtr, err); gu_putc('"', wtr, err); } } gu_puts("}", wtr, err); break; } case PGF_SYMBOL_LIT: { PgfSymbolLit *slit = gu_variant_data(sym); gu_printf(wtr, err, "{%d,%d}", slit->d, slit->r); break; } case PGF_SYMBOL_VAR: { PgfSymbolVar *svar = gu_variant_data(sym); gu_printf(wtr, err, "<%d,$%d>", svar->d, svar->r); break; } default: gu_impossible(); } }
PgfApplication* pgf_expr_unapply(PgfExpr expr, GuPool* pool) { int arity = pgf_expr_arity(expr); if (arity < 0) { return NULL; } PgfApplication* appl = gu_new_flex(pool, PgfApplication, args, arity); appl->n_args = arity; for (int n = arity - 1; n >= 0; n--) { PgfExpr e = pgf_expr_unwrap(expr); gu_assert(gu_variant_tag(e) == PGF_EXPR_APP); PgfExprApp* app = gu_variant_data(e); appl->args[n] = app->arg; expr = app->fun; } PgfExpr e = pgf_expr_unwrap(expr); gu_assert(gu_variant_tag(e) == PGF_EXPR_FUN); PgfExprFun* fun = gu_variant_data(e); appl->fun = fun->fun; return appl; }