aboutsummaryrefslogtreecommitdiffstats
path: root/src/mds-kbdc/make-tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mds-kbdc/make-tree.c')
-rw-r--r--src/mds-kbdc/make-tree.c31
1 files changed, 23 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;