diff options
author | Camil Staps | 2016-09-24 10:33:10 +0200 |
---|---|---|
committer | Camil Staps | 2016-09-24 10:33:10 +0200 |
commit | 61cc1ddcc0de9c58a5c364562c6f110c8001e72d (patch) | |
tree | 247c17d670ba1aa33613f6a08a1880aed1b42d33 | |
parent | Working graphs (?) (diff) |
Fixed strictness annotations
-rw-r--r-- | interpreter/eval.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/interpreter/eval.c b/interpreter/eval.c index a0c9e54..5efd0d8 100644 --- a/interpreter/eval.c +++ b/interpreter/eval.c @@ -11,6 +11,7 @@ typedef struct { char* name; struct node* node; + unsigned is_strict; } replacement; typedef struct replacements { @@ -21,11 +22,12 @@ typedef struct replacements { void eval(fuspel* rules, struct node** node, replacements* repls, unsigned to_rnf); -void push_repl(replacements* repls, char* name, struct node* node) { +void push_repl(replacements* repls, char* name, struct node* node, unsigned is_strict) { while (repls->rest) repls = repls->rest; repls->rest = my_calloc(1, sizeof(replacements)); repls->rest->replacement.name = name; repls->rest->replacement.node = node; + repls->rest->replacement.is_strict = is_strict; repls->rest->rest = NULL; } @@ -38,10 +40,11 @@ void free_repls(replacements* repls) { } repls->replacement.name = NULL; repls->replacement.node = NULL; + repls->replacement.is_strict = 0; } } -void replace_all(replacements* repls, struct node** node) { +void replace_all(fuspel *rules, replacements* repls, struct node** node) { unsigned int org_used_count; if (!node || !*node) @@ -66,6 +69,8 @@ void replace_all(replacements* repls, struct node** node) { free_node(*node, 1, 1); *node = repls->replacement.node; use_node(*node, org_used_count); + if (repls->replacement.is_strict) + eval(rules, node, NULL, 0); break; } } @@ -74,8 +79,8 @@ void replace_all(replacements* repls, struct node** node) { case NODE_LIST: case NODE_TUPLE: case NODE_APP: - replace_all(repls, (struct node**) &(*node)->var1); - replace_all(repls, (struct node**) &(*node)->var2); + replace_all(rules, repls, (struct node**) &(*node)->var1); + replace_all(rules, repls, (struct node**) &(*node)->var2); break; } } @@ -105,10 +110,12 @@ struct node*** flatten_app_args(struct node** from) { } unsigned match_expr(fuspel* rules, expression* expr, struct node** node, - replacements* repls) { + replacements* repls, unsigned is_strict) { replacements* _repls; for (_repls = repls; _repls->rest; _repls = _repls->rest); + is_strict |= expr->is_strict; + if (expr->kind == EXPR_INT || expr->kind == EXPR_LIST || expr->kind == EXPR_TUPLE) @@ -119,7 +126,7 @@ unsigned match_expr(fuspel* rules, expression* expr, struct node** node, return *((int*) (*node)->var1) == *((int*) expr->var1); case EXPR_NAME: - push_repl(_repls, (char*) expr->var1, *node); + push_repl(_repls, (char*) expr->var1, *node, is_strict); return 1; case EXPR_LIST: @@ -131,8 +138,8 @@ unsigned match_expr(fuspel* rules, expression* expr, struct node** node, return (*node)->var1 == NULL; return - match_expr(rules, expr->var1, (struct node**) &(*node)->var1, _repls) && - match_expr(rules, expr->var2, (struct node**) &(*node)->var2, _repls); + match_expr(rules, expr->var1, (struct node**) &(*node)->var1, _repls, is_strict) && + match_expr(rules, expr->var2, (struct node**) &(*node)->var2, _repls, is_strict); default: return 0; @@ -160,7 +167,7 @@ int match_rule(fuspel* rules, rewrite_rule* rule, struct node** node, printf("RULE: %s\n", rule->name); while (!empty_args_list(args)) { - if (!match_expr(rules, &args->elem, node, repls)) { + if (!match_expr(rules, &args->elem, node, repls, 0)) { my_free(node_args); return -1; } @@ -297,7 +304,7 @@ void eval(fuspel* rules, struct node** node, replacements* repls, print_node(new_node); printf(">\n"); - replace_all(_repls->rest, &new_node); + replace_all(rules, _repls->rest, &new_node); use_node(new_node, org_used_count - 1); for (__repls = _repls->rest; |