From 64a00dad4891aced22d77a404461a3aee2df0046 Mon Sep 17 00:00:00 2001 From: "kr.angelov" Date: Sat, 21 Jan 2012 10:27:55 +0000 Subject: [PATCH] added an API for printing the PGF to human readable format --- src/runtime/c/Makefile.am | 9 ++++- src/runtime/c/pgf/data.c | 3 ++ src/runtime/c/pgf/data.h | 6 ++- src/runtime/c/pgf/expr.c | 57 +++++++++++++++++++++++++---- src/runtime/c/pgf/expr.h | 8 +++- src/runtime/c/pgf/pgf.h | 2 + src/runtime/c/pgf/reader.c | 41 ++++++++++----------- src/runtime/c/utils/pgf-translate.c | 2 +- 8 files changed, 94 insertions(+), 34 deletions(-) diff --git a/src/runtime/c/Makefile.am b/src/runtime/c/Makefile.am index 0930dc58a..710dd7330 100644 --- a/src/runtime/c/Makefile.am +++ b/src/runtime/c/Makefile.am @@ -47,7 +47,7 @@ pgfinclude_HEADERS = \ pgf/expr.h \ pgf/linearize.h \ pgf/parser.h \ - pgf/pgf.h + pgf/pgf.h libgu_la_SOURCES = \ gu/assert.c \ @@ -88,15 +88,20 @@ libpgf_la_SOURCES = \ pgf/parser.c \ pgf/parser.h \ pgf/reader.c \ - pgf/linearize.c + pgf/linearize.c \ + pgf/printer.c bin_PROGRAMS = \ utils/pgf2yaml \ + utils/pgf-print \ utils/pgf-translate utils_pgf2yaml_SOURCES = utils/pgf2yaml.c utils_pgf2yaml_LDADD = libpgf.la libgu.la +utils_pgf_print_SOURCES = utils/pgf-print.c +utils_pgf_print_LDADD = libpgf.la libgu.la + utils_pgf_translate_SOURCES = utils/pgf-translate.c utils_pgf_translate_LDADD = libpgf.la libgu.la diff --git a/src/runtime/c/pgf/data.c b/src/runtime/c/pgf/data.c index 98cbf5427..19aa51f23 100644 --- a/src/runtime/c/pgf/data.c +++ b/src/runtime/c/pgf/data.c @@ -229,6 +229,9 @@ GU_DEFINE_TYPE( GU_DEFINE_TYPE( PgfConcr, struct, GU_MEMBER(PgfConcr, cflags, PgfFlagsP), + GU_MEMBER_P(PgfConcr, ccats, GuMap), + GU_MEMBER_P(PgfConcr, cncfuns, PgfCncFuns), + GU_MEMBER_P(PgfConcr, sequences, PgfSequences), GU_MEMBER_P(PgfConcr, printnames, PgfPrintNames), GU_MEMBER_V(PgfConcr, cnccats, GU_TYPE_LIT(pointer, PgfCIdMap*, diff --git a/src/runtime/c/pgf/data.h b/src/runtime/c/pgf/data.h index d80a19526..1cc053e37 100644 --- a/src/runtime/c/pgf/data.h +++ b/src/runtime/c/pgf/data.h @@ -157,6 +157,7 @@ struct PgfCncCat { struct PgfCncFun { PgfCId fun; // XXX: resolve to PgfFunDecl*? + int funid; GuLength n_lins; PgfSeqId lins[]; }; @@ -184,8 +185,11 @@ extern GU_DECLARE_TYPE(PgfPrintNames, GuStringMap); struct PgfConcr { PgfFlags* cflags; PgfPrintNames* printnames; - PgfCIdMap* cnccats; + GuMap* ccats; PgfCCatSeq extra_ccats; + PgfCncFuns* cncfuns; + PgfSequences* sequences; + PgfCIdMap* cnccats; }; extern GU_DECLARE_TYPE(PgfConcr, struct); diff --git a/src/runtime/c/pgf/expr.c b/src/runtime/c/pgf/expr.c index cd5d69928..105a3db9d 100644 --- a/src/runtime/c/pgf/expr.c +++ b/src/runtime/c/pgf/expr.c @@ -291,8 +291,8 @@ pgf_read_expr(GuReader* rdr, GuPool* pool, GuExn* err) return expr; } -static void -pgf_expr_print_with_paren(PgfExpr expr, bool need_paren, +void +pgf_print_expr(PgfExpr expr, int prec, GuWriter* wtr, GuExn* err) { GuVariantInfo ei = gu_variant_open(expr); @@ -304,13 +304,13 @@ pgf_expr_print_with_paren(PgfExpr expr, bool need_paren, } case PGF_EXPR_APP: { PgfExprApp* app = ei.data; - if (need_paren) { + if (prec > 3) { gu_puts("(", wtr, err); } - pgf_expr_print_with_paren(app->fun, false, wtr, err); + pgf_print_expr(app->fun, 3, wtr, err); gu_puts(" ", wtr, err); - pgf_expr_print_with_paren(app->arg, true, wtr, err); - if (need_paren) { + pgf_print_expr(app->arg, 4, wtr, err); + if (prec > 3) { gu_puts(")", wtr, err); } break; @@ -329,6 +329,47 @@ pgf_expr_print_with_paren(PgfExpr expr, bool need_paren, } void -pgf_expr_print(PgfExpr expr, GuWriter* wtr, GuExn* err) { - pgf_expr_print_with_paren(expr, false, wtr, err); +pgf_print_hypo(PgfHypo *hypo, int prec, GuWriter *wtr, GuExn *err) +{ + if (hypo->bindtype == PGF_BIND_TYPE_IMPLICIT) { + gu_puts("({", wtr, err); + gu_string_write(hypo->cid, wtr, err); + gu_puts("} : ", wtr, err); + pgf_print_type(hypo->type, 0, wtr, err); + gu_puts(")", wtr, err); + } else { + GuPool* tmp_pool = gu_new_pool(); + GuString tmp = gu_str_string("_", tmp_pool); + + if (!gu_string_eq(hypo->cid, tmp)) { + gu_puts("(", wtr, err); + gu_string_write(hypo->cid, wtr, err); + gu_puts(" : ", wtr, err); + pgf_print_type(hypo->type, 0, wtr, err); + gu_puts(")", wtr, err); + } else { + pgf_print_type(hypo->type, prec, wtr, err); + } + + gu_pool_free(tmp_pool); + } +} + +void +pgf_print_type(PgfType *type, int prec, GuWriter *wtr, GuExn *err) +{ + size_t len = gu_seq_length(type->hypos); + for (size_t i = 0; i < len; i++) { + PgfHypo *hypo = gu_seq_index(type->hypos, PgfHypo, i); + pgf_print_hypo(hypo, 1, wtr, err); + + gu_puts(" -> ", wtr, err); + } + + gu_string_write(type->cid, wtr, err); + + for (int i = 0; i < type->n_exprs; i++) { + gu_puts(" ", wtr, err); + pgf_print_expr(type->exprs[i], 4, wtr, err); + } } diff --git a/src/runtime/c/pgf/expr.h b/src/runtime/c/pgf/expr.h index 7ecca30bd..65e2d66a9 100644 --- a/src/runtime/c/pgf/expr.h +++ b/src/runtime/c/pgf/expr.h @@ -147,6 +147,12 @@ PgfExpr pgf_read_expr(GuReader* rdr, GuPool* pool, GuExn* err); void -pgf_expr_print(PgfExpr expr, GuWriter* wtr, GuExn* err); +pgf_print_expr(PgfExpr expr, int prec, GuWriter* wtr, GuExn* err); + +void +pgf_print_hypo(PgfHypo *hypo, int prec, GuWriter *wtr, GuExn *err); + +void +pgf_print_type(PgfType *type, int prec, GuWriter *wtr, GuExn *err); #endif /* EXPR_H_ */ diff --git a/src/runtime/c/pgf/pgf.h b/src/runtime/c/pgf/pgf.h index 8ee26aadd..df4904b53 100644 --- a/src/runtime/c/pgf/pgf.h +++ b/src/runtime/c/pgf/pgf.h @@ -74,5 +74,7 @@ GU_DECLARE_TYPE(PgfPGF, struct); /// @} +void +pgf_print(PgfPGF* pgf, GuWriter* wtr, GuExn* err); #endif // PGF_H_ diff --git a/src/runtime/c/pgf/reader.c b/src/runtime/c/pgf/reader.c index ba4c5217a..d902b698a 100644 --- a/src/runtime/c/pgf/reader.c +++ b/src/runtime/c/pgf/reader.c @@ -54,7 +54,6 @@ struct PgfReader { GuTypeMap* read_to_map; GuTypeMap* read_new_map; void* curr_key; - GuPool* curr_pool; }; typedef struct PgfReadTagExn PgfReadTagExn; @@ -433,6 +432,7 @@ pgf_read_to_PgfCCatId(GuType* type, PgfReader* rdr, void* to) PgfCCat** pto = to; int fid = pgf_read_int(rdr); gu_return_on_exn(rdr->err,); + PgfCCat* ccat = gu_map_get(rdr->curr_ccats, &fid, PgfCCat*); if (!ccat) { ccat = gu_new(PgfCCat, rdr->pool); @@ -539,11 +539,18 @@ pgf_read_new_idarray(GuType* type, PgfReader* rdr, GuPool* pool, size_t* size_out) { (void) type; - void* list = pgf_read_new_GuList(type, rdr, rdr->curr_pool, size_out); + void* list = pgf_read_new_GuList(type, rdr, rdr->opool, size_out); if (type == gu_type(PgfSequences)) { rdr->curr_sequences = list; } else if (type == gu_type(PgfCncFuns)) { rdr->curr_cncfuns = list; + + // set the function ids + int n_funs = gu_list_length(rdr->curr_cncfuns); + for (int funid = 0; funid < n_funs; funid++) { + PgfCncFun* cncfun = gu_list_index(rdr->curr_cncfuns, funid); + cncfun->funid = funid; + } } else { gu_impossible(); } @@ -645,39 +652,31 @@ pgf_read_new_PgfConcr(GuType* type, PgfReader* rdr, GuPool* pool, size_t* size_out) { (void) (type && size_out); - /* We allocate indices from a temporary pool. The actual data - * is allocated from rdr->opool. Once everything is resolved - * and indices aren't needed, the temporary pool can be - * freed. */ - GuPool* tmp_pool = gu_new_pool(); - rdr->curr_pool = tmp_pool; - PgfConcr* concr = gu_new(PgfConcr, pool);; + PgfConcr* concr = gu_new(PgfConcr, pool); concr->cflags = pgf_read_new(rdr, gu_type(PgfFlags), pool, NULL); concr->printnames = pgf_read_new(rdr, gu_type(PgfPrintNames), pool, NULL); - rdr->curr_sequences = - pgf_read_new(rdr, gu_type(PgfSequences), pool, NULL); - rdr->curr_cncfuns = + concr->sequences = + pgf_read_new(rdr, gu_type(PgfSequences), rdr->opool, NULL); + concr->cncfuns = pgf_read_new(rdr, gu_type(PgfCncFuns), pool, NULL); GuMapType* lindefs_t = gu_type_cast(gu_type(PgfLinDefs), GuMap); - rdr->curr_lindefs = gu_map_type_make(lindefs_t, tmp_pool); + rdr->curr_lindefs = gu_map_type_make(lindefs_t, pool); pgf_read_into_map(lindefs_t, rdr, rdr->curr_lindefs, rdr->opool); GuMapType* ccats_t = gu_type_cast(gu_type(PgfCCatMap), GuMap); - rdr->curr_ccats = - gu_new_int_map(PgfCCat*, &gu_null_struct, tmp_pool); - rdr->ccat_locs = - gu_new_int_map(GuBuf*, &gu_null_struct, tmp_pool); - pgf_read_into_map(ccats_t, rdr, rdr->curr_ccats, rdr->opool); + concr->ccats = + gu_new_int_map(PgfCCat*, &gu_null_struct, pool); + rdr->curr_ccats = concr->ccats; + pgf_read_into_map(ccats_t, rdr, concr->ccats, rdr->opool); concr->cnccats = pgf_read_new(rdr, gu_type(PgfCncCatMap), rdr->opool, NULL); - GuBuf* extra_ccats = gu_new_buf(PgfCCat*, tmp_pool); + GuBuf* extra_ccats = gu_new_buf(PgfCCat*, pool); PgfCCatCbCtx ctx = { { pgf_read_ccat_cb }, extra_ccats }; - gu_map_iter(rdr->curr_ccats, &ctx.fn, NULL); + gu_map_iter(concr->ccats, &ctx.fn, NULL); concr->extra_ccats = gu_buf_freeze(extra_ccats, rdr->opool); (void) pgf_read_int(rdr); // totalcats - gu_pool_free(tmp_pool); return concr; } diff --git a/src/runtime/c/utils/pgf-translate.c b/src/runtime/c/utils/pgf-translate.c index c5cdc31e2..5b7405489 100644 --- a/src/runtime/c/utils/pgf-translate.c +++ b/src/runtime/c/utils/pgf-translate.c @@ -144,7 +144,7 @@ int main(int argc, char* argv[]) { } gu_putc(' ', wtr, err); // Write out the abstract syntax tree - pgf_expr_print(expr, wtr, err); + pgf_print_expr(expr, 0, wtr, err); gu_putc('\n', wtr, err); // Enumerate the concrete syntax trees corresponding