aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCamil Staps2016-09-24 10:33:10 +0200
committerCamil Staps2016-09-24 10:33:10 +0200
commit61cc1ddcc0de9c58a5c364562c6f110c8001e72d (patch)
tree247c17d670ba1aa33613f6a08a1880aed1b42d33
parentWorking graphs (?) (diff)
Fixed strictness annotations
-rw-r--r--interpreter/eval.c27
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;