diff options
-rw-r--r-- | doc/info/mds.texinfo | 5 | ||||
-rw-r--r-- | src/mds-kbdc/simplify-tree.c | 88 | ||||
-rw-r--r-- | src/mds-kbdc/tree.c | 5 | ||||
-rw-r--r-- | src/mds-kbdc/tree.h | 22 |
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_; |