aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mds-kbdc/make-tree.c31
-rw-r--r--test-files/mds-kbdc/make-tree/valid/if-else9
-rw-r--r--test-files/mds-kbdc/make-tree/valid/if-elseif9
-rw-r--r--test-files/mds-kbdc/make-tree/valid/if-elseif-else9
-rw-r--r--test-files/mds-kbdc/make-tree/valid/if-elseif-elseif59
-rw-r--r--test-files/mds-kbdc/make-tree/valid/if-elseif-elseif-else70
6 files changed, 179 insertions, 8 deletions
diff --git a/src/mds-kbdc/make-tree.c b/src/mds-kbdc/make-tree.c
index 1172dbe..13bf682 100644
--- a/src/mds-kbdc/make-tree.c
+++ b/src/mds-kbdc/make-tree.c
@@ -809,6 +809,7 @@ int parse_to_tree(const char* restrict filename, mds_kbdc_tree_t** restrict resu
}
else if (!strcmp(line, "else"))
{
+ size_t i;
if (stack_ptr == 0)
{
NEW_ERROR(1, ERROR, "runaway ‘else’ statement");
@@ -817,35 +818,47 @@ int parse_to_tree(const char* restrict filename, mds_kbdc_tree_t** restrict resu
line += strlen(line);
*end = prev_end_char, prev_end_char = '\0';
end = line + strlen(line);
- stack_ptr--;
while (*line && (*line == ' '))
line++;
- if (strcmp(keyword_stack[stack_ptr], "if"))
+ i = stack_ptr - 1;
+ while (keyword_stack[i] == NULL)
+ i--;
+ if (strcmp(keyword_stack[i], "if"))
{
+ stack_ptr--;
line = original, end = line + strlen(line);
NEW_ERROR(1, ERROR, "runaway ‘else’ statement");
}
else if (*line == '\0')
{
/* else */
- mds_kbdc_tree_if_t* node = &(tree_stack[stack_ptr][0]->if_);
- tree_stack[stack_ptr + 1] = &(node->otherwise);
- keyword_stack[stack_ptr++] = "if";
+ mds_kbdc_tree_if_t* supernode = &(tree_stack[stack_ptr - 1][0]->if_);
+ if (supernode->otherwise)
+ {
+ line = strstr(source_code.lines[line_i], "else");
+ end = line + 4, prev_end_char = *end;
+ NEW_ERROR(1, ERROR, "multiple ‘else’ statements");
+ mds_kbdc_tree_free(supernode->otherwise);
+ supernode->otherwise = NULL;
+ }
+ tree_stack[stack_ptr] = &(supernode->otherwise);
}
else if ((strstr(line, "if") == line) && ((line[2] == ' ') || (line[2] == '\0')))
{
/* else if */
+ mds_kbdc_tree_if_t* supernode = &(tree_stack[stack_ptr - 1][0]->if_);
NEW_NODE(if, IF);
node->loc_end = node->loc_start + 2;
- tree_stack[stack_ptr][0]->if_.otherwise = (mds_kbdc_tree_t*)node;
end = line += 2, prev_end_char = *end, *end = '\0';
CHARS(condition);
END;
- BRANCH("if");
+ tree_stack[stack_ptr] = &(supernode->otherwise);
+ BRANCH(NULL);
}
else
{
NEW_ERROR(1, ERROR, "expecting nothing or ‘if’");
+ stack_ptr--;
}
}
else if (!strcmp(line, "for"))
@@ -927,9 +940,9 @@ int parse_to_tree(const char* restrict filename, mds_kbdc_tree_t** restrict resu
}
line += strlen(line);
*end = prev_end_char, prev_end_char = '\0';
- stack_ptr--;
while (*line && (*line == ' '))
line++;
+ while (keyword_stack[--stack_ptr] == NULL);
if (*line == '\0')
{
line = original, end = line + strlen(line);
@@ -996,6 +1009,8 @@ int parse_to_tree(const char* restrict filename, mds_kbdc_tree_t** restrict resu
NEW_ERROR(0, ERROR, "premature end of file");
while (stack_ptr--)
{
+ if (keyword_stack[stack_ptr] == NULL)
+ continue;
line_i = tree_stack[stack_ptr][0]->loc_line;
line = source_code.lines[line_i] + tree_stack[stack_ptr][0]->loc_start;
end = source_code.lines[line_i] + tree_stack[stack_ptr][0]->loc_end;
diff --git a/test-files/mds-kbdc/make-tree/valid/if-else b/test-files/mds-kbdc/make-tree/valid/if-else
index 217f478..796f2bf 100644
--- a/test-files/mds-kbdc/make-tree/valid/if-else
+++ b/test-files/mds-kbdc/make-tree/valid/if-else
@@ -3,6 +3,7 @@ if \1
else
<letter \2> : "\2"
end if
+<letter a> : "a"
# (if (@ 1 0-2) ‘\1’
# (.inner
@@ -26,4 +27,12 @@ end if
# )
# )
# )
+# (map (@ 6 0-0)
+# (.sequence
+# (keys (@ 6 0-10) ‘<letter a>’)
+# )
+# (.result
+# (string (@ 6 13-16) ‘"a"’)
+# )
+# )
diff --git a/test-files/mds-kbdc/make-tree/valid/if-elseif b/test-files/mds-kbdc/make-tree/valid/if-elseif
index 44d8d1f..5a61010 100644
--- a/test-files/mds-kbdc/make-tree/valid/if-elseif
+++ b/test-files/mds-kbdc/make-tree/valid/if-elseif
@@ -3,6 +3,7 @@ if \1
else if \2
<letter \2> : "\2"
end if
+<letter a> : "a"
# (if (@ 1 0-2) ‘\1’
# (.inner
@@ -31,4 +32,12 @@ end if
# )
# )
# )
+# (map (@ 6 0-0)
+# (.sequence
+# (keys (@ 6 0-10) ‘<letter a>’)
+# )
+# (.result
+# (string (@ 6 13-16) ‘"a"’)
+# )
+# )
diff --git a/test-files/mds-kbdc/make-tree/valid/if-elseif-else b/test-files/mds-kbdc/make-tree/valid/if-elseif-else
index 461ebc7..ece7744 100644
--- a/test-files/mds-kbdc/make-tree/valid/if-elseif-else
+++ b/test-files/mds-kbdc/make-tree/valid/if-elseif-else
@@ -5,6 +5,7 @@ else if \2
else
<letter \3> : "\3"
end if
+<letter a> : "a"
# (if (@ 1 0-2) ‘\1’
# (.inner
@@ -42,4 +43,12 @@ end if
# )
# )
# )
+# (map (@ 8 0-0)
+# (.sequence
+# (keys (@ 8 0-10) ‘<letter a>’)
+# )
+# (.result
+# (string (@ 8 13-16) ‘"a"’)
+# )
+# )
diff --git a/test-files/mds-kbdc/make-tree/valid/if-elseif-elseif b/test-files/mds-kbdc/make-tree/valid/if-elseif-elseif
new file mode 100644
index 0000000..81f59fb
--- /dev/null
+++ b/test-files/mds-kbdc/make-tree/valid/if-elseif-elseif
@@ -0,0 +1,59 @@
+if \1
+ <letter \1> : "\1"
+else if \2
+ <letter \2> : "\2"
+else if \3
+ <letter \3> : "\3"
+end if
+<letter a> : "a"
+
+# (if (@ 1 0-2) ‘\1’
+# (.inner
+# (map (@ 2 2-2)
+# (.sequence
+# (keys (@ 2 2-13) ‘<letter \1>’)
+# )
+# (.result
+# (string (@ 2 16-20) ‘"\1"’)
+# )
+# )
+# )
+# (.otherwise
+# (if (@ 3 3-7) ‘\2’
+# (.inner
+# (map (@ 4 4-4)
+# (.sequence
+# (keys (@ 4 4-15) ‘<letter \2>’)
+# )
+# (.result
+# (string (@ 4 18-22) ‘"\2"’)
+# )
+# )
+# )
+# (.otherwise
+# (if (@ 5 3-7) ‘\3’
+# (.inner
+# (map (@ 6 4-4)
+# (.sequence
+# (keys (@ 6 4-15) ‘<letter \3>’)
+# )
+# (.result
+# (string (@ 6 18-22) ‘"\3"’)
+# )
+# )
+# )
+# (.otherwise nil)
+# )
+# )
+# )
+# )
+# )
+# (map (@ 8 0-0)
+# (.sequence
+# (keys (@ 8 0-10) ‘<letter a>’)
+# )
+# (.result
+# (string (@ 8 13-16) ‘"a"’)
+# )
+# )
+
diff --git a/test-files/mds-kbdc/make-tree/valid/if-elseif-elseif-else b/test-files/mds-kbdc/make-tree/valid/if-elseif-elseif-else
new file mode 100644
index 0000000..c4bbf5b
--- /dev/null
+++ b/test-files/mds-kbdc/make-tree/valid/if-elseif-elseif-else
@@ -0,0 +1,70 @@
+if \1
+ <letter \1> : "\1"
+else if \2
+ <letter \2> : "\2"
+else if \3
+ <letter \3> : "\3"
+else
+ <letter \4> : "\4"
+end if
+<letter a> : "a"
+
+# (if (@ 1 0-2) ‘\1’
+# (.inner
+# (map (@ 2 2-2)
+# (.sequence
+# (keys (@ 2 2-13) ‘<letter \1>’)
+# )
+# (.result
+# (string (@ 2 16-20) ‘"\1"’)
+# )
+# )
+# )
+# (.otherwise
+# (if (@ 3 3-7) ‘\2’
+# (.inner
+# (map (@ 4 4-4)
+# (.sequence
+# (keys (@ 4 4-15) ‘<letter \2>’)
+# )
+# (.result
+# (string (@ 4 18-22) ‘"\2"’)
+# )
+# )
+# )
+# (.otherwise
+# (if (@ 5 3-7) ‘\3’
+# (.inner
+# (map (@ 6 4-4)
+# (.sequence
+# (keys (@ 6 4-15) ‘<letter \3>’)
+# )
+# (.result
+# (string (@ 6 18-22) ‘"\3"’)
+# )
+# )
+# )
+# (.otherwise
+# (map (@ 8 4-4)
+# (.sequence
+# (keys (@ 8 4-15) ‘<letter \4>’)
+# )
+# (.result
+# (string (@ 8 18-22) ‘"\4"’)
+# )
+# )
+# )
+# )
+# )
+# )
+# )
+# )
+# (map (@ 10 0-0)
+# (.sequence
+# (keys (@ 10 0-10) ‘<letter a>’)
+# )
+# (.result
+# (string (@ 10 13-16) ‘"a"’)
+# )
+# )
+