aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--interpreter/code.c4
-rw-r--r--interpreter/eval.c76
-rw-r--r--interpreter/graphs.c8
-rw-r--r--interpreter/graphs.h2
-rw-r--r--interpreter/print.c63
-rw-r--r--interpreter/print.h6
6 files changed, 122 insertions, 37 deletions
diff --git a/interpreter/code.c b/interpreter/code.c
index c194d02..d0b5416 100644
--- a/interpreter/code.c
+++ b/interpreter/code.c
@@ -6,14 +6,14 @@
#include "mem.h"
void fill_node_int(struct node** node, int i) {
- free_node(*node, 0);
+ free_node(*node, 1, 0);
(*node)->kind = EXPR_INT;
(*node)->var1 = my_calloc(1, sizeof(int));
*((int*) (*node)->var1) = i;
}
void fill_node_name(struct node** node, char* s) {
- free_node(*node, 0);
+ free_node(*node, 1, 0);
(*node)->kind = EXPR_NAME;
(*node)->var1 = my_calloc(1, strlen(s) + 1);
strcpy((*node)->var1, s);
diff --git a/interpreter/eval.c b/interpreter/eval.c
index 74b869a..7e762ef 100644
--- a/interpreter/eval.c
+++ b/interpreter/eval.c
@@ -6,6 +6,10 @@
#include "graphs.h"
#include "mem.h"
+#ifdef _FUSPEL_DEBUG
+#include "print.h"
+#endif
+
typedef struct {
char* name;
struct node* node;
@@ -35,43 +39,38 @@ replacements* push_repl(replacements* repls, char* name, struct node* node) {
void replace_all(replacements* repls, struct node** node) {
unsigned char i;
unsigned int org_used_count;
- unsigned rerun = 1;
if (!node || !*node)
return;
- while (rerun) {
- rerun = 0;
-
- switch ((*node)->kind) {
- case EXPR_INT:
- case EXPR_CODE:
- break;
+ switch ((*node)->kind) {
+ case EXPR_INT:
+ case EXPR_CODE:
+ break;
- case EXPR_NAME:
- for (i = 0; repls->replacements[i].name; i++) {
- if (!strcmp(repls->replacements[i].name,
- (char*) (*node)->var1)) {
- org_used_count = (*node)->used_count;
- free_node(*node, 1);
- *node = repls->replacements[i].node;
- use_node(*node, org_used_count);
- rerun = 1;
- break;
- }
+ case EXPR_NAME:
+ for (i = 0; repls->replacements[i].name; i++) {
+ if (!strcmp(repls->replacements[i].name,
+ (char*) (*node)->var1)) {
+ org_used_count = (*node)->used_count;
+ free_node(*node, 1, 1);
+ *node = repls->replacements[i].node;
+ use_node(*node, org_used_count);
+ break;
}
- break;
+ }
+ break;
- case EXPR_LIST:
- case EXPR_TUPLE:
- case EXPR_APP:
- replace_all(repls, (struct node**) &(*node)->var1);
- replace_all(repls, (struct node**) &(*node)->var2);
- break;
- }
+ case EXPR_LIST:
+ case EXPR_TUPLE:
+ case EXPR_APP:
+ replace_all(repls, (struct node**) &(*node)->var1);
+ replace_all(repls, (struct node**) &(*node)->var2);
+ break;
}
}
+
struct node** flatten_app_args(struct node* from) {
struct node** result;
unsigned int i;
@@ -210,6 +209,10 @@ void eval_code_app(fuspel* rules, struct node** node,
my_free(args);
}
+#ifdef _FUSPEL_DEBUG
+struct node* root_node;
+#endif
+
void eval(fuspel* rules, struct node** node,
replacements** repls, nodes_array** to_free, unsigned to_rnf) {
fuspel* _rules;
@@ -228,6 +231,13 @@ void eval(fuspel* rules, struct node** node,
(*to_free)->length = 10;
}
+#ifdef _FUSPEL_DEBUG
+ if (!root_node) {
+ root_node = *node;
+ print_node_to_file(root_node, NULL);
+ }
+#endif
+
do {
rerun = 0;
@@ -261,13 +271,13 @@ void eval(fuspel* rules, struct node** node,
for (j = 0; (*repls)->replacements[j].node; j++)
use_node((*repls)->replacements[j].node, 1);
- free_node(*_node, 0);
+ free_node(*_node, 1, 0);
cpy_expression_to_node(*_node, &_rules->rule.rhs);
replace_all(*repls, _node);
use_node(*_node, org_used_count - 1);
for (j = 0; (*repls)->replacements[j].node; j++)
- free_node((*repls)->replacements[j].node, 1);
+ free_node((*repls)->replacements[j].node, add_args + 1, 1);
(*to_free)->nodes[0] = NULL;
(*repls)->replacements[0].name = NULL;
@@ -300,6 +310,11 @@ void eval(fuspel* rules, struct node** node,
//TODO
break;
}
+
+#ifdef _FUSPEL_DEBUG
+ if (rerun)
+ print_node_to_file(root_node, NULL);
+#endif
} while (rerun);
}
@@ -318,7 +333,8 @@ expression* eval_main(fuspel* rules) {
cpy_node_to_expression(expr, main_node);
- free_node(main_node, 1);
+ printf("main is used %d time(s)\n", main_node->used_count);
+ free_node(main_node, 1, 1);
my_free(*repls);
my_free(*to_free);
diff --git a/interpreter/graphs.c b/interpreter/graphs.c
index 34877a2..d802b0f 100644
--- a/interpreter/graphs.c
+++ b/interpreter/graphs.c
@@ -18,17 +18,17 @@ void use_node(struct node* node, unsigned int count) {
}
}
-void free_node(struct node* node, unsigned free_first) {
+void free_node(struct node* node, unsigned int count, unsigned free_first) {
if (!node)
return;
- node->used_count--;
+ node->used_count -= count;
if (node->kind == EXPR_LIST ||
node->kind == EXPR_TUPLE ||
node->kind == EXPR_APP) {
- free_node((struct node*) node->var1, 1);
- free_node((struct node*) node->var2, 1);
+ free_node((struct node*) node->var1, count, 1);
+ free_node((struct node*) node->var2, count, 1);
}
if (node->used_count == 0) {
diff --git a/interpreter/graphs.h b/interpreter/graphs.h
index 07ca663..f127642 100644
--- a/interpreter/graphs.h
+++ b/interpreter/graphs.h
@@ -16,7 +16,7 @@ typedef struct {
} nodes_array;
void use_node(struct node* node, unsigned int count);
-void free_node(struct node* node, unsigned free_first);
+void free_node(struct node* node, unsigned int count, unsigned free_first);
nodes_array* push_node(nodes_array* nodes, struct node* node);
diff --git a/interpreter/print.c b/interpreter/print.c
index edcedf3..fa784ed 100644
--- a/interpreter/print.c
+++ b/interpreter/print.c
@@ -122,3 +122,66 @@ void print_node(struct node* node) {
free_expression(e);
my_free(e);
}
+
+#ifdef _FUSPEL_DEBUG
+static unsigned int file_count = 0;
+
+void print_node_to_file(struct node* node, FILE* f) {
+ unsigned close = 0;
+
+ if (!node)
+ return;
+
+ if (!f) {
+ char fname[20];
+ sprintf(fname, "graph-%03u.dot", file_count++);
+ f = fopen(fname, "w");
+ fprintf(f, "digraph {\n");
+ fprintf(f, "node [shape=rectangle];\n");
+ close = 1;
+ }
+
+ switch (node->kind) {
+ case EXPR_INT:
+ fprintf(f, "%d [label=\"%d (%d)\"];\n",
+ node, *((int*) node->var1), node->used_count);
+ break;
+
+ case EXPR_NAME:
+ fprintf(f, "%d [label=\"%s (%d)\"];\n",
+ node, (char*) node->var1, node->used_count);
+ break;
+
+ case EXPR_CODE:
+ fprintf(f, "%d [label=\"code: %p (%d)\"];\n",
+ node, node->var1, node->used_count);
+ break;
+
+ case EXPR_LIST:
+ case EXPR_TUPLE:
+ case EXPR_APP:
+ if (node->kind == EXPR_LIST)
+ fprintf(f, "%d [label=\"List (%d)\"];\n",
+ node, node->used_count);
+ else if (node->kind == EXPR_TUPLE)
+ fprintf(f, "%d [label=\"Tuple (%d)\"];\n",
+ node, node->used_count);
+ else if (node->kind == EXPR_APP)
+ fprintf(f, "%d [label=\"App (%d)\"];\n",
+ node, node->used_count);
+
+ if (node->var1) {
+ print_node_to_file((struct node*) node->var1, f);
+ print_node_to_file((struct node*) node->var2, f);
+ fprintf(f, "%d -> %d;\n", node, node->var1);
+ fprintf(f, "%d -> %d;\n", node, node->var2);
+ }
+ break;
+ }
+
+ if (close) {
+ fprintf(f, "}");
+ fclose(f);
+ }
+}
+#endif
diff --git a/interpreter/print.h b/interpreter/print.h
index 544786f..047a7f7 100644
--- a/interpreter/print.h
+++ b/interpreter/print.h
@@ -4,6 +4,8 @@
#include "syntax.h"
#include "graphs.h"
+#include <stdio.h>
+
void print_token(token*);
void print_token_list(token_list*);
@@ -13,4 +15,8 @@ void print_fuspel(fuspel*);
void print_node(struct node*);
+#ifdef _FUSPEL_DEBUG
+void print_node_to_file(struct node*, FILE*);
+#endif
+
#endif