diff options
9 files changed, 66 insertions, 19 deletions
diff --git a/src/mds-kbdc/compile-layout.c b/src/mds-kbdc/compile-layout.c index 75b134d..a8b20eb 100644 --- a/src/mds-kbdc/compile-layout.c +++ b/src/mds-kbdc/compile-layout.c @@ -17,6 +17,7 @@ */ #include "compile-layout.h" /* TODO add call stack */ +/* TODO fix so that for-loops do not generate the same errors/warnings in all iterations. */ #include "include-stack.h" #include "builtin-functions.h" @@ -418,7 +419,8 @@ static char32_t* parse_function_call(mds_kbdc_tree_t* restrict tree, const char* else { *end = --bracket; - NEW_ERROR(tree, ERROR, "invalid escape"); + if (tree->processed != PROCESS_LEVEL) + NEW_ERROR(tree, ERROR, "invalid escape"); goto error; } @@ -964,7 +966,7 @@ static char32_t* parse_keys(mds_kbdc_tree_t* restrict tree, const char* restrict STORE; escape = 1; } - else if (c == ',') + else if (c == ',') /* TODO must handle " too */ { /* Include commas as (1 << 31) ^ 1 (above 2³¹, yet guaranteed not to be -1). */ for (i = 0; i < 7; i++) @@ -1582,12 +1584,15 @@ static int compile_have_range(mds_kbdc_tree_assumption_have_range_t* restrict tr } /* Add all characters to the assumption list. */ - while (*first != *last) + for (;;) { fail_if (xmalloc(character, 2, char32_t)); - character[0] = (*first)++; + character[0] = *first; character[1] = -1; result->assumed_strings[result->assumed_strings_ptr++] = character; + /* Bounds are inclusive. */ + if ((*first)++ == *last) + break; } done: @@ -1954,7 +1959,7 @@ static int compile_for(mds_kbdc_tree_for_t* restrict tree) char32_t diff; char32_t character[2]; size_t variable; - int saved_errno; + int possible_shadow = 1, saved_errno; last_value_statement = NULL; @@ -1966,7 +1971,7 @@ static int compile_for(mds_kbdc_tree_for_t* restrict tree) for (lineoff_last = lineoff_first + strlen(tree->first); code[lineoff_last] == ' '; lineoff_last++); for (lineoff_last += strlen("to"); code[lineoff_last] == ' '; lineoff_last++); /* Locate the first character of the select variable. */ - for (lineoff_var = lineoff_last + strlen(tree->variable); code[lineoff_var] == ' '; lineoff_var++); + for (lineoff_var = lineoff_last + strlen(tree->last); code[lineoff_var] == ' '; lineoff_var++); for (lineoff_var += strlen("as"); code[lineoff_var] == ' '; lineoff_var++); /* Duplicate bounds and evaluate function calls, @@ -2004,12 +2009,16 @@ static int compile_for(mds_kbdc_tree_for_t* restrict tree) /* Iterate over the loop for as long as a `return` or `break` has not been encountered (without being caught elsewhere). */ character[1] = -1; - for (diff = (*first > *last) ? -1 : +1; (*first != *last) && (break_level < 2); *first += diff) + for (diff = (*first > *last) ? -1 : +1; break_level < 2; *first += diff) { break_level = 0; character[0] = *first; - fail_if (let(variable, character, NULL, (mds_kbdc_tree_t*)tree, lineoff_var, 1)); + fail_if (let(variable, character, NULL, (mds_kbdc_tree_t*)tree, lineoff_var, possible_shadow)); + possible_shadow = 0; fail_if (compile_subtree(tree->inner)); + /* Bounds are inclusive. */ + if (*first == *last) + break; } /* Catch `break` and `continue`, they may not propagate further. */ @@ -2240,7 +2249,7 @@ static int compile_map(mds_kbdc_tree_map_t* restrict tree) /* Duplicate arguments and evaluate function calls, variable dereferences and escapes in the mapping input sequence. */ - fail_if ((seq = mds_kbdc_tree_dup(old_seq), seq = NULL)); + fail_if ((seq = mds_kbdc_tree_dup(old_seq), seq == NULL)); fail_if ((bad |= evaluate_element(seq), bad < 0)); /* Duplicate arguments and evaluate function calls, @@ -2248,7 +2257,7 @@ static int compile_map(mds_kbdc_tree_map_t* restrict tree) output sequence, unless this is a value-statement. */ if (tree->result) { - fail_if ((res = mds_kbdc_tree_dup(old_res), res = NULL)); + fail_if ((res = mds_kbdc_tree_dup(old_res), res == NULL)); fail_if ((bad |= evaluate_element(res), bad < 0)); } @@ -2268,11 +2277,11 @@ static int compile_map(mds_kbdc_tree_map_t* restrict tree) goto done; /* Duplicate the mapping-statement but give it the evaluated mapping-arguments. */ - tree->sequence = seq; - tree->result = res; - fail_if ((dup_map = &(mds_kbdc_tree_dup((mds_kbdc_tree_t*)tree)->map), dup_map = NULL)); - tree->sequence = old_seq, seq = NULL; - tree->result = old_res, res = NULL; + tree->sequence = NULL; + tree->result = NULL; + fail_if ((dup_map = &(mds_kbdc_tree_dup((mds_kbdc_tree_t*)tree)->map), dup_map == NULL)); + tree->sequence = old_seq, dup_map->sequence = seq, seq = NULL; + tree->result = old_res, dup_map->result = res, res = NULL; /* Enlist the mapping for assembling. */ fail_if ((include_stack = mds_kbdc_include_stack_save(), include_stack == NULL)); @@ -2348,7 +2357,7 @@ static int compile_macro_call(mds_kbdc_tree_macro_call_t* restrict tree) mds_kbdc_tree_macro_t* macro; mds_kbdc_include_stack_t* macro_include_stack; mds_kbdc_include_stack_t* our_include_stack = NULL; - size_t variable; + size_t variable = 0; int bad, saved_errno; last_value_statement = NULL; @@ -2356,7 +2365,7 @@ static int compile_macro_call(mds_kbdc_tree_macro_call_t* restrict tree) /* Duplicate arguments and evaluate function calls, variable dereferences and escapes in the macro call arguments. */ - fail_if ((arg = mds_kbdc_tree_dup(tree->arguments), arg = NULL)); + fail_if ((arg = mds_kbdc_tree_dup(tree->arguments), arg == NULL)); fail_if ((bad = evaluate_element(arg), bad < 0)); if (bad) return 0; @@ -2372,7 +2381,7 @@ static int compile_macro_call(mds_kbdc_tree_macro_call_t* restrict tree) /* Push call stack and set parameters. */ variables_stack_push(); for (arg_ = arg; arg_; arg_ = arg_->next) - fail_if (let(variable, NULL, arg_, NULL, 0, 0)); + fail_if (let(++variable, NULL, arg_, NULL, 0, 0)); /* Switch include-stack to the macro's. */ fail_if ((our_include_stack = mds_kbdc_include_stack_save(), our_include_stack == NULL)); diff --git a/src/mds-kbdc/tree.c b/src/mds-kbdc/tree.c index e5af0b9..662aa06 100644 --- a/src/mds-kbdc/tree.c +++ b/src/mds-kbdc/tree.c @@ -300,7 +300,7 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(const mds_kbdc_tree_t* restrict this) node->loc_start = this->loc_start; node->loc_end = this->loc_end; node->processed = this->processed; - node->next = mds_kbdc_tree_dup(this->next); + node->next = mds_kbdc_tree_dup(this->next); /* TODO perhaps we do not need recursion for this. */ fail_if (this->next && (node->next == NULL)); switch (this->type) diff --git a/test-files/mds-kbdc/compile-layout/valid/assumption b/test-files/mds-kbdc/compile-layout/valid/assumption index cf38db9..ebda249 100644 --- a/test-files/mds-kbdc/compile-layout/valid/assumption +++ b/test-files/mds-kbdc/compile-layout/valid/assumption @@ -3,5 +3,6 @@ assumption have " " have_chars ",.-" have_range "a" "z" + have_range "9" "0" end assumption diff --git a/test-files/mds-kbdc/compile-layout/valid/for-if-break-end-dead b/test-files/mds-kbdc/compile-layout/valid/for-if-break-end-dead new file mode 100644 index 0000000..a6a4c6e --- /dev/null +++ b/test-files/mds-kbdc/compile-layout/valid/for-if-break-end-dead @@ -0,0 +1,7 @@ +for "a" to "e" as \1 + if 1 + break + end if + <letter \1> : \1 +end for + diff --git a/test-files/mds-kbdc/compile-layout/valid/for-if-continue-end-dead b/test-files/mds-kbdc/compile-layout/valid/for-if-continue-end-dead new file mode 100644 index 0000000..a98feb7 --- /dev/null +++ b/test-files/mds-kbdc/compile-layout/valid/for-if-continue-end-dead @@ -0,0 +1,7 @@ +for "a" to "e" as \1 + if 1 + continue + end if + <letter \1> : \1 +end for + diff --git a/test-files/mds-kbdc/compile-layout/valid/for-map b/test-files/mds-kbdc/compile-layout/valid/for-map new file mode 100644 index 0000000..5d334f6 --- /dev/null +++ b/test-files/mds-kbdc/compile-layout/valid/for-map @@ -0,0 +1,4 @@ +for "a" to "e" as \1 + <letter \1> : \1 +end for + diff --git a/test-files/mds-kbdc/compile-layout/valid/let-if-map-end-let-else-map b/test-files/mds-kbdc/compile-layout/valid/let-if-map-end-let-else-map new file mode 100644 index 0000000..9d66433 --- /dev/null +++ b/test-files/mds-kbdc/compile-layout/valid/let-if-map-end-let-else-map @@ -0,0 +1,13 @@ +let \1 : "a" +if \equals(\1 "a") + <letter \1> : \1 +else + "\1" : "x" +end if +let \1 : "b" +if \not(\equals(\1 "b")) + "\1" : "x" +else + <letter \1> : \1 +end if + diff --git a/test-files/mds-kbdc/compile-layout/valid/map b/test-files/mds-kbdc/compile-layout/valid/map new file mode 100644 index 0000000..4a906f2 --- /dev/null +++ b/test-files/mds-kbdc/compile-layout/valid/map @@ -0,0 +1,2 @@ +"a" : "a" + diff --git a/test-files/mds-kbdc/compile-layout/valid/reversed_for-map b/test-files/mds-kbdc/compile-layout/valid/reversed_for-map new file mode 100644 index 0000000..7ae2062 --- /dev/null +++ b/test-files/mds-kbdc/compile-layout/valid/reversed_for-map @@ -0,0 +1,4 @@ +for "e" to "a" as \1 + <letter \1> : \1 +end for + |