diff options
author | Mattias Andrée <maandree@operamail.com> | 2014-12-11 04:29:54 +0100 |
---|---|---|
committer | Mattias Andrée <maandree@operamail.com> | 2014-12-11 04:29:54 +0100 |
commit | df29e69e8cb89146b145a317cc15f535e52f82d8 (patch) | |
tree | 03cd9ebc6dc68d5aad597cf9b2f12a1ec603ff1e | |
parent | m (diff) | |
download | mds-df29e69e8cb89146b145a317cc15f535e52f82d8.tar.gz mds-df29e69e8cb89146b145a317cc15f535e52f82d8.tar.bz2 mds-df29e69e8cb89146b145a317cc15f535e52f82d8.tar.xz |
mds-kbdc: validate-tree: you can define functions and macros inside assumption-clauses
Signed-off-by: Mattias Andrée <maandree@operamail.com>
-rw-r--r-- | src/mds-kbdc/validate-tree.c | 73 | ||||
-rw-r--r-- | test-files/mds-kbdc/validate-tree/valid/assumption-function | 21 | ||||
-rw-r--r-- | test-files/mds-kbdc/validate-tree/valid/assumption-macro | 23 |
3 files changed, 84 insertions, 33 deletions
diff --git a/src/mds-kbdc/validate-tree.c b/src/mds-kbdc/validate-tree.c index 466f138..3c676eb 100644 --- a/src/mds-kbdc/validate-tree.c +++ b/src/mds-kbdc/validate-tree.c @@ -30,6 +30,11 @@ #define C(TYPE) MDS_KBDC_TREE_TYPE_##TYPE /** + * Check the value of `innermost_visit` + */ +#define VISITING(TYPE) (innermost_visit == MDS_KBDC_TREE_TYPE_##TYPE) + +/** * Add an error with “included from here”-notes to the error list * * @param NODE:const mds_kbdc_tree_t* The node the triggered the error @@ -84,6 +89,13 @@ static mds_kbdc_tree_assumption_t* assumption = NULL; */ static size_t def_includes_ptr = 0; +/** + * The type of the currently innermost visited node + * of `C(FUNCTION)`, `C(MACRO)`, `C(INFORMATION)` and + * `C(ASSUMPTION)`, -1 if none + */ +static int innermost_visit = -1; + /** @@ -125,30 +137,25 @@ static int validate_include(mds_kbdc_tree_include_t* restrict tree) static int validate_function(mds_kbdc_tree_function_t* restrict tree) { int r; - if (function) + if (VISITING(FUNCTION)) { NEW_ERROR(tree, includes_ptr, ERROR, "nested function definition"); NEW_ERROR(function, def_includes_ptr, NOTE, "outer function defined here"); return 0; } - else if (macro) + else if (VISITING(MACRO)) { NEW_ERROR(tree, includes_ptr, ERROR, "function definition inside macro definition"); NEW_ERROR(macro, def_includes_ptr, NOTE, "outer macro defined here"); return 0; } - else if (information) + else if (VISITING(INFORMATION)) { NEW_ERROR(tree, includes_ptr, ERROR, "function definition inside information clause"); NEW_ERROR(information, def_includes_ptr, NOTE, "outer information clause defined here"); return 0; } - else if (assumption) - { - NEW_ERROR(tree, includes_ptr, ERROR, "function definition inside assumption clause"); - NEW_ERROR(assumption, def_includes_ptr, NOTE, "outer assumption clause defined here"); - return 0; - } + innermost_visit = tree->type; function = tree; def_includes_ptr = includes_ptr; r = validate_subtree(tree->inner); @@ -167,30 +174,25 @@ static int validate_function(mds_kbdc_tree_function_t* restrict tree) static int validate_macro(mds_kbdc_tree_macro_t* restrict tree) { int r; - if (function) + if (VISITING(FUNCTION)) { NEW_ERROR(tree, includes_ptr, ERROR, "macro definition inside function definition"); NEW_ERROR(function, def_includes_ptr, NOTE, "outer function definition defined here"); return 0; } - else if (macro) + else if (VISITING(MACRO)) { NEW_ERROR(tree, includes_ptr, ERROR, "nested macro definition"); NEW_ERROR(macro, def_includes_ptr, NOTE, "outer macro defined here"); return 0; } - else if (information) + else if (VISITING(INFORMATION)) { NEW_ERROR(tree, includes_ptr, ERROR, "macro definition inside information clause"); NEW_ERROR(information, def_includes_ptr, NOTE, "outer information clause defined here"); return 0; } - else if (assumption) - { - NEW_ERROR(tree, includes_ptr, ERROR, "macro definition inside assumption clause"); - NEW_ERROR(assumption, def_includes_ptr, NOTE, "outer assumption clause defined here"); - return 0; - } + innermost_visit = tree->type; macro = tree; def_includes_ptr = includes_ptr; r = validate_subtree(tree->inner); @@ -209,30 +211,31 @@ static int validate_macro(mds_kbdc_tree_macro_t* restrict tree) static int validate_information(mds_kbdc_tree_information_t* restrict tree) { int r; - if (function) + if (VISITING(FUNCTION)) { NEW_ERROR(tree, includes_ptr, ERROR, "information clause inside function definition"); NEW_ERROR(function, def_includes_ptr, NOTE, "outer function definition defined here"); return 0; } - else if (macro) + else if (VISITING(MACRO)) { NEW_ERROR(tree, includes_ptr, ERROR, "information clause inside macro definition"); NEW_ERROR(macro, def_includes_ptr, NOTE, "outer macro defined here"); return 0; } - else if (information) + else if (VISITING(INFORMATION)) { NEW_ERROR(tree, includes_ptr, ERROR, "nested information clause"); NEW_ERROR(information, def_includes_ptr, NOTE, "outer information clause defined here"); return 0; } - else if (assumption) + else if (VISITING(ASSUMPTION)) { NEW_ERROR(tree, includes_ptr, ERROR, "information clause inside assumption clause"); NEW_ERROR(assumption, def_includes_ptr, NOTE, "outer assumption clause defined here"); return 0; } + innermost_visit = tree->type; information = tree; def_includes_ptr = includes_ptr; r = validate_subtree(tree->inner); @@ -251,30 +254,31 @@ static int validate_information(mds_kbdc_tree_information_t* restrict tree) static int validate_assumption(mds_kbdc_tree_assumption_t* restrict tree) { int r; - if (function) + if (VISITING(FUNCTION)) { NEW_ERROR(tree, includes_ptr, ERROR, "assumption clause inside function definition"); NEW_ERROR(function, def_includes_ptr, NOTE, "outer function definition defined here"); return 0; } - else if (macro) + else if (VISITING(MACRO)) { NEW_ERROR(tree, includes_ptr, ERROR, "assumption clause inside macro definition"); NEW_ERROR(macro, def_includes_ptr, NOTE, "outer macro defined here"); return 0; } - else if (information) + else if (VISITING(INFORMATION)) { NEW_ERROR(tree, includes_ptr, ERROR, "assumption clause inside information clause"); NEW_ERROR(information, def_includes_ptr, NOTE, "outer information clause defined here"); return 0; } - else if (assumption) + else if (VISITING(ASSUMPTION)) { NEW_ERROR(tree, includes_ptr, ERROR, "nested assumption clause"); NEW_ERROR(assumption, def_includes_ptr, NOTE, "outer assumption clause defined here"); return 0; } + innermost_visit = tree->type; assumption = tree; def_includes_ptr = includes_ptr; r = validate_subtree(tree->inner); @@ -300,11 +304,11 @@ static int validate_map(mds_kbdc_tree_map_t* restrict tree) * at this process level, determine whether a * value-statement is used correctly or not. */ - else if (information) + else if (VISITING(INFORMATION)) NEW_ERROR(tree, includes_ptr, ERROR, "mapping-statement inside information clause"); - else if (assumption) + else if (VISITING(ASSUMPTION)) NEW_ERROR(tree, includes_ptr, ERROR, "mapping-statement inside assumption clause"); - else if (function) + else if (VISITING(FUNCTION)) NEW_ERROR(tree, includes_ptr, ERROR, "mapping-statement inside function definition"); return 0; fail: @@ -320,11 +324,11 @@ static int validate_map(mds_kbdc_tree_map_t* restrict tree) */ static int validate_macro_call(mds_kbdc_tree_macro_call_t* restrict tree) { - if (information) + if (VISITING(INFORMATION)) NEW_ERROR(tree, includes_ptr, ERROR, "macro call inside information clause"); - else if (assumption) + else if (VISITING(ASSUMPTION)) NEW_ERROR(tree, includes_ptr, ERROR, "macro call inside assumption clause"); - else if (function) + else if (VISITING(FUNCTION)) NEW_ERROR(tree, includes_ptr, ERROR, "macro call inside function definition"); return 0; fail: @@ -454,6 +458,7 @@ static int validate_subtree(mds_kbdc_tree_t* restrict tree) { #define v(type) fail_if (validate_##type(&(tree->type))) #define V(type) fail_if (validate_##type(&(tree->type##_))) + int old_innermost_visit = innermost_visit; again: if (tree == NULL) return 0; @@ -486,10 +491,11 @@ static int validate_subtree(mds_kbdc_tree_t* restrict tree) break; } + innermost_visit = old_innermost_visit; tree = tree->next; goto again; fail: - return -1; + return innermost_visit = old_innermost_visit, -1; #undef V #undef v } @@ -517,5 +523,6 @@ int validate_tree(mds_kbdc_parsed_t* restrict result_) #undef NEW_ERROR +#undef VISITING #undef C diff --git a/test-files/mds-kbdc/validate-tree/valid/assumption-function b/test-files/mds-kbdc/validate-tree/valid/assumption-function new file mode 100644 index 0000000..8cdc5d5 --- /dev/null +++ b/test-files/mds-kbdc/validate-tree/valid/assumption-function @@ -0,0 +1,21 @@ +assumption + function digit/1 + "\add(\1 "0")" + end function +end assumption + +# (assumption (@ 1 0-10) +# (.inner +# (function (@ 2 2-10) ‘digit/1’ +# (.inner +# (map (@ 3 4-18) +# (.sequence +# (string (@ 3 4-18) ‘"\add(\1 "0")"’) +# ) +# (.result nil) +# ) +# ) +# ) +# ) +# ) + diff --git a/test-files/mds-kbdc/validate-tree/valid/assumption-macro b/test-files/mds-kbdc/validate-tree/valid/assumption-macro new file mode 100644 index 0000000..68d64d3 --- /dev/null +++ b/test-files/mds-kbdc/validate-tree/valid/assumption-macro @@ -0,0 +1,23 @@ +assumption + macro letter/1 + <letter \1> : \1 + end macro +end assumption + +# (assumption (@ 1 0-10) +# (.inner +# (macro (@ 2 2-7) ‘letter/1’ +# (.inner +# (map (@ 3 4-20) +# (.sequence +# (keys (@ 3 4-15) ‘<letter \1>’) +# ) +# (.result +# (string (@ 3 18-20) ‘\1’) +# ) +# ) +# ) +# ) +# ) +# ) + |