summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorkr.angelov <kr.angelov@gmail.com>2013-04-05 08:42:56 +0000
committerkr.angelov <kr.angelov@gmail.com>2013-04-05 08:42:56 +0000
commita449a240de28948ea045021e923dea0594170782 (patch)
tree351b10795ffdea66b8b68e606c1ccf5933ed73fc /src
parent3c244ff27f015df6cfa918c9ba3e192f4d5b62ff (diff)
a very simple linearization for partial abstract trees in the C runtime
Diffstat (limited to 'src')
-rw-r--r--src/runtime/c/pgf/linearizer.c106
-rw-r--r--src/runtime/c/pgf/linearizer.h18
2 files changed, 69 insertions, 55 deletions
diff --git a/src/runtime/c/pgf/linearizer.c b/src/runtime/c/pgf/linearizer.c
index 3386b4da2..4f3bee0a0 100644
--- a/src/runtime/c/pgf/linearizer.c
+++ b/src/runtime/c/pgf/linearizer.c
@@ -108,6 +108,7 @@ struct PgfLzn {
typedef enum {
PGF_CNC_TREE_APP,
+ PGF_CNC_TREE_CHUNKS,
PGF_CNC_TREE_LIT,
} PgfCncTreeTag;
@@ -118,6 +119,11 @@ typedef struct {
} PgfCncTreeApp;
typedef struct {
+ GuLength n_args;
+ PgfCncTree args[];
+} PgfCncTreeChunks;
+
+typedef struct {
PgfLiteral lit;
} PgfCncTreeLit;
@@ -127,11 +133,6 @@ pgf_print_cnc_tree(PgfCncTree ctree, GuWriter* wtr, GuExn* err)
{
GuVariantInfo ti = gu_variant_open(ctree);
switch (ti.tag) {
- case PGF_CNC_TREE_LIT: {
- PgfCncTreeLit* clit = ti.data;
- pgf_print_literal(clit->lit, wtr, err);
- break;
- }
case PGF_CNC_TREE_APP: {
PgfCncTreeApp* capp = ti.data;
if (capp->n_args > 0) gu_putc('(', wtr, err);
@@ -143,6 +144,25 @@ pgf_print_cnc_tree(PgfCncTree ctree, GuWriter* wtr, GuExn* err)
if (capp->n_args > 0) gu_putc(')', wtr, err);
break;
}
+ case PGF_CNC_TREE_CHUNKS: {
+ PgfCncTreeChunks* chunks = ti.data;
+ if (chunks->n_args > 0) gu_putc('(', wtr, err);
+ gu_putc('?', wtr, err);
+ for (size_t i = 0; i < chunks->n_args; i++) {
+ gu_putc(' ', wtr, err);
+ pgf_print_cnc_tree(chunks->args[i], wtr, err);
+ }
+ if (chunks->n_args > 0) gu_putc(')', wtr, err);
+ break;
+ }
+ case PGF_CNC_TREE_LIT: {
+ PgfCncTreeLit* clit = ti.data;
+ pgf_print_literal(clit->lit, wtr, err);
+ break;
+ }
+ case GU_VARIANT_NULL:
+ gu_puts("null", wtr, err);
+ break;
default:
gu_impossible();
}
@@ -292,13 +312,34 @@ pgf_lzn_resolve(PgfLzn* lzn, PgfExpr expr, PgfCCat* ccat, GuPool* pool)
goto done;
}
case PGF_EXPR_META: {
- if (ccat == NULL || ccat->lindefs == NULL) {
+ if (ccat == NULL) {
+ size_t n_args = gu_buf_length(args);
+
+ PgfCncTreeChunks* chunks =
+ gu_new_flex_variant(PGF_CNC_TREE_CHUNKS,
+ PgfCncTreeChunks,
+ args, n_args, &ret, pool);
+ chunks->n_args = n_args;
+
+ for (size_t i = 0; i < n_args; i++) {
+ PgfExpr earg = gu_buf_get(args, PgfExpr, n_args-i-1);
+ chunks->args[i] = pgf_lzn_resolve(lzn, earg, NULL, pool);
+ if (gu_variant_is_null(chunks->args[i])) {
+ ret = gu_null_variant;
+ break;
+ }
+ }
+
goto done;
- }
+ } else {
+ if (ccat->lindefs == NULL) {
+ goto done;
+ }
- GuString s = gu_str_string("?", pool);
- ret = pgf_lzn_resolve_def(lzn, ccat->lindefs, s, pool);
- goto done;
+ GuString s = gu_str_string("?", pool);
+ ret = pgf_lzn_resolve_def(lzn, ccat->lindefs, s, pool);
+ goto done;
+ }
}
case PGF_EXPR_FUN: {
PgfExprFun* efun = i.data;
@@ -318,7 +359,7 @@ pgf_lzn_resolve(PgfLzn* lzn, PgfExpr expr, PgfCCat* ccat, GuPool* pool)
gu_putc('[', wtr, err);
gu_string_write(efun->fun, wtr, err);
gu_putc(']', wtr, err);
- GuString s = gu_string_buf_freeze(sbuf, tmp_pool);
+ GuString s = gu_string_buf_freeze(sbuf, pool);
ret = pgf_lzn_resolve_def(lzn, ccat->lindefs, s, pool);
@@ -399,23 +440,6 @@ pgf_lzr_concretize(PgfConcr* concr, PgfExpr expr, GuPool* pool)
return &lzn->en;
}
-int
-pgf_cnc_tree_dimension(PgfCncTree ctree)
-{
- GuVariantInfo cti = gu_variant_open(ctree);
- switch (cti.tag) {
- case PGF_CNC_TREE_LIT:
- return 1;
- case PGF_CNC_TREE_APP: {
- PgfCncTreeApp* fapp = cti.data;
- return fapp->fun->n_lins;
- }
- default:
- gu_impossible();
- return 0;
- }
-}
-
void
pgf_lzr_linearize(PgfConcr* concr, PgfCncTree ctree, size_t lin_idx, PgfLinFuncs** fnsp)
{
@@ -423,14 +447,6 @@ pgf_lzr_linearize(PgfConcr* concr, PgfCncTree ctree, size_t lin_idx, PgfLinFuncs
GuVariantInfo cti = gu_variant_open(ctree);
switch (cti.tag) {
- case PGF_CNC_TREE_LIT: {
- gu_require(lin_idx == 0);
- PgfCncTreeLit* flit = cti.data;
- if (fns->expr_literal) {
- fns->expr_literal(fnsp, flit->lit);
- }
- break;
- }
case PGF_CNC_TREE_APP: {
PgfCncTreeApp* fapp = cti.data;
PgfCncFun* fun = fapp->fun;
@@ -475,7 +491,23 @@ pgf_lzr_linearize(PgfConcr* concr, PgfCncTree ctree, size_t lin_idx, PgfLinFuncs
}
}
break;
- } // case PGF_CNC_TREE_APP
+ }
+ case PGF_CNC_TREE_CHUNKS: {
+ gu_require(lin_idx == 0);
+ PgfCncTreeChunks* fchunks = cti.data;
+ for (size_t i = 0; i < fchunks->n_args; i++) {
+ pgf_lzr_linearize(concr, fchunks->args[i], 0, fnsp);
+ }
+ break;
+ }
+ case PGF_CNC_TREE_LIT: {
+ gu_require(lin_idx == 0);
+ PgfCncTreeLit* flit = cti.data;
+ if (fns->expr_literal) {
+ fns->expr_literal(fnsp, flit->lit);
+ }
+ break;
+ }
default:
gu_impossible();
}
diff --git a/src/runtime/c/pgf/linearizer.h b/src/runtime/c/pgf/linearizer.h
index c3a1cc2ca..ce7e483b6 100644
--- a/src/runtime/c/pgf/linearizer.h
+++ b/src/runtime/c/pgf/linearizer.h
@@ -48,24 +48,6 @@ typedef GuEnum PgfCncTreeEnum;
PgfCncTreeEnum*
pgf_lzr_concretize(PgfConcr* concr, PgfExpr expr, GuPool* pool);
-/** @}
- *
- * @name Linearizing concrete syntax trees
- *
- * An individual concrete syntax tree has several different
- * linearizations, corresponding to the various fields and cases of
- * corresponding GF values. The number of these linearizations, called
- * the \e dimension of the tree, can be retrieved with
- * #pgf_cnc_tree_dimension.
- *
- * A single linearization of a concrete syntax tree is performed by
- * #pgf_lzr_linearize. The linearization is realized as a sequence of
- * events that are notified by calling the functions of a #PgfLinFuncs
- * structure that the client provides.
- *
- * @{
- */
-
/// Callback functions for linearization.
typedef struct PgfLinFuncs PgfLinFuncs;