diff --git a/src/runtime/c/pgf/linearizer.c b/src/runtime/c/pgf/linearizer.c index ced2a8cf2..dd8909848 100644 --- a/src/runtime/c/pgf/linearizer.c +++ b/src/runtime/c/pgf/linearizer.c @@ -13,7 +13,7 @@ #include #include -//#define PGF_LINEARIZER_DEBUG +#define PGF_LINEARIZER_DEBUG static void pgf_lzr_add_overl_entry(PgfCncOverloadMap* overl_table, @@ -130,6 +130,13 @@ pgf_print_cnc_tree(PgfCncTree ctree, GuOut* out, GuExn* err) if (clit->n_vars > 0) gu_putc(')', out, err); break; } + case PGF_CNC_TREE_LINDEF: { + PgfCncTreeLinDef* clindef = ti.data; + gu_putc('(', out, err); + pgf_print_cnc_tree_vars(clindef->n_vars, clindef->context, out, err); + gu_printf(out, err, "F%d[%s] %s)", clindef->fun->funid, clindef->str); + break; + } case GU_VARIANT_NULL: gu_puts("null", out, err); break; @@ -222,44 +229,32 @@ redo:; static PgfCncTree pgf_cnc_resolve_def(PgfCnc* cnc, size_t n_vars, PgfPrintContext* context, - PgfCCat* ccat, GuString s, GuPool* pool) + PgfCId abs_id, PgfCCat* ccat, GuString s, GuPool* pool) { - PgfCncTree lit = gu_null_variant; PgfCncTree ret = gu_null_variant; + PgfCncFun* fun = NULL; - PgfCncTreeLit* clit = - gu_new_variant(PGF_CNC_TREE_LIT, - PgfCncTreeLit, - &lit, pool); - clit->n_vars = 0; - clit->context = context; - clit->fid = cnc->fid++; - PgfLiteralStr* lit_str = - gu_new_flex_variant(PGF_LITERAL_STR, - PgfLiteralStr, - val, strlen(s)+1, - &clit->lit, pool); - strcpy((char*) lit_str->val, (char*) s); + if (ccat->lindefs != NULL) { + int index = + gu_choice_next(cnc->ch, gu_seq_length(ccat->lindefs)); + if (index < 0) { + return ret; + } - if (ccat->lindefs == NULL) - return lit; - - int index = - gu_choice_next(cnc->ch, gu_seq_length(ccat->lindefs)); - if (index < 0) { - return ret; + fun = gu_seq_get(ccat->lindefs, PgfCncFun*, index); } - PgfCncTreeApp* capp = - gu_new_flex_variant(PGF_CNC_TREE_APP, - PgfCncTreeApp, - args, 1, &ret, pool); - capp->ccat = ccat; - capp->fun = gu_seq_get(ccat->lindefs, PgfCncFun*, index); - capp->fid = cnc->fid++; - capp->n_vars = n_vars; - capp->context = context; - capp->n_args = 1; - capp->args[0] = lit; + + PgfCncTreeLinDef* clindef = + gu_new_variant(PGF_CNC_TREE_LINDEF, + PgfCncTreeLinDef, + &ret, pool); + clindef->abs_id = abs_id; + clindef->ccat = ccat; + clindef->fun = fun; + clindef->fid = cnc->fid++; + clindef->n_vars = n_vars; + clindef->context = context; + clindef->str = s; return ret; } @@ -433,10 +428,10 @@ pgf_cnc_resolve(PgfCnc* cnc, gu_putc('[', out, err); gu_string_write(efun->fun, out, err); gu_putc(']', out, err); - GuString s = gu_string_buf_freeze(sbuf, tmp_pool); + GuString s = gu_string_buf_freeze(sbuf, pool); if (ccat != NULL) { - ret = pgf_cnc_resolve_def(cnc, n_vars, context, ccat, s, pool); + ret = pgf_cnc_resolve_def(cnc, n_vars, context, efun->fun, ccat, s, pool); } else { PgfCncTreeLit* clit = gu_new_variant(PGF_CNC_TREE_LIT, @@ -504,7 +499,7 @@ redo:; } if (ccat != NULL) { - ret = pgf_cnc_resolve_def(cnc, n_vars, context, ccat, ctxt->name, pool); + ret = pgf_cnc_resolve_def(cnc, n_vars, context, ctxt->name, ccat, ctxt->name, pool); } else { PgfCncTreeLit* clit = gu_new_variant(PGF_CNC_TREE_LIT, @@ -634,7 +629,7 @@ typedef struct { typedef struct { PgfLinFuncs* funcs; - PgfCncTreeApp* app; + PgfCncTree ctree; PgfSymbolKP* kp; GuBuf* events; PgfLzr* lzr; @@ -642,7 +637,7 @@ typedef struct { } PgfLzrCache; static void -pgf_lzr_linearize_symbols(PgfLzr* lzr, PgfCncTreeApp* fapp, +pgf_lzr_linearize_symbols(PgfLzr* lzr, PgfCncTree ctree, PgfSymbols* syms, uint16_t sym_idx); static void @@ -652,7 +647,7 @@ static void pgf_lzr_cache_flush(PgfLzrCache* cache, PgfSymbols* form) { cache->lzr->funcs = cache->prev; - pgf_lzr_linearize_symbols(cache->lzr, cache->app, form, 0); + pgf_lzr_linearize_symbols(cache->lzr, cache->ctree, form, 0); size_t n_cached = gu_buf_length(cache->events); for (size_t i = 0; i < n_cached; i++) { @@ -826,6 +821,12 @@ pgf_lzr_linearize_var(PgfLzr* lzr, PgfCncTree ctree, size_t var_idx) context = flit->context; break; } + case PGF_CNC_TREE_LINDEF: { + PgfCncTreeLinDef* flindef = cti.data; + n_vars = flindef->n_vars; + context = flindef->context; + break; + } default: gu_impossible(); } @@ -842,7 +843,7 @@ pgf_lzr_linearize_var(PgfLzr* lzr, PgfCncTree ctree, size_t var_idx) } static void -pgf_lzr_linearize_symbols(PgfLzr* lzr, PgfCncTreeApp* fapp, +pgf_lzr_linearize_symbols(PgfLzr* lzr, PgfCncTree ctree, PgfSymbols* syms, uint16_t sym_idx) { size_t nsyms = gu_seq_length(syms); @@ -851,26 +852,40 @@ pgf_lzr_linearize_symbols(PgfLzr* lzr, PgfCncTreeApp* fapp, GuVariantInfo sym_i = gu_variant_open(sym); switch (sym_i.tag) { case PGF_SYMBOL_CAT: - case PGF_SYMBOL_LIT: { - if (fapp == NULL) - return; - - PgfSymbolIdx* sidx = sym_i.data; - gu_assert((unsigned) sidx->d < fapp->n_args); - - PgfCncTree argf = fapp->args[sidx->d]; - pgf_lzr_linearize_tree(lzr, argf, sidx->r); - break; - } + case PGF_SYMBOL_LIT: case PGF_SYMBOL_VAR: { - if (fapp == NULL) + if (gu_variant_is_null(ctree)) return; PgfSymbolIdx* sidx = sym_i.data; - gu_assert((unsigned) sidx->d < fapp->n_args); - PgfCncTree argf = fapp->args[sidx->d]; - pgf_lzr_linearize_var(lzr, argf, sidx->r); + GuVariantInfo tree_i = gu_variant_open(ctree); + switch (tree_i.tag) { + case PGF_CNC_TREE_APP: { + PgfCncTreeApp* papp = tree_i.data; + + gu_assert((unsigned) sidx->d < papp->n_args); + + PgfCncTree argf = papp->args[sidx->d]; + if (sym_i.tag == PGF_SYMBOL_VAR) + pgf_lzr_linearize_var(lzr, argf, sidx->r); + else + pgf_lzr_linearize_tree(lzr, argf, sidx->r); + break; + } + case PGF_CNC_TREE_LINDEF: { + PgfCncTreeLinDef* plindef = tree_i.data; + + gu_assert(sidx->d == 0); + + if ((*lzr->funcs)->symbol_token) { + (*lzr->funcs)->symbol_token(lzr->funcs, plindef->str); + } + break; + } + default: + gu_impossible(); + } break; } case PGF_SYMBOL_KS: { @@ -885,12 +900,12 @@ pgf_lzr_linearize_symbols(PgfLzr* lzr, PgfCncTreeApp* fapp, PgfSymbolKP* kp = sym_i.data; //gu_buf_push(pres, PgfSymbolKP*, kp); PgfLzrCache* cache = gu_new(PgfLzrCache, lzr->tmp_pool); - cache->funcs = &pgf_lzr_cache_funcs; - cache->app = fapp; - cache->kp = kp; - cache->events= gu_new_buf(PgfLzrCached, lzr->tmp_pool); - cache->lzr = lzr; - cache->prev = lzr->funcs; + cache->funcs = &pgf_lzr_cache_funcs; + cache->ctree = ctree; + cache->kp = kp; + cache->events = gu_new_buf(PgfLzrCached, lzr->tmp_pool); + cache->lzr = lzr; + cache->prev = lzr->funcs; lzr->funcs = &cache->funcs; break; } @@ -945,8 +960,8 @@ pgf_lzr_linearize_tree(PgfLzr* lzr, PgfCncTree ctree, size_t lin_idx) } gu_require(lin_idx < fun->n_lins); - pgf_lzr_linearize_symbols(lzr, fapp, fun->lins[lin_idx]->syms, 0); - + pgf_lzr_linearize_symbols(lzr, ctree, fun->lins[lin_idx]->syms, 0); + if ((*lzr->funcs)->end_phrase && fapp->ccat != NULL) { (*lzr->funcs)->end_phrase(lzr->funcs, fun->absfun->type->cid, @@ -1017,6 +1032,29 @@ pgf_lzr_linearize_tree(PgfLzr* lzr, PgfCncTree ctree, size_t lin_idx) break; } + case PGF_CNC_TREE_LINDEF: { + PgfCncTreeLinDef* flindef = cti.data; + PgfCncFun* fun = flindef->fun; + + if ((*lzr->funcs)->begin_phrase) { + (*lzr->funcs)->begin_phrase(lzr->funcs, + "", + flindef->fid, lin_idx, + flindef->abs_id); + } + + gu_require(lin_idx < fun->n_lins); + pgf_lzr_linearize_symbols(lzr, ctree, fun->lins[lin_idx]->syms, 0); + + if ((*lzr->funcs)->end_phrase) { + (*lzr->funcs)->end_phrase(lzr->funcs, + "", + flindef->fid, lin_idx, + flindef->abs_id); + } + + break; + } default: gu_impossible(); } @@ -1186,10 +1224,16 @@ pgf_lzr_get_table(PgfConcr* concr, PgfCncTree ctree, *labels = &s_label; break; } + case PGF_CNC_TREE_LINDEF: { + static GuString s = "s"; + + *n_lins = 1; + *labels = &s; + break; + } default: gu_impossible(); } - } PGF_API void @@ -1230,7 +1274,7 @@ pgf_get_tokens(PgfSymbols* syms, uint16_t sym_idx, GuPool* pool) }; PgfLzr* lzr = pgf_new_lzr(NULL, &flin.funcs, tmp_pool); - pgf_lzr_linearize_symbols(lzr, NULL, syms, sym_idx); + pgf_lzr_linearize_symbols(lzr, gu_null_variant, syms, sym_idx); while (lzr->funcs != &flin.funcs) { PgfLzrCache* cache = gu_container(lzr->funcs, PgfLzrCache, funcs); diff --git a/src/runtime/c/pgf/linearizer.h b/src/runtime/c/pgf/linearizer.h index 57fad962f..78ac092b6 100644 --- a/src/runtime/c/pgf/linearizer.h +++ b/src/runtime/c/pgf/linearizer.h @@ -18,6 +18,7 @@ typedef enum { PGF_CNC_TREE_APP, PGF_CNC_TREE_CHUNKS, PGF_CNC_TREE_LIT, + PGF_CNC_TREE_LINDEF } PgfCncTreeTag; typedef struct { @@ -50,6 +51,19 @@ typedef struct { PgfLiteral lit; } PgfCncTreeLit; +typedef struct { + PgfCId abs_id; + + PgfCCat* ccat; + PgfCncFun* fun; + int fid; + + size_t n_vars; + PgfPrintContext* context; + + GuString str; +} PgfCncTreeLinDef; + #endif /// An enumeration of #PgfCncTree trees.