diff options
-rw-r--r-- | src/mds-kbdc/make-tree.c | 31 | ||||
-rw-r--r-- | test-files/mds-kbdc/make-tree/valid/if-else | 9 | ||||
-rw-r--r-- | test-files/mds-kbdc/make-tree/valid/if-elseif | 9 | ||||
-rw-r--r-- | test-files/mds-kbdc/make-tree/valid/if-elseif-else | 9 | ||||
-rw-r--r-- | test-files/mds-kbdc/make-tree/valid/if-elseif-elseif | 59 | ||||
-rw-r--r-- | test-files/mds-kbdc/make-tree/valid/if-elseif-elseif-else | 70 |
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"’) +# ) +# ) + |