From 61cc1ddcc0de9c58a5c364562c6f110c8001e72d Mon Sep 17 00:00:00 2001
From: Camil Staps
Date: Sat, 24 Sep 2016 10:33:10 +0200
Subject: Fixed strictness annotations

---
 interpreter/eval.c | 27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)

(limited to 'interpreter')

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;
-- 
cgit v1.2.3