diff options
Diffstat (limited to '')
-rw-r--r-- | src/mds-kbdc/tree.c | 731 |
1 files changed, 394 insertions, 337 deletions
diff --git a/src/mds-kbdc/tree.c b/src/mds-kbdc/tree.c index 289ccac..33db89e 100644 --- a/src/mds-kbdc/tree.c +++ b/src/mds-kbdc/tree.c @@ -36,7 +36,7 @@ typedef struct mds_kbdc_tree_information_data mds_kbdc_tree_information_data_t; /** * Tree type constant shortener */ -#define C(t) MDS_KBDC_TREE_TYPE_##t +#define C(t) MDS_KBDC_TREE_TYPE_##t /** @@ -45,10 +45,11 @@ typedef struct mds_kbdc_tree_information_data mds_kbdc_tree_information_data_t; * @param this The memory slot for the tree node * @param type The type of the node */ -void mds_kbdc_tree_initialise(mds_kbdc_tree_t* restrict this, int type) +void +mds_kbdc_tree_initialise(mds_kbdc_tree_t *restrict this, int type) { - memset(this, 0, sizeof(mds_kbdc_tree_t)); - this->type = type; + memset(this, 0, sizeof(mds_kbdc_tree_t)); + this->type = type; } @@ -58,14 +59,15 @@ void mds_kbdc_tree_initialise(mds_kbdc_tree_t* restrict this, int type) * @param type The type of the node * @return The tree node, `NULL` on error */ -mds_kbdc_tree_t* mds_kbdc_tree_create(int type) +mds_kbdc_tree_t * +mds_kbdc_tree_create(int type) { - mds_kbdc_tree_t* this; - fail_if (xmalloc(this, 1, mds_kbdc_tree_t)); - mds_kbdc_tree_initialise(this, type); - return this; - fail: - return NULL; + mds_kbdc_tree_t *this; + fail_if (xmalloc(this, 1, mds_kbdc_tree_t)); + mds_kbdc_tree_initialise(this, type); + return this; +fail: + return NULL; } @@ -75,110 +77,109 @@ mds_kbdc_tree_t* mds_kbdc_tree_create(int type) * @param this The tree node * @param recursive Whether subtree should be destroyed and freed */ -static void mds_kbdc_tree_destroy_(mds_kbdc_tree_t* restrict this, int recursive) +static void mds_kbdc_tree_destroy_(mds_kbdc_tree_t *restrict this, int recursive) { -#define V(type, var) (((type)this)->var) -#define xfree(t, v) (free(V(t, v)), V(t, v) = NULL) -#define xdestroy(t, v) (recursive ? (mds_kbdc_tree_destroy_(V(t, v), 1), xfree(t, v)) : (V(t, v) = NULL)) - - mds_kbdc_tree_t* prev = NULL; - mds_kbdc_tree_t* first = this; - - again: - if (this == NULL) - return; - - switch (this->type) - { - case C(INFORMATION): - case C(ASSUMPTION): - case C(ALTERNATION): - case C(UNORDERED): - case C(ORDERED): - xdestroy(mds_kbdc_tree_nesting_t*, inner); - break; - - case C(INFORMATION_LANGUAGE): - case C(INFORMATION_COUNTRY): - case C(INFORMATION_VARIANT): - xfree(mds_kbdc_tree_information_data_t*, data); - break; - - case C(FUNCTION): - case C(MACRO): - xfree(mds_kbdc_tree_callable_t*, name); - xdestroy(mds_kbdc_tree_callable_t*, inner); - break; - - case C(INCLUDE): - xfree(mds_kbdc_tree_include_t*, filename); - xdestroy(mds_kbdc_tree_include_t*, inner); - mds_kbdc_source_code_free(this->include.source_code); - break; - - case C(ASSUMPTION_HAVE): - xdestroy(mds_kbdc_tree_assumption_have_t*, data); - break; - - case C(ASSUMPTION_HAVE_CHARS): - xfree(mds_kbdc_tree_assumption_have_chars_t*, chars); - break; - - case C(ASSUMPTION_HAVE_RANGE): - xfree(mds_kbdc_tree_assumption_have_range_t*, first); - xfree(mds_kbdc_tree_assumption_have_range_t*, last); - break; - - case C(FOR): - xfree(mds_kbdc_tree_for_t*, first); - xfree(mds_kbdc_tree_for_t*, last); - xfree(mds_kbdc_tree_for_t*, variable); - xdestroy(mds_kbdc_tree_for_t*, inner); - break; - - case C(IF): - xfree(mds_kbdc_tree_if_t*, condition); - xdestroy(mds_kbdc_tree_if_t*, inner); - xdestroy(mds_kbdc_tree_if_t*, otherwise); - break; - - case C(LET): - xfree(mds_kbdc_tree_let_t*, variable); - xdestroy(mds_kbdc_tree_let_t*, value); - break; - - case C(MAP): - xdestroy(mds_kbdc_tree_map_t*, sequence); - xdestroy(mds_kbdc_tree_map_t*, result); - break; - - case C(ARRAY): - xdestroy(mds_kbdc_tree_array_t*, elements); - break; - - case C(KEYS): - case C(STRING): - case C(COMPILED_KEYS): - case C(COMPILED_STRING): - xfree(mds_kbdc_tree_keys_t*, keys); - /* We are abusing the similaries of the structures. */ - break; - - case C(MACRO_CALL): - xfree(mds_kbdc_tree_macro_call_t*, name); - xdestroy(mds_kbdc_tree_macro_call_t*, arguments); - break; - - default: - break; - } - - prev = this; - this = this->next; - if (prev != first) - free(prev); - goto again; - +#define V(type, var) (((type)this)->var) +#define xfree(t, v) (free(V(t, v)), V(t, v) = NULL) +#define xdestroy(t, v) (recursive ? (mds_kbdc_tree_destroy_(V(t, v), 1), xfree(t, v)) : (V(t, v) = NULL)) + + mds_kbdc_tree_t *prev = NULL; + mds_kbdc_tree_t *first = this; + +again: + if (!this) + return; + + switch (this->type) { + case C(INFORMATION): + case C(ASSUMPTION): + case C(ALTERNATION): + case C(UNORDERED): + case C(ORDERED): + xdestroy(mds_kbdc_tree_nesting_t *, inner); + break; + + case C(INFORMATION_LANGUAGE): + case C(INFORMATION_COUNTRY): + case C(INFORMATION_VARIANT): + xfree(mds_kbdc_tree_information_data_t *, data); + break; + + case C(FUNCTION): + case C(MACRO): + xfree(mds_kbdc_tree_callable_t *, name); + xdestroy(mds_kbdc_tree_callable_t *, inner); + break; + + case C(INCLUDE): + xfree(mds_kbdc_tree_include_t *, filename); + xdestroy(mds_kbdc_tree_include_t *, inner); + mds_kbdc_source_code_free(this->include.source_code); + break; + + case C(ASSUMPTION_HAVE): + xdestroy(mds_kbdc_tree_assumption_have_t *, data); + break; + + case C(ASSUMPTION_HAVE_CHARS): + xfree(mds_kbdc_tree_assumption_have_chars_t *, chars); + break; + + case C(ASSUMPTION_HAVE_RANGE): + xfree(mds_kbdc_tree_assumption_have_range_t *, first); + xfree(mds_kbdc_tree_assumption_have_range_t *, last); + break; + + case C(FOR): + xfree(mds_kbdc_tree_for_t *, first); + xfree(mds_kbdc_tree_for_t *, last); + xfree(mds_kbdc_tree_for_t *, variable); + xdestroy(mds_kbdc_tree_for_t *, inner); + break; + + case C(IF): + xfree(mds_kbdc_tree_if_t *, condition); + xdestroy(mds_kbdc_tree_if_t *, inner); + xdestroy(mds_kbdc_tree_if_t *, otherwise); + break; + + case C(LET): + xfree(mds_kbdc_tree_let_t *, variable); + xdestroy(mds_kbdc_tree_let_t *, value); + break; + + case C(MAP): + xdestroy(mds_kbdc_tree_map_t *, sequence); + xdestroy(mds_kbdc_tree_map_t *, result); + break; + + case C(ARRAY): + xdestroy(mds_kbdc_tree_array_t *, elements); + break; + + case C(KEYS): + case C(STRING): + case C(COMPILED_KEYS): + case C(COMPILED_STRING): + xfree(mds_kbdc_tree_keys_t *, keys); + /* We are abusing the similaries of the structures. */ + break; + + case C(MACRO_CALL): + xfree(mds_kbdc_tree_macro_call_t *, name); + xdestroy(mds_kbdc_tree_macro_call_t *, arguments); + break; + + default: + break; + } + + prev = this; + this = this->next; + if (prev != first) + free(prev); + goto again; + #undef xdestroy #undef xfree #undef V @@ -192,9 +193,10 @@ static void mds_kbdc_tree_destroy_(mds_kbdc_tree_t* restrict this, int recursive * * @param this The tree node */ -void mds_kbdc_tree_destroy_nonrecursive(mds_kbdc_tree_t* restrict this) +void +mds_kbdc_tree_destroy_nonrecursive(mds_kbdc_tree_t *restrict this) { - mds_kbdc_tree_destroy_(this, 0); + mds_kbdc_tree_destroy_(this, 0); } @@ -206,10 +208,11 @@ void mds_kbdc_tree_destroy_nonrecursive(mds_kbdc_tree_t* restrict this) * * @param this The tree node */ -void mds_kbdc_tree_free_nonrecursive(mds_kbdc_tree_t* restrict this) +void +mds_kbdc_tree_free_nonrecursive(mds_kbdc_tree_t *restrict this) { - mds_kbdc_tree_destroy_nonrecursive(this); - free(this); + mds_kbdc_tree_destroy_nonrecursive(this); + free(this); } @@ -220,9 +223,10 @@ void mds_kbdc_tree_free_nonrecursive(mds_kbdc_tree_t* restrict this) * * @param this The tree node */ -void mds_kbdc_tree_destroy(mds_kbdc_tree_t* restrict this) +void +mds_kbdc_tree_destroy(mds_kbdc_tree_t *restrict this) { - mds_kbdc_tree_destroy_(this, 1); + mds_kbdc_tree_destroy_(this, 1); } @@ -233,10 +237,11 @@ void mds_kbdc_tree_destroy(mds_kbdc_tree_t* restrict this) * * @param this The tree node */ -void mds_kbdc_tree_free(mds_kbdc_tree_t* restrict this) +void +mds_kbdc_tree_free(mds_kbdc_tree_t *restrict this) { - mds_kbdc_tree_destroy(this); - free(this); + mds_kbdc_tree_destroy(this); + free(this); } @@ -246,7 +251,7 @@ void mds_kbdc_tree_free(mds_kbdc_tree_t* restrict this) * * @param member:identifer The member in the tree to duplicate */ -#define T(member) fail_if (t->member && (n->member = mds_kbdc_tree_dup(t->member), n->member == NULL)) +#define T(member) fail_if (t->member && !(n->member = mds_kbdc_tree_dup(t->member))) /** @@ -254,7 +259,7 @@ void mds_kbdc_tree_free(mds_kbdc_tree_t* restrict this) * * @param member:identifer The member in the tree to duplicate */ -#define S(member) fail_if (t->member && xstrdup(n->member, t->member)) +#define S(member) fail_if (t->member && xstrdup(n->member, t->member)) /** @@ -262,7 +267,7 @@ void mds_kbdc_tree_free(mds_kbdc_tree_t* restrict this) * * @param member:identifer The member in the tree to duplicate */ -#define Z(member) fail_if (t->member && (n->member = string_dup(t->member), n->member == NULL)) +#define Z(member) fail_if (t->member && !(n->member = string_dup(t->member))) /** @@ -270,7 +275,7 @@ void mds_kbdc_tree_free(mds_kbdc_tree_t* restrict this) * * @param member:identifer The member in the tree to copied */ -#define R(member) fail_if (t->member && (n->member = mds_kbdc_source_code_dup(t->member), n->member == NULL)) +#define R(member) fail_if (t->member && !(n->member = mds_kbdc_source_code_dup(t->member))) @@ -280,62 +285,109 @@ void mds_kbdc_tree_free(mds_kbdc_tree_t* restrict this) * @param this The tree node * @return A duplicate of `this`, `NULL` on error */ -mds_kbdc_tree_t* mds_kbdc_tree_dup(const mds_kbdc_tree_t* restrict this) +mds_kbdc_tree_t * +mds_kbdc_tree_dup(const mds_kbdc_tree_t *restrict this) { -#define t this -#define n (*node) - mds_kbdc_tree_t* rc = NULL; - mds_kbdc_tree_t** node = &rc; - int saved_errno; - - again: - if (t == NULL) return rc; - fail_if (xcalloc(n, 1, mds_kbdc_tree_t)); +#define t this +#define n (*node) + mds_kbdc_tree_t *rc = NULL; + mds_kbdc_tree_t **node = &rc; + int saved_errno; + +again: + if (!t) + return rc; + fail_if (xcalloc(n, 1, mds_kbdc_tree_t)); + + n->type = t->type; + n->loc_line = t->loc_line; + n->loc_start = t->loc_start; + n->loc_end = t->loc_end; + n->processed = t->processed; + + switch (this->type) { + case C(INFORMATION): + case C(ASSUMPTION): + case C(ALTERNATION): + case C(UNORDERED): + case C(ORDERED): + T(ordered.inner); + break; + case C(FUNCTION): + case C(MACRO): + S(macro.name); + T(macro.inner); + break; + case C(ASSUMPTION_HAVE): + T(have.data); + break; + case C(ARRAY): + T(array.elements); + break; + case C(LET): + S(let.variable); + T(let.value); + break; + case C(MACRO_CALL): + S(macro_call.name); + T(macro_call.arguments); + break; + case C(INFORMATION_LANGUAGE): + case C(INFORMATION_COUNTRY): + case C(INFORMATION_VARIANT): + S(variant.data); + break; + case C(INCLUDE): + S(include.filename); + T(include.inner); + R(include.source_code); + break; + case C(ASSUMPTION_HAVE_CHARS): + S(have_chars.chars); + break; + case C(KEYS): + S(keys.keys); + break; + case C(STRING): + S(string.string); + break; + case C(COMPILED_KEYS): + Z(compiled_keys.keys); + break; + case C(COMPILED_STRING): + Z(compiled_string.string); + break; + case C(ASSUMPTION_HAVE_RANGE): + S(have_range.first); + S(have_range.last); + break; + case C(FOR): + S(for_.first); + S(for_.last); + S(for_.variable); + T(for_.inner); + break; + case C(IF): + S(if_.condition); + T(if_.inner); + T(if_.otherwise); + break; + case C(MAP): + T(map.sequence); + T(map.result); + break; + default: + break; + } + + t = t->next; + node = &(n->next); + goto again; - n->type = t->type; - n->loc_line = t->loc_line; - n->loc_start = t->loc_start; - n->loc_end = t->loc_end; - n->processed = t->processed; - - switch (this->type) - { - case C(INFORMATION): - case C(ASSUMPTION): - case C(ALTERNATION): - case C(UNORDERED): - case C(ORDERED): T(ordered.inner); break; - case C(FUNCTION): - case C(MACRO): S(macro.name); T(macro.inner); break; - case C(ASSUMPTION_HAVE): T(have.data); break; - case C(ARRAY): T(array.elements); break; - case C(LET): S(let.variable); T(let.value); break; - case C(MACRO_CALL): S(macro_call.name); T(macro_call.arguments); break; - case C(INFORMATION_LANGUAGE): - case C(INFORMATION_COUNTRY): - case C(INFORMATION_VARIANT): S(variant.data); break; - case C(INCLUDE): S(include.filename); T(include.inner); R(include.source_code); break; - case C(ASSUMPTION_HAVE_CHARS): S(have_chars.chars); break; - case C(KEYS): S(keys.keys); break; - case C(STRING): S(string.string); break; - case C(COMPILED_KEYS): Z(compiled_keys.keys); break; - case C(COMPILED_STRING): Z(compiled_string.string); break; - case C(ASSUMPTION_HAVE_RANGE): S(have_range.first); S(have_range.last); break; - case C(FOR): S(for_.first); S(for_.last); S(for_.variable); T(for_.inner); break; - case C(IF): S(if_.condition); T(if_.inner); T(if_.otherwise); break; - case C(MAP): T(map.sequence); T(map.result); break; - default: - break; - } - - t = t->next; - node = &(n->next); - goto again; - - fail: - saved_errno = errno; - mds_kbdc_tree_free(rc); - return errno = saved_errno, NULL; +fail: + saved_errno = errno; + mds_kbdc_tree_free(rc); + return errno = saved_errno, NULL; #undef n #undef t } @@ -355,12 +407,12 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(const mds_kbdc_tree_t* restrict this) * @param LOWERCASE:identifer The name of subtype * @param NOTATION:const char* The notation for the subtype */ -#define NODE(LOWERCASE, NOTATION) \ - const mds_kbdc_tree_##LOWERCASE##_t* node; \ - node = (const mds_kbdc_tree_##LOWERCASE##_t*)this; \ - fprintf(output, "%*.s(\033[01m%s\033[00m", indent, "", NOTATION); \ - fprintf(output, " \033[36m(@ %zu %zu-%zu)\033[00m", \ - node->loc_line + 1, node->loc_start, node->loc_end) +#define NODE(LOWERCASE, NOTATION)\ + const mds_kbdc_tree_##LOWERCASE##_t *node;\ + node = (const mds_kbdc_tree_##LOWERCASE##_t *)this;\ + fprintf(output, "%*.s(\033[01m%s\033[00m", indent, "", NOTATION);\ + fprintf(output, " \033[36m(@ %zu %zu-%zu)\033[00m",\ + node->loc_line + 1, node->loc_start, node->loc_end) /** @@ -368,22 +420,23 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(const mds_kbdc_tree_t* restrict this) * * @param MEMBER:identifier The tree structure's member */ -#define BRANCH(MEMBER) \ - if (node->MEMBER) \ - { \ - fprintf(output, "\n%*.s(.%s\n", indent + 2, "", #MEMBER); \ - mds_kbdc_tree_print_indented(node->MEMBER, output, indent + 4); \ - fprintf(output, "%*.s)", indent + 2, ""); \ - } \ - else \ - fprintf(output, "\n%*.s(.%s \033[35mnil\033[00m)", indent + 2, "", #MEMBER) +#define BRANCH(MEMBER)\ + do {\ + if (node->MEMBER) {\ + fprintf(output, "\n%*.s(.%s\n", indent + 2, "", #MEMBER);\ + mds_kbdc_tree_print_indented(node->MEMBER, output, indent + 4);\ + fprintf(output, "%*.s)", indent + 2, "");\ + } else {\ + fprintf(output, "\n%*.s(.%s \033[35mnil\033[00m)", indent + 2, "", #MEMBER);\ + }\ + } while (0) /** * End a tree which has at least one member that is a subtree */ -#define COMPLEX \ - fprintf(output, "\n%*.s)\n", indent, "") +#define COMPLEX\ + fprintf(output, "\n%*.s)\n", indent, "") /** @@ -391,11 +444,13 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(const mds_kbdc_tree_t* restrict this) * * @param MEMBER:identifier The tree structure's member */ -#define STRING(MEMBER) \ - if (node->MEMBER) \ - fprintf(output, " ‘\033[32m%s\033[00m’", node->MEMBER); \ - else \ - fprintf(output, " \033[35mnil\033[00m") +#define STRING(MEMBER)\ + do {\ + if (node->MEMBER)\ + fprintf(output, " ‘\033[32m%s\033[00m’", node->MEMBER);\ + else\ + fprintf(output, " \033[35mnil\033[00m");\ + } while (0) /** @@ -404,9 +459,11 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(const mds_kbdc_tree_t* restrict this) * * @param MEMBER:identifier The tree structure's member */ -#define SIMPLE(MEMBER) \ - STRING(MEMBER); \ - fprintf(output, ")\n") +#define SIMPLE(MEMBER)\ + do {\ + STRING(MEMBER);\ + fprintf(output, ")\n");\ + } while (0) /** @@ -417,12 +474,12 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(const mds_kbdc_tree_t* restrict this) * @param NOTATION:const char* See `NODE` * @param MEMBER:identifier See `STRING` */ -#define SIMPLEX(LOWERCASE, NOTATION, MEMBER) \ - { \ - NODE(LOWERCASE, NOTATION); \ - SIMPLE(MEMBER); \ - } \ - break +#define SIMPLEX(LOWERCASE, NOTATION, MEMBER)\ + {\ + NODE(LOWERCASE, NOTATION);\ + SIMPLE(MEMBER);\ + }\ + break /** @@ -434,13 +491,13 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(const mds_kbdc_tree_t* restrict this) * @param FIRST:identifier See `STRING`, the first member * @param LAST:identifier See `STRING`, the second member */ -#define DUPLEX(LOWERCASE, NOTATION, FIRST, LAST) \ - { \ - NODE(LOWERCASE, NOTATION); \ - STRING(FIRST); \ - SIMPLE(LAST); \ - } \ - break +#define DUPLEX(LOWERCASE, NOTATION, FIRST, LAST)\ + {\ + NODE(LOWERCASE, NOTATION);\ + STRING(FIRST);\ + SIMPLE(LAST);\ + }\ + break /** @@ -451,13 +508,13 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(const mds_kbdc_tree_t* restrict this) * @param NOTATION:const char* See `NODE` * @param MEMBER:identifier See `BRANCH` */ -#define NESTING(LOWERCASE, NOTATION, MEMBER) \ - { \ - NODE(LOWERCASE, NOTATION); \ - BRANCH(MEMBER); \ - COMPLEX; \ - } \ - break +#define NESTING(LOWERCASE, NOTATION, MEMBER)\ + {\ + NODE(LOWERCASE, NOTATION);\ + BRANCH(MEMBER);\ + COMPLEX;\ + }\ + break /** @@ -470,14 +527,14 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(const mds_kbdc_tree_t* restrict this) * @param NAMER:identifier See `STRING` * @param MEMBER:identifier See `BRANCH` */ -#define NAMED_NESTING(LOWERCASE, NOTATION, NAMER, MEMBER) \ - { \ - NODE(LOWERCASE, NOTATION); \ - STRING(NAMER); \ - BRANCH(MEMBER); \ - COMPLEX; \ - } \ - break +#define NAMED_NESTING(LOWERCASE, NOTATION, NAMER, MEMBER)\ + {\ + NODE(LOWERCASE, NOTATION);\ + STRING(NAMER);\ + BRANCH(MEMBER);\ + COMPLEX;\ + }\ + break /** @@ -485,12 +542,12 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(const mds_kbdc_tree_t* restrict this) * * @param NOTATION:const char* See `NODE` */ -#define NOTHING(NOTATION) \ - fprintf(output, "%*.s(\033[01m%s\033[00m", indent, "", NOTATION); \ - fprintf(output, " \033[36m(@ %zu %zu-%zu)\033[00m", \ - this->loc_line + 1, this->loc_start, this->loc_end); \ - fprintf(output, ")\n"); \ - break +#define NOTHING(NOTATION)\ + fprintf(output, "%*.s(\033[01m%s\033[00m", indent, "", NOTATION);\ + fprintf(output, " \033[36m(@ %zu %zu-%zu)\033[00m",\ + this->loc_line + 1, this->loc_start, this->loc_end);\ + fprintf(output, ")\n");\ + break @@ -501,100 +558,100 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(const mds_kbdc_tree_t* restrict this) * @param output The output file * @param indent The indent */ -static void mds_kbdc_tree_print_indented(const mds_kbdc_tree_t* restrict this, FILE* output, int indent) +static void +mds_kbdc_tree_print_indented(const mds_kbdc_tree_t *restrict this, FILE *output, int indent) { - again: - if (this == NULL) - return; - - switch (this->type) - { - /* These have their break built into their macro. */ - case C(INFORMATION): NESTING(information, "information", inner); - case C(INFORMATION_LANGUAGE): SIMPLEX(information_language, "language", data); - case C(INFORMATION_COUNTRY): SIMPLEX(information_country, "country", data); - case C(INFORMATION_VARIANT): SIMPLEX(information_variant, "variant", data); - case C(INCLUDE): NAMED_NESTING(include, "include", filename, inner); - case C(FUNCTION): NAMED_NESTING(function, "function", name, inner); - case C(MACRO): NAMED_NESTING(macro, "macro", name, inner); - case C(ASSUMPTION): NESTING(assumption, "assumption", inner); - case C(ASSUMPTION_HAVE): NESTING(assumption_have, "have", data); - case C(ASSUMPTION_HAVE_CHARS): SIMPLEX(assumption_have_chars, "have_chars", chars); - case C(ASSUMPTION_HAVE_RANGE): DUPLEX(assumption_have_range, "have_range", first, last); - case C(LET): NAMED_NESTING(let, "let", variable, value); - case C(ARRAY): NESTING(array, "array", elements); - case C(KEYS): SIMPLEX(keys, "keys", keys); - case C(STRING): SIMPLEX(string, "string", string); - 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"); - case C(CONTINUE): NOTHING("continue"); - - case C(COMPILED_KEYS): - { - NODE(compiled_keys, "compiled_keys"); - if (node->keys) - fprintf(output, " ‘\033[32m%s\033[00m’", string_encode(node->keys)); - else - fprintf(output, " \033[35mnil\033[00m"); - fprintf(output, ")\n"); - } - break; - - case C(COMPILED_STRING): - { - NODE(compiled_string, "compiled_string"); - if (node->string) - fprintf(output, " ‘\033[32m%s\033[00m’", string_encode(node->string)); - else - fprintf(output, " \033[35mnil\033[00m"); - fprintf(output, ")\n"); - } - break; - - case C(FOR): - { - NODE(for, "for"); - STRING(first); - STRING(last); - fprintf(output, " (.variable"); - STRING(variable); - fprintf(output, ")"); - BRANCH(inner); - COMPLEX; - } - break; - - case C(IF): - { - NODE(if, "if"); - STRING(condition); - BRANCH(inner); - BRANCH(otherwise); - COMPLEX; - } - break; - - case C(MAP): - { - NODE(map, "map"); - BRANCH(sequence); - BRANCH(result); - COMPLEX; - } - break; - - default: - abort(); - break; - } - - this = this->next; - goto again; +again: + if (!this) + return; + + switch (this->type) { + /* These have their break built into their macro. */ + case C(INFORMATION): NESTING(information, "information", inner); + case C(INFORMATION_LANGUAGE): SIMPLEX(information_language, "language", data); + case C(INFORMATION_COUNTRY): SIMPLEX(information_country, "country", data); + case C(INFORMATION_VARIANT): SIMPLEX(information_variant, "variant", data); + case C(INCLUDE): NAMED_NESTING(include, "include", filename, inner); + case C(FUNCTION): NAMED_NESTING(function, "function", name, inner); + case C(MACRO): NAMED_NESTING(macro, "macro", name, inner); + case C(ASSUMPTION): NESTING(assumption, "assumption", inner); + case C(ASSUMPTION_HAVE): NESTING(assumption_have, "have", data); + case C(ASSUMPTION_HAVE_CHARS): SIMPLEX(assumption_have_chars, "have_chars", chars); + case C(ASSUMPTION_HAVE_RANGE): DUPLEX(assumption_have_range, "have_range", first, last); + case C(LET): NAMED_NESTING(let, "let", variable, value); + case C(ARRAY): NESTING(array, "array", elements); + case C(KEYS): SIMPLEX(keys, "keys", keys); + case C(STRING): SIMPLEX(string, "string", string); + 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"); + case C(CONTINUE): NOTHING("continue"); + + case C(COMPILED_KEYS): + { + NODE(compiled_keys, "compiled_keys"); + if (node->keys) + fprintf(output, " ‘\033[32m%s\033[00m’", string_encode(node->keys)); + else + fprintf(output, " \033[35mnil\033[00m"); + fprintf(output, ")\n"); + } + break; + + case C(COMPILED_STRING): + { + NODE(compiled_string, "compiled_string"); + if (node->string) + fprintf(output, " ‘\033[32m%s\033[00m’", string_encode(node->string)); + else + fprintf(output, " \033[35mnil\033[00m"); + fprintf(output, ")\n"); + } + break; + + case C(FOR): + { + NODE(for, "for"); + STRING(first); + STRING(last); + fprintf(output, " (.variable"); + STRING(variable); + fprintf(output, ")"); + BRANCH(inner); + COMPLEX; + } + break; + + case C(IF): + { + NODE(if, "if"); + STRING(condition); + BRANCH(inner); + BRANCH(otherwise); + COMPLEX; + } + break; + + case C(MAP): + { + NODE(map, "map"); + BRANCH(sequence); + BRANCH(result); + COMPLEX; + } + break; + + default: + abort(); + break; + } + + this = this->next; + goto again; } @@ -604,9 +661,10 @@ static void mds_kbdc_tree_print_indented(const mds_kbdc_tree_t* restrict this, F * @param this The tree node * @param output The output file */ -void mds_kbdc_tree_print(const mds_kbdc_tree_t* restrict this, FILE* output) +void +mds_kbdc_tree_print(const mds_kbdc_tree_t *restrict this, FILE *output) { - mds_kbdc_tree_print_indented(this, output, 0); + mds_kbdc_tree_print_indented(this, output, 0); } @@ -622,4 +680,3 @@ void mds_kbdc_tree_print(const mds_kbdc_tree_t* restrict this, FILE* output) #undef NODE #undef C - |