aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/info/mds.texinfo5
-rw-r--r--src/mds-kbdc/simplify-tree.c88
-rw-r--r--src/mds-kbdc/tree.c5
-rw-r--r--src/mds-kbdc/tree.h22
4 files changed, 88 insertions, 32 deletions
diff --git a/doc/info/mds.texinfo b/doc/info/mds.texinfo
index 9dd851c..6f5e5f5 100644
--- a/doc/info/mds.texinfo
+++ b/doc/info/mds.texinfo
@@ -5456,7 +5456,10 @@ Thus, there should not be side-effects where
either one is used, nor does it make since
to nest the two constructs in any other
way than alternation or unordered subsequence
-inside unordered subsequence.
+inside unordered subsequence. The compiler
+may however choose to discourage unordered
+subsequence inside unordered subsequence
+because of readability issues.
diff --git a/src/mds-kbdc/simplify-tree.c b/src/mds-kbdc/simplify-tree.c
index f032dd6..7ca0729 100644
--- a/src/mds-kbdc/simplify-tree.c
+++ b/src/mds-kbdc/simplify-tree.c
@@ -286,7 +286,7 @@ static int simplify_alternation(mds_kbdc_tree_alternation_t* restrict tree)
else if (argument->type == MDS_KBDC_TREE_TYPE_ALTERNATION)
{
/* Alternation nesting. */
- NEW_ERROR(argument, WARNING, "alternation inside alternation is unnecessary");
+ NEW_ERROR(argument, WARNING, "alternation inside alternation is unnessary");
if (simplify_alternation(&(argument->alternation)))
return -1;
if (argument->type == MDS_KBDC_TREE_TYPE_ALTERNATION)
@@ -310,7 +310,59 @@ static int simplify_alternation(mds_kbdc_tree_alternation_t* restrict tree)
redo = 1;
}
- /* TODO unordered */
+ /* TODO unordered (warn: discouraged) */
+
+ return 0;
+ pfail:
+ return -1;
+}
+
+
+/**
+ * Simplify an unordered subsequence-subtree
+ *
+ * @param tree The unordered subsequence-subtree
+ * @return Zero on success, -1 on error
+ */
+static int simplify_unordered(mds_kbdc_tree_unordered_t* restrict tree)
+{
+ mds_kbdc_tree_t* argument;
+ mds_kbdc_tree_t* temp;
+ mds_kbdc_tree_t** here;
+
+ /* Test emptyness. */
+ if (tree->inner == NULL)
+ {
+ NEW_ERROR(tree, ERROR, "empty unordered subsequence");
+ tree->type = MDS_KBDC_TREE_TYPE_NOTHING;
+ tree->processed = PROCESS_LEVEL;
+ return 0;
+ }
+
+ /* Test singletonness. */
+ if (tree->inner->next == NULL)
+ {
+ temp = tree->inner;
+ NEW_ERROR(tree, WARNING, "singleton unordered subsequence");
+ memcpy(tree, temp, sizeof(mds_kbdc_tree_t));
+ free(temp);
+ return simplify((mds_kbdc_tree_t*)tree);
+ }
+
+ /* Remove ‘.’:s. */
+ for (here = &(tree->inner); *here;)
+ if ((*here)->type != MDS_KBDC_TREE_TYPE_NOTHING)
+ here = &((*here)->next);
+ else
+ while (*here && (*here)->type == MDS_KBDC_TREE_TYPE_NOTHING)
+ {
+ argument = (*here)->next, (*here)->next = NULL;
+ NEW_ERROR(*here, WARNING, "‘.’ inside unordered subsequences has no effect");
+ mds_kbdc_tree_free(*here);
+ *here = argument;
+ }
+
+ /* TODO alternation, unordered (warn: unreadable) */
return 0;
pfail:
@@ -326,7 +378,8 @@ static int simplify_alternation(mds_kbdc_tree_alternation_t* restrict tree)
*/
static int simplify(mds_kbdc_tree_t* restrict tree)
{
-#define s(expr) if ((r = simplify(tree->expr))) return r;
+#define s(expr) if ((r = simplify(tree->expr))) return r
+#define S(type) if ((r = simplify_##type(&(tree->type)))) return r
int r;
again:
if (tree == NULL)
@@ -339,29 +392,11 @@ static int simplify(mds_kbdc_tree_t* restrict tree)
case MDS_KBDC_TREE_TYPE_MACRO: s (macro.inner); break;
case MDS_KBDC_TREE_TYPE_ASSUMPTION: s (assumption.inner); break;
case MDS_KBDC_TREE_TYPE_FOR: s (for_.inner); break;
- case MDS_KBDC_TREE_TYPE_IF:
- s (if_.inner);
- s (if_.otherwise);
- break;
-
- case MDS_KBDC_TREE_TYPE_MAP:
- /* TODO */
- break;
-
- case MDS_KBDC_TREE_TYPE_ALTERNATION:
- if ((r = simplify_alternation(&(tree->alternation))))
- return r;
- break;
-
- case MDS_KBDC_TREE_TYPE_UNORDERED:
- /* TODO find alternation and nothing, find singletons, error if empty, unordered */
- break;
-
- case MDS_KBDC_TREE_TYPE_MACRO_CALL:
- if ((r = simplify_macro_call(&(tree->macro_call))))
- return r;
- break;
-
+ case MDS_KBDC_TREE_TYPE_IF: s (if_.inner); s (if_.otherwise); break;
+ case MDS_KBDC_TREE_TYPE_MAP: /* TODO */ break;
+ case MDS_KBDC_TREE_TYPE_ALTERNATION: S (alternation); break;
+ case MDS_KBDC_TREE_TYPE_UNORDERED: S (unordered); break;
+ case MDS_KBDC_TREE_TYPE_MACRO_CALL: S (macro_call); break;
default:
break;
}
@@ -369,6 +404,7 @@ static int simplify(mds_kbdc_tree_t* restrict tree)
tree = tree->next;
goto again;
#undef s
+#undef S
}
diff --git a/src/mds-kbdc/tree.c b/src/mds-kbdc/tree.c
index 5d00601..1e7dc07 100644
--- a/src/mds-kbdc/tree.c
+++ b/src/mds-kbdc/tree.c
@@ -80,6 +80,7 @@ static void mds_kbdc_tree_destroy_(mds_kbdc_tree_t* restrict this, int recursive
case C(ASSUMPTION):
case C(ALTERNATION):
case C(UNORDERED):
+ case C(ORDERED):
xdestroy(struct mds_kbdc_tree_nesting*, inner);
break;
@@ -285,7 +286,8 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(mds_kbdc_tree_t* restrict this)
case C(INFORMATION):
case C(ASSUMPTION):
case C(ALTERNATION):
- case C(UNORDERED): { NODE(nesting); T(inner); } break;
+ case C(UNORDERED):
+ case C(ORDERED): { NODE(nesting); T(inner); } break;
case C(FUNCTION):
case C(MACRO): { NODE(callable); S(name);T(inner); } break;
case C(ASSUMPTION_HAVE): { NODE(assumption_have); T(data); } break;
@@ -510,6 +512,7 @@ static void mds_kbdc_tree_print_indented(mds_kbdc_tree_t* restrict this, FILE* o
case C(NOTHING): NOTHING("nothing");
case C(ALTERNATION): NESTING(alternation, "alternation", inner);
case C(UNORDERED): NESTING(unordered, "unordered", inner);
+ case C(ORDERED): NESTING(ordered, "ordered", inner);
case C(MACRO_CALL): NAMED_NESTING(macro_call, "macro_call", name, arguments);
case C(RETURN): NOTHING("return");
case C(BREAK): NOTHING("break");
diff --git a/src/mds-kbdc/tree.h b/src/mds-kbdc/tree.h
index e529dfc..8354744 100644
--- a/src/mds-kbdc/tree.h
+++ b/src/mds-kbdc/tree.h
@@ -131,24 +131,29 @@
#define MDS_KBDC_TREE_TYPE_UNORDERED 20
/**
+ * Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_ordered_t`
+ */
+#define MDS_KBDC_TREE_TYPE_ORDERED 21
+
+/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_macro_call_t`
*/
-#define MDS_KBDC_TREE_TYPE_MACRO_CALL 21
+#define MDS_KBDC_TREE_TYPE_MACRO_CALL 22
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_return_t`
*/
-#define MDS_KBDC_TREE_TYPE_RETURN 22
+#define MDS_KBDC_TREE_TYPE_RETURN 23
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_break_t`
*/
-#define MDS_KBDC_TREE_TYPE_BREAK 23
+#define MDS_KBDC_TREE_TYPE_BREAK 24
/**
* Value of `mds_kbdc_tree_t.type` for `mds_kbdc_tree_continue_t`
*/
-#define MDS_KBDC_TREE_TYPE_CONTINUE 24
+#define MDS_KBDC_TREE_TYPE_CONTINUE 25
@@ -576,6 +581,14 @@ typedef struct mds_kbdc_tree_nesting mds_kbdc_tree_alternation_t;
*/
typedef struct mds_kbdc_tree_nesting mds_kbdc_tree_unordered_t;
+/**
+ * Tree structure for an ordered sequence
+ *
+ * This is intended has an auxiliary type for
+ * simplifying trees
+ */
+typedef struct mds_kbdc_tree_nesting mds_kbdc_tree_ordered_t;
+
/**
* Tree structure for a macro call
@@ -653,6 +666,7 @@ union mds_kbdc_tree
mds_kbdc_tree_nothing_t nothing;
mds_kbdc_tree_alternation_t alternation;
mds_kbdc_tree_unordered_t unordered;
+ mds_kbdc_tree_ordered_t ordered;
mds_kbdc_tree_macro_call_t macro_call;
mds_kbdc_tree_return_t return_;
mds_kbdc_tree_break_t break_;