aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mds-kbdc/compile-layout.c45
-rw-r--r--src/mds-kbdc/tree.c2
-rw-r--r--test-files/mds-kbdc/compile-layout/valid/assumption1
-rw-r--r--test-files/mds-kbdc/compile-layout/valid/for-if-break-end-dead7
-rw-r--r--test-files/mds-kbdc/compile-layout/valid/for-if-continue-end-dead7
-rw-r--r--test-files/mds-kbdc/compile-layout/valid/for-map4
-rw-r--r--test-files/mds-kbdc/compile-layout/valid/let-if-map-end-let-else-map13
-rw-r--r--test-files/mds-kbdc/compile-layout/valid/map2
-rw-r--r--test-files/mds-kbdc/compile-layout/valid/reversed_for-map4
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
+