aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mds-kbdc/make-tree.c50
-rw-r--r--src/mds-kbdc/parse-error.c2
-rw-r--r--src/mds-kbdc/tree.c4
-rw-r--r--src/mds-kbdc/tree.h6
-rw-r--r--test-files/mds-kbdc/make-tree/valid/assumption7
-rw-r--r--test-files/mds-kbdc/make-tree/valid/assumption-filled24
-rw-r--r--test-files/mds-kbdc/make-tree/valid/break4
-rw-r--r--test-files/mds-kbdc/make-tree/valid/continue4
-rw-r--r--test-files/mds-kbdc/make-tree/valid/function15
-rw-r--r--test-files/mds-kbdc/make-tree/valid/if18
-rw-r--r--test-files/mds-kbdc/make-tree/valid/if-else29
-rw-r--r--test-files/mds-kbdc/make-tree/valid/if-else-if36
-rw-r--r--test-files/mds-kbdc/make-tree/valid/if-elseif34
-rw-r--r--test-files/mds-kbdc/make-tree/valid/if-elseif-else45
-rw-r--r--test-files/mds-kbdc/make-tree/valid/if-if25
-rw-r--r--test-files/mds-kbdc/make-tree/valid/include4
-rw-r--r--test-files/mds-kbdc/make-tree/valid/information7
-rw-r--r--test-files/mds-kbdc/make-tree/valid/information-filled14
-rw-r--r--test-files/mds-kbdc/make-tree/valid/macro17
-rw-r--r--test-files/mds-kbdc/make-tree/valid/return4
20 files changed, 328 insertions, 21 deletions
diff --git a/src/mds-kbdc/make-tree.c b/src/mds-kbdc/make-tree.c
index 37ed34c..1172dbe 100644
--- a/src/mds-kbdc/make-tree.c
+++ b/src/mds-kbdc/make-tree.c
@@ -134,6 +134,21 @@
/**
+ * Create a new node named `subnode`
+ *
+ * @param LOWERCASE:identifier The keyword, for the node type, in lower case
+ * @param UPPERCASE:identifier The keyword, for the node type, in upper case
+ */
+#define NEW_SUBNODE(LOWERCASE, UPPERCASE) \
+ mds_kbdc_tree_##LOWERCASE##_t* subnode; \
+ fail_if (xcalloc(subnode, 1, mds_kbdc_tree_##LOWERCASE##_t)); \
+ subnode->type = MDS_KBDC_TREE_TYPE_##UPPERCASE; \
+ subnode->loc_line = line_i; \
+ subnode->loc_start = (size_t)(line - source_code.lines[line_i]); \
+ subnode->loc_end = (size_t)(end - source_code.lines[line_i])
+
+
+/**
* Update the tip of the tree stack with the current node
* and change the pointer at the tip to the pointer to the
* current node's down pointer
@@ -283,12 +298,12 @@
call_end = arg_end + get_end_of_call(arg_end, 0, strlen(arg_end)); \
} \
else if (quote) quote = (c != '"'); \
- else if (c == ' ') break; \
+ else if (c == ' ') { arg_end--; break; } \
else quote = (c == '"'); \
} \
- prev_end_char = *arg_end, *arg_end = '\0'; \
+ prev_end_char = *arg_end, *arg_end = '\0', end = arg_end; \
fail_if ((node->var = strdup(line)) == NULL); \
- end = line = arg_end; \
+ line = end; \
} \
} \
while (0)
@@ -429,26 +444,22 @@
else if (quote) quote = (c != '"'); \
else if (c == '\"') quote = 1; \
else if (c == '>') triangle = 0; \
- else if ((c == ' ') && !triangle) break; \
+ else if ((c == ' ') && !triangle) { arg_end--; break; } \
} \
- prev_end_char = *arg_end, *arg_end = '\0'; \
+ prev_end_char = *arg_end, *arg_end = '\0', end = arg_end; \
if (*line == '<') \
{ \
- mds_kbdc_tree_keys_t* subnode; \
- fail_if (xcalloc(subnode, 1, mds_kbdc_tree_keys_t)); \
- subnode->type = MDS_KBDC_TREE_TYPE_KEYS; \
+ NEW_SUBNODE(keys, KEYS); \
node->var = (mds_kbdc_tree_t*)subnode; \
fail_if ((subnode->keys = strdup(line)) == NULL); \
} \
else \
{ \
- mds_kbdc_tree_string_t* subnode; \
- fail_if (xcalloc(subnode, 1, mds_kbdc_tree_string_t)); \
- subnode->type = MDS_KBDC_TREE_TYPE_STRING; \
+ NEW_SUBNODE(string, STRING); \
node->var = (mds_kbdc_tree_t*)subnode; \
fail_if ((subnode->string = strdup(line)) == NULL); \
} \
- end = line = arg_end; \
+ line = end; \
} \
} \
while (0)
@@ -494,11 +505,11 @@
else if (quote) quote = (c != '"'); \
else if (c == '\"') quote = 1; \
else if (c == '>') triangle = 0; \
- else if ((c == ' ') && !triangle) break; \
+ else if ((c == ' ') && !triangle) { arg_end--; break; } \
} \
prev_end_char = *arg_end, *arg_end = '\0'; \
fail_if ((node->var = strdup(line)) == NULL); \
- end = line = arg_end; \
+ end = arg_end, line = end; \
} \
} \
while (0)
@@ -821,12 +832,13 @@ int parse_to_tree(const char* restrict filename, mds_kbdc_tree_t** restrict resu
tree_stack[stack_ptr + 1] = &(node->otherwise);
keyword_stack[stack_ptr++] = "if";
}
- else if ((strstr(line, "if") == line) && ((line[3] == ' ') || (line[3] == '\0')))
+ else if ((strstr(line, "if") == line) && ((line[2] == ' ') || (line[2] == '\0')))
{
/* else if */
NEW_NODE(if, IF);
+ node->loc_end = node->loc_start + 2;
tree_stack[stack_ptr][0]->if_.otherwise = (mds_kbdc_tree_t*)node;
- line += 2;
+ end = line += 2, prev_end_char = *end, *end = '\0';
CHARS(condition);
END;
BRANCH("if");
@@ -943,8 +955,10 @@ int parse_to_tree(const char* restrict filename, mds_kbdc_tree_t** restrict resu
SEQUENCE_FULLY_POPPED(stack_orig);
stack_ptr--;
*end = prev_end_char;
+ while (*line && (*line == ' '))
+ line++;
if (*line++ != ':')
- continue;
+ continue; /* Not an error in macros. */
#define node supernode
#define inner result
BRANCH(":");
@@ -954,6 +968,8 @@ int parse_to_tree(const char* restrict filename, mds_kbdc_tree_t** restrict resu
SEQUENCE_FULLY_POPPED(stack_orig);
stack_ptr--;
*end = prev_end_char;
+ while (*line && (*line == ' '))
+ line++;
if (*line == '\0')
continue;
end = line + strlen(line), prev_end_char = *end;
diff --git a/src/mds-kbdc/parse-error.c b/src/mds-kbdc/parse-error.c
index 1ad5ae1..298c712 100644
--- a/src/mds-kbdc/parse-error.c
+++ b/src/mds-kbdc/parse-error.c
@@ -82,7 +82,7 @@ void mds_kbdc_parse_error_print(const mds_kbdc_parse_error_t* restrict this, FIL
/* Print error information. */
fprintf(output, "\033[01m%s\033[21m:", this->pathname); /* TODO should be relative to the current dir */
if (this->error_is_in_file)
- fprintf(output, "%zu:%zu–%zu:", this->line + 1, start + 1, end + 1);
+ fprintf(output, "%zu:%zu–%zu:", this->line + 1, start, end);
switch (this->severity)
{
case MDS_KBDC_PARSE_ERROR_NOTE: fprintf(output, " \033[01;36mnote:\033[00m "); break;
diff --git a/src/mds-kbdc/tree.c b/src/mds-kbdc/tree.c
index 9f1085c..b460d04 100644
--- a/src/mds-kbdc/tree.c
+++ b/src/mds-kbdc/tree.c
@@ -232,7 +232,7 @@ void mds_kbdc_tree_free(mds_kbdc_tree_t* restrict this)
node = (mds_kbdc_tree_##LOWERCASE##_t*)this; \
fprintf(output, "%*.s(\033[01m%s\033[00m", indent, "", NOTATION); \
fprintf(output, " \033[36m(@ %zu %zu-%zu)\033[00m", \
- node->loc_line, node->loc_start, node->loc_end)
+ node->loc_line + 1, node->loc_start, node->loc_end)
/**
@@ -360,7 +360,7 @@ void mds_kbdc_tree_free(mds_kbdc_tree_t* restrict this)
#define NOTHING(NOTATION) \
fprintf(output, "%*.s(\033[01m%s\033[00m", indent, "", NOTATION); \
fprintf(output, " \033[36m(@ %zu %zu-%zu)\033[00m", \
- this->loc_line, this->loc_start, this->loc_end); \
+ this->loc_line + 1, this->loc_start, this->loc_end); \
fprintf(output, ")\n"); \
break
diff --git a/src/mds-kbdc/tree.h b/src/mds-kbdc/tree.h
index 28d319d..f3ad7f2 100644
--- a/src/mds-kbdc/tree.h
+++ b/src/mds-kbdc/tree.h
@@ -473,7 +473,11 @@ typedef struct mds_kbdc_tree_let
/**
* Tree structure for mapping a (possible single element)
* sequence of key combinations or strings to another
- * combination or string or sequence there of
+ * combination or string or sequence thereof
+ *
+ * Inside functions this can be used for the return value,
+ * in such case `sequence` should not be `NULL` but
+ * `sequence.next` and `result` should be `NULL`
*/
typedef struct mds_kbdc_tree_map
{
diff --git a/test-files/mds-kbdc/make-tree/valid/assumption b/test-files/mds-kbdc/make-tree/valid/assumption
new file mode 100644
index 0000000..1be3caf
--- /dev/null
+++ b/test-files/mds-kbdc/make-tree/valid/assumption
@@ -0,0 +1,7 @@
+assumption
+end assumption
+
+# (assumption (@ 1 0-10)
+# (.inner nil)
+# )
+
diff --git a/test-files/mds-kbdc/make-tree/valid/assumption-filled b/test-files/mds-kbdc/make-tree/valid/assumption-filled
new file mode 100644
index 0000000..fbf8a3c
--- /dev/null
+++ b/test-files/mds-kbdc/make-tree/valid/assumption-filled
@@ -0,0 +1,24 @@
+assumption
+ have " "
+ have <dead compose>
+ have_chars ",."
+ have_range "0" "9"
+end assumption
+
+# (assumption (@ 1 0-10)
+# (.inner
+# (have (@ 2 2-6)
+# (.data
+# (string (@ 2 7-10) ‘" "’)
+# )
+# )
+# (have (@ 3 2-6)
+# (.data
+# (keys (@ 3 7-21) ‘<dead compose>’)
+# )
+# )
+# (have_chars (@ 4 2-12) ‘",."’)
+# (have_range (@ 5 2-12) ‘"0"’ ‘"9"’)
+# )
+# )
+
diff --git a/test-files/mds-kbdc/make-tree/valid/break b/test-files/mds-kbdc/make-tree/valid/break
new file mode 100644
index 0000000..f6441ce
--- /dev/null
+++ b/test-files/mds-kbdc/make-tree/valid/break
@@ -0,0 +1,4 @@
+break
+
+# (break (@ 1 0-5))
+
diff --git a/test-files/mds-kbdc/make-tree/valid/continue b/test-files/mds-kbdc/make-tree/valid/continue
new file mode 100644
index 0000000..0a7f39f
--- /dev/null
+++ b/test-files/mds-kbdc/make-tree/valid/continue
@@ -0,0 +1,4 @@
+continue
+
+# (continue (@ 1 0-8))
+
diff --git a/test-files/mds-kbdc/make-tree/valid/function b/test-files/mds-kbdc/make-tree/valid/function
new file mode 100644
index 0000000..99b44f7
--- /dev/null
+++ b/test-files/mds-kbdc/make-tree/valid/function
@@ -0,0 +1,15 @@
+function add/3
+ \add(\1 \add(\2 \3))
+end function
+
+# (function (@ 1 0-8) ‘add/3’
+# (.inner
+# (map (@ 2 2-2)
+# (.sequence
+# (keys (@ 2 2-22) ‘\add(\1 \add(\2 \3))’)
+# )
+# (.result nil)
+# )
+# )
+# )
+
diff --git a/test-files/mds-kbdc/make-tree/valid/if b/test-files/mds-kbdc/make-tree/valid/if
new file mode 100644
index 0000000..44ca203
--- /dev/null
+++ b/test-files/mds-kbdc/make-tree/valid/if
@@ -0,0 +1,18 @@
+if \1
+ <letter \1> : "\1"
+end if
+
+# (if (@ 1 0-2) ‘\1’
+# (.inner
+# (map (@ 2 2-2)
+# (.sequence
+# (keys (@ 2 2-13) ‘<letter \1>’)
+# )
+# (.result
+# (string (@ 2 16-20) ‘"\1"’)
+# )
+# )
+# )
+# (.otherwise nil)
+# )
+
diff --git a/test-files/mds-kbdc/make-tree/valid/if-else b/test-files/mds-kbdc/make-tree/valid/if-else
new file mode 100644
index 0000000..217f478
--- /dev/null
+++ b/test-files/mds-kbdc/make-tree/valid/if-else
@@ -0,0 +1,29 @@
+if \1
+ <letter \1> : "\1"
+else
+ <letter \2> : "\2"
+end if
+
+# (if (@ 1 0-2) ‘\1’
+# (.inner
+# (map (@ 2 2-2)
+# (.sequence
+# (keys (@ 2 2-13) ‘<letter \1>’)
+# )
+# (.result
+# (string (@ 2 16-20) ‘"\1"’)
+# )
+# )
+# )
+# (.otherwise nil
+# (map (@ 4 2-2)
+# (.sequence
+# (keys (@ 4 2-13) ‘<letter \2>’)
+# )
+# (.result
+# (string (@ 4 16-20) ‘"\2"’)
+# )
+# )
+# )
+# )
+
diff --git a/test-files/mds-kbdc/make-tree/valid/if-else-if b/test-files/mds-kbdc/make-tree/valid/if-else-if
new file mode 100644
index 0000000..fe88c43
--- /dev/null
+++ b/test-files/mds-kbdc/make-tree/valid/if-else-if
@@ -0,0 +1,36 @@
+if \1
+ <letter \1> : "\1"
+else
+ if \2
+ <letter \2> : "\2"
+ end if
+end if
+
+# (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 (@ 4 2-4) ‘\2’
+# (.inner
+# (map (@ 5 4-4)
+# (.sequence
+# (keys (@ 5 4-15) ‘<letter \2>’)
+# )
+# (.result
+# (string (@ 5 18-22) ‘"\2"’)
+# )
+# )
+# )
+# (.otherwise nil)
+# )
+# )
+# )
+
diff --git a/test-files/mds-kbdc/make-tree/valid/if-elseif b/test-files/mds-kbdc/make-tree/valid/if-elseif
new file mode 100644
index 0000000..44d8d1f
--- /dev/null
+++ b/test-files/mds-kbdc/make-tree/valid/if-elseif
@@ -0,0 +1,34 @@
+if \1
+ <letter \1> : "\1"
+else if \2
+ <letter \2> : "\2"
+end if
+
+# (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 nil)
+# )
+# )
+# )
+
diff --git a/test-files/mds-kbdc/make-tree/valid/if-elseif-else b/test-files/mds-kbdc/make-tree/valid/if-elseif-else
new file mode 100644
index 0000000..461ebc7
--- /dev/null
+++ b/test-files/mds-kbdc/make-tree/valid/if-elseif-else
@@ -0,0 +1,45 @@
+if \1
+ <letter \1> : "\1"
+else if \2
+ <letter \2> : "\2"
+else
+ <letter \3> : "\3"
+end if
+
+# (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
+# (map (@ 6 4-4)
+# (.sequence
+# (keys (@ 6 4-15) ‘<letter \3>’)
+# )
+# (.result
+# (string (@ 6 18-22) ‘"\3"’)
+# )
+# )
+# )
+# )
+# )
+# )
+
diff --git a/test-files/mds-kbdc/make-tree/valid/if-if b/test-files/mds-kbdc/make-tree/valid/if-if
new file mode 100644
index 0000000..3a63615
--- /dev/null
+++ b/test-files/mds-kbdc/make-tree/valid/if-if
@@ -0,0 +1,25 @@
+if \1
+ if \2
+ <letter \1> : "\2"
+ end if
+end if
+
+# (if (@ 1 0-2) ‘\1’
+# (.inner
+# (if (@ 2 2-4) ‘\1’
+# (.inner
+# (map (@ 3 4-4)
+# (.sequence
+# (keys (@ 3 4-15) ‘<letter \1>’)
+# )
+# (.result
+# (string (@ 3 18-22) ‘"\2"’)
+# )
+# )
+# )
+# (.otherwise nil)
+# )
+# )
+# (.otherwise nil)
+# )
+
diff --git a/test-files/mds-kbdc/make-tree/valid/include b/test-files/mds-kbdc/make-tree/valid/include
new file mode 100644
index 0000000..32dcdf2
--- /dev/null
+++ b/test-files/mds-kbdc/make-tree/valid/include
@@ -0,0 +1,4 @@
+include "assumption-filled"
+
+# (include (@ 1 0-7) ‘"assumption-filled"’)
+
diff --git a/test-files/mds-kbdc/make-tree/valid/information b/test-files/mds-kbdc/make-tree/valid/information
new file mode 100644
index 0000000..1192eaf
--- /dev/null
+++ b/test-files/mds-kbdc/make-tree/valid/information
@@ -0,0 +1,7 @@
+information
+end information
+
+# (information (@ 1 0-11)
+# (.inner nil)
+# )
+
diff --git a/test-files/mds-kbdc/make-tree/valid/information-filled b/test-files/mds-kbdc/make-tree/valid/information-filled
new file mode 100644
index 0000000..69ce6dd
--- /dev/null
+++ b/test-files/mds-kbdc/make-tree/valid/information-filled
@@ -0,0 +1,14 @@
+information
+ language "Language" # test that the quotes ends where it should
+ country "Country"
+ variant "Variant"
+end information
+
+# (information (@ 1 0-11)
+# (.inner
+# (language (@ 2 2-10) ‘"Language"’)
+# (country (@ 3 2-9) ‘"Country"’)
+# (variant (@ 4 2-9) ‘"Variant"’)
+# )
+# )
+
diff --git a/test-files/mds-kbdc/make-tree/valid/macro b/test-files/mds-kbdc/make-tree/valid/macro
new file mode 100644
index 0000000..151417b
--- /dev/null
+++ b/test-files/mds-kbdc/make-tree/valid/macro
@@ -0,0 +1,17 @@
+macro identity/1
+ <letter \1> : "\1"
+end macro
+
+# (macro (@ 1 0-5) ‘identity/1’
+# (.inner
+# (map (@ 2 2-2)
+# (.sequence
+# (keys (@ 2 2-13) ‘<letter \1>’)
+# )
+# (.result
+# (string (@ 2 16-20) ‘"\1"’)
+# )
+# )
+# )
+# )
+
diff --git a/test-files/mds-kbdc/make-tree/valid/return b/test-files/mds-kbdc/make-tree/valid/return
new file mode 100644
index 0000000..eeee7fa
--- /dev/null
+++ b/test-files/mds-kbdc/make-tree/valid/return
@@ -0,0 +1,4 @@
+return
+
+# (return (@ 1 0-6))
+