aboutsummaryrefslogtreecommitdiff
path: root/interpreter
diff options
context:
space:
mode:
Diffstat (limited to 'interpreter')
-rw-r--r--interpreter/.gitignore2
-rw-r--r--interpreter/Makefile2
-rw-r--r--interpreter/code.c8
-rw-r--r--interpreter/eval.c252
-rw-r--r--interpreter/graphs.c40
-rw-r--r--interpreter/graphs.h18
-rw-r--r--interpreter/print.c89
-rw-r--r--interpreter/print.h7
-rw-r--r--interpreter/syntax.h13
9 files changed, 246 insertions, 185 deletions
diff --git a/interpreter/.gitignore b/interpreter/.gitignore
index ea6faae..165017a 100644
--- a/interpreter/.gitignore
+++ b/interpreter/.gitignore
@@ -1,2 +1,4 @@
*.o
+graph-*.png
+graph-*.dot
fuspel
diff --git a/interpreter/Makefile b/interpreter/Makefile
index 99da737..2f13de3 100644
--- a/interpreter/Makefile
+++ b/interpreter/Makefile
@@ -1,4 +1,4 @@
-CFLAGS=-Wall -Wextra -Werror -s
+CFLAGS=-Wall -Wextra -Wno-format -Werror
DEPS=lex.h syntax.h print.h parse.h log.h eval.h mem.h code.h graphs.h
OBJ=fuspel.o lex.o syntax.o print.o parse.o log.o eval.o mem.o code.o graphs.o
diff --git a/interpreter/code.c b/interpreter/code.c
index d0b5416..e3cafa7 100644
--- a/interpreter/code.c
+++ b/interpreter/code.c
@@ -7,14 +7,14 @@
void fill_node_int(struct node** node, int i) {
free_node(*node, 1, 0);
- (*node)->kind = EXPR_INT;
+ (*node)->kind = NODE_INT;
(*node)->var1 = my_calloc(1, sizeof(int));
*((int*) (*node)->var1) = i;
}
void fill_node_name(struct node** node, char* s) {
free_node(*node, 1, 0);
- (*node)->kind = EXPR_NAME;
+ (*node)->kind = NODE_NAME;
(*node)->var1 = my_calloc(1, strlen(s) + 1);
strcpy((*node)->var1, s);
}
@@ -24,14 +24,14 @@ void code_time(struct node** result) {
}
void code_mul(struct node** result, struct node* a, struct node* b) {
- if (a->kind != EXPR_INT || b->kind != EXPR_INT)
+ if (a->kind != NODE_INT || b->kind != NODE_INT)
fill_node_name(result, "mul on non-ints");
else
fill_node_int(result, *((int*) a->var1) * *((int*) b->var1));
}
void code_sub(struct node** result, struct node* a, struct node* b) {
- if (a->kind != EXPR_INT || b->kind != EXPR_INT)
+ if (a->kind != NODE_INT || b->kind != NODE_INT)
fill_node_name(result, "sub on non-ints");
else
fill_node_int(result, *((int*) b->var1) - *((int*) a->var1));
diff --git a/interpreter/eval.c b/interpreter/eval.c
index 7e762ef..a0c9e54 100644
--- a/interpreter/eval.c
+++ b/interpreter/eval.c
@@ -6,88 +6,97 @@
#include "graphs.h"
#include "mem.h"
-#ifdef _FUSPEL_DEBUG
#include "print.h"
-#endif
typedef struct {
char* name;
struct node* node;
} replacement;
-typedef struct {
- unsigned int length;
- replacement replacements[1];
+typedef struct replacements {
+ replacement replacement;
+ struct replacements* rest;
} replacements;
-void eval(fuspel* rules, struct node** node,
- replacements** repls, nodes_array** to_free, unsigned to_rnf);
+void eval(fuspel* rules, struct node** node, replacements* repls,
+ unsigned to_rnf);
-replacements* push_repl(replacements* repls, char* name, struct node* node) {
- unsigned int i;
- for (i = 0; i < repls->length && repls->replacements[i].name; i++);
- if (repls->replacements[i].name)
- repls = my_realloc(repls, sizeof(replacements) +
- 2 * repls->length * sizeof(replacement));
- repls->replacements[i].name = name;
- repls->replacements[i].node = node;
- repls->replacements[i + 1].name = NULL;
- repls->replacements[i + 1].node = NULL;
- return repls;
+void push_repl(replacements* repls, char* name, struct node* node) {
+ 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->rest = NULL;
+}
+
+void free_repls(replacements* repls) {
+ if (repls) {
+ if (repls->rest) {
+ free_repls(repls->rest);
+ my_free(repls->rest);
+ repls->rest = NULL;
+ }
+ repls->replacement.name = NULL;
+ repls->replacement.node = NULL;
+ }
}
void replace_all(replacements* repls, struct node** node) {
- unsigned char i;
unsigned int org_used_count;
if (!node || !*node)
return;
switch ((*node)->kind) {
- case EXPR_INT:
- case EXPR_CODE:
+ case NODE_INT:
+ case NODE_CODE:
break;
- case EXPR_NAME:
- for (i = 0; repls->replacements[i].name; i++) {
- if (!strcmp(repls->replacements[i].name,
+ case NODE_NAME:
+ for (; repls && repls; repls = repls->rest) {
+ if (repls->replacement.name && repls->replacement.node &&
+ !strcmp(repls->replacement.name,
(char*) (*node)->var1)) {
+ printf("Replacing %s with %p on %p / %p\n",
+ (char*) (*node)->var1,
+ repls->replacement.node,
+ node,
+ *node);
org_used_count = (*node)->used_count;
free_node(*node, 1, 1);
- *node = repls->replacements[i].node;
+ *node = repls->replacement.node;
use_node(*node, org_used_count);
break;
}
}
break;
- case EXPR_LIST:
- case EXPR_TUPLE:
- case EXPR_APP:
+ case NODE_LIST:
+ case NODE_TUPLE:
+ case NODE_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;
+struct node*** flatten_app_args(struct node** from) {
+ struct node ***result;
unsigned int i;
unsigned char len = 0;
- struct node* _from = from;
+ struct node* _from = *from;
- while (_from->kind == EXPR_APP) {
+ while (_from->kind == NODE_APP) {
len++;
_from = _from->var1;
}
len++;
- result = my_calloc(1, sizeof(struct node*) * (len + 1));
+ result = my_calloc(1, sizeof(struct node**) * (len + 1));
i = 1;
- while (from->kind == EXPR_APP) {
- result[len - i] = from->var2;
- from = from->var1;
+ while ((*from)->kind == NODE_APP) {
+ result[len - i] = (struct node**) &(*from)->var2;
+ from = (struct node**) &(*from)->var1;
i++;
}
result[0] = from;
@@ -96,58 +105,62 @@ struct node** flatten_app_args(struct node* from) {
}
unsigned match_expr(fuspel* rules, expression* expr, struct node** node,
- replacements** repls, nodes_array** to_free) {
+ replacements* repls) {
+ replacements* _repls;
+ for (_repls = repls; _repls->rest; _repls = _repls->rest);
- if (expr->kind != EXPR_NAME)
- eval(rules, node, repls, to_free, 1);
+ if (expr->kind == EXPR_INT ||
+ expr->kind == EXPR_LIST ||
+ expr->kind == EXPR_TUPLE)
+ eval(rules, node, NULL, 1);
switch (expr->kind) {
case EXPR_INT:
return *((int*) (*node)->var1) == *((int*) expr->var1);
case EXPR_NAME:
- *repls = push_repl(*repls, (char*) expr->var1, *node);
+ push_repl(_repls, (char*) expr->var1, *node);
return 1;
case EXPR_LIST:
case EXPR_TUPLE:
- if ((*node)->kind != expr->kind)
+ if ((int) (*node)->kind != (int) expr->kind)
return 0;
- *to_free = push_node(*to_free, *node);
-
if (!expr->var1)
return (*node)->var1 == NULL;
return
- match_expr(rules, expr->var1, (struct node**) &(*node)->var1, repls, to_free) &&
- match_expr(rules, expr->var2, (struct node**) &(*node)->var2, repls, to_free);
+ match_expr(rules, expr->var1, (struct node**) &(*node)->var1, _repls) &&
+ match_expr(rules, expr->var2, (struct node**) &(*node)->var2, _repls);
default:
return 0;
}
}
-int match_rule(fuspel* rules, rewrite_rule* rule, struct node* node,
- replacements** repls, nodes_array** to_free) {
- struct node** node_args;
+int match_rule(fuspel* rules, rewrite_rule* rule, struct node** node,
+ replacements* repls) {
+ struct node*** node_args;
unsigned char i;
- switch (node->kind) {
- case EXPR_NAME:
- return (strcmp(rule->name, (char*) node->var1)) ? -1 : 0;
+ switch ((*node)->kind) {
+ case NODE_NAME:
+ return (strcmp(rule->name, (char*) (*node)->var1)) ? -1 : 0;
break;
- case EXPR_APP:
+ case NODE_APP:
node_args = flatten_app_args(node);
i = 0;
- if (!strcmp(node_args[0]->var1, rule->name)) {
- struct node* node = node_args[++i];
+ if (!strcmp((*node_args[0])->var1, rule->name)) {
+ struct node** node = node_args[++i];
arg_list* args = rule->args;
unsigned char args_len = len_arg_list(args);
+ printf("RULE: %s\n", rule->name);
+
while (!empty_args_list(args)) {
- if (!match_expr(rules, &args->elem, &node, repls, to_free)) {
+ if (!match_expr(rules, &args->elem, node, repls)) {
my_free(node_args);
return -1;
}
@@ -175,33 +188,32 @@ int match_rule(fuspel* rules, rewrite_rule* rule, struct node* node,
}
unsigned is_code_app(struct node* node) {
- for (; node->kind == EXPR_APP; node = node->var1);
- return node->kind == EXPR_CODE;
+ for (; node->kind == NODE_APP; node = node->var1);
+ return node->kind == NODE_CODE;
}
-void eval_code_app(fuspel* rules, struct node** node,
- replacements** repls, nodes_array** to_free) {
- struct node *root, **args;
+void eval_code_app(fuspel* rules, struct node** node, replacements* repls) {
+ struct node *root, ***args;
Code_1* f1;
Code_2* f2;
unsigned char i;
- for (root = *node; root->kind == EXPR_APP; root = root->var1);
- if (root->kind != EXPR_CODE || !root->var1)
+ for (root = *node; root->kind == NODE_APP; root = root->var1);
+ if (root->kind != NODE_CODE || !root->var1)
return;
- args = flatten_app_args(*node);
+ args = flatten_app_args(node);
for (i = 1; i <= *((unsigned char*) root->var2); i++)
- eval(rules, &args[i], repls, to_free, 0);
+ eval(rules, args[i], repls, 0);
switch (*((unsigned char*) root->var2)) {
case 1:
f1 = (Code_1*) root->var1;
- f1(node, args[1]);
+ f1(node, *args[1]);
case 2:
f2 = (Code_2*) root->var1;
- f2(node, args[1], args[2]);
+ f2(node, *args[1], *args[2]);
}
use_node(*node, 1);
@@ -210,136 +222,150 @@ void eval_code_app(fuspel* rules, struct node** node,
}
#ifdef _FUSPEL_DEBUG
-struct node* root_node;
+struct node** root_node;
#endif
-void eval(fuspel* rules, struct node** node,
- replacements** repls, nodes_array** to_free, unsigned to_rnf) {
+void eval(fuspel* rules, struct node** node, replacements* repls,
+ unsigned to_rnf) {
fuspel* _rules;
- unsigned rerun;
+ unsigned rerun, do_free_repls = 0;
if (!node || !*node)
return;
- if (!*repls) {
- *repls = my_calloc(1, sizeof(replacements) + 10 * sizeof(replacement));
- (*repls)->length = 10;
- }
-
- if (!*to_free) {
- *to_free = my_calloc(1, sizeof(nodes_array) + 10 * sizeof(struct node*));
- (*to_free)->length = 10;
+ if (!repls) {
+ repls = my_calloc(1, sizeof(replacements));
+ do_free_repls = 1;
}
#ifdef _FUSPEL_DEBUG
if (!root_node) {
- root_node = *node;
- print_node_to_file(root_node, NULL);
+ root_node = node;
+ print_node_to_file(*root_node, NULL, NULL);
}
#endif
do {
+ replacements* _repls;
+
rerun = 0;
+ printf("\nREWRITING %p / %p: ", node, *node);
+ print_node(*node);
+ printf("... (repls %p)\n", repls);
+
switch ((*node)->kind) {
- case EXPR_INT:
+ case NODE_INT:
break;
- case EXPR_NAME:
- case EXPR_APP:
+ case NODE_NAME:
+ case NODE_APP:
if (is_code_app(*node)) {
- eval_code_app(rules, node, repls, to_free);
+ eval_code_app(rules, node, repls);
rerun = 1;
break;
}
+ for (_repls = repls; _repls->rest; _repls = _repls->rest);
+
_rules = rules;
while (_rules) {
int add_args = match_rule(
- rules, &_rules->rule, *node, repls, to_free);
+ rules, &_rules->rule, node, _repls);
if (add_args >= 0) {
unsigned char j;
unsigned int org_used_count;
+ replacements* __repls;
struct node** _node = node;
+ struct node* new_node = my_calloc(1, sizeof(struct node));
for (j = 0; j < add_args; j++)
_node = (struct node**) &(*_node)->var1;
org_used_count = (*_node)->used_count;
- for (j = 0; (*repls)->replacements[j].node; j++)
- use_node((*repls)->replacements[j].node, 1);
+ for (__repls = _repls->rest;
+ __repls && __repls->replacement.node;
+ __repls = __repls->rest)
+ use_node(__repls->replacement.node, 1);
+
+ printf("Replacing <");
+ print_node(*_node);
+ printf(">: <");
+ cpy_expression_to_node(new_node, &_rules->rule.rhs);
+ print_node(new_node);
+ printf(">\n");
- free_node(*_node, 1, 0);
- cpy_expression_to_node(*_node, &_rules->rule.rhs);
- replace_all(*repls, _node);
- use_node(*_node, org_used_count - 1);
+ replace_all(_repls->rest, &new_node);
+ use_node(new_node, org_used_count - 1);
- for (j = 0; (*repls)->replacements[j].node; j++)
- free_node((*repls)->replacements[j].node, add_args + 1, 1);
+ for (__repls = _repls->rest;
+ __repls && __repls->replacement.node;
+ __repls = __repls->rest)
+ free_node(__repls->replacement.node, 1, 1);
- (*to_free)->nodes[0] = NULL;
- (*repls)->replacements[0].name = NULL;
- (*repls)->replacements[0].node = NULL;
+ free_node(*_node, 1, 1);
+ *_node = new_node;
rerun = 1;
break;
}
- (*to_free)->nodes[0] = NULL;
- (*repls)->replacements[0].name = NULL;
- (*repls)->replacements[0].node = NULL;
+ free_repls(_repls->rest);
_rules = _rules->rest;
}
+
+ free_repls(_repls);
break;
- case EXPR_LIST:
+ case NODE_LIST:
if (!(*node)->var1)
break;
- case EXPR_TUPLE:
+ case NODE_TUPLE:
if (to_rnf)
break;
- eval(rules, (struct node**) &(*node)->var1, repls, to_free, to_rnf);
- eval(rules, (struct node**) &(*node)->var2, repls, to_free, to_rnf);
+ eval(rules, (struct node**) &(*node)->var1, repls, to_rnf);
+ eval(rules, (struct node**) &(*node)->var2, repls, to_rnf);
break;
- case EXPR_CODE:
+ case NODE_CODE:
//TODO
break;
}
#ifdef _FUSPEL_DEBUG
if (rerun)
- print_node_to_file(root_node, NULL);
+ print_node_to_file(*root_node, NULL, NULL);
#endif
} while (rerun);
+
+ if (do_free_repls) {
+ free_repls(repls);
+ my_free(repls);
+ }
}
expression* eval_main(fuspel* rules) {
struct node* main_node = my_calloc(1, sizeof(struct node));
expression* expr = my_calloc(1, sizeof(expression));
- replacements** repls = my_calloc(1, sizeof(replacements*));
- nodes_array** to_free = my_calloc(1, sizeof(nodes_array*));
+ replacements* repls = my_calloc(1, sizeof(replacements));
main_node->kind = EXPR_NAME;
main_node->used_count = 1;
main_node->var1 = my_calloc(1, 5);
strcpy(main_node->var1, "main");
- eval(rules, &main_node, repls, to_free, 0);
+ eval(rules, &main_node, repls, 0);
cpy_node_to_expression(expr, main_node);
- 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);
+ free_repls(repls);
my_free(repls);
- my_free(to_free);
return expr;
}
diff --git a/interpreter/graphs.c b/interpreter/graphs.c
index d802b0f..ad70abb 100644
--- a/interpreter/graphs.c
+++ b/interpreter/graphs.c
@@ -10,9 +10,9 @@ void use_node(struct node* node, unsigned int count) {
node->used_count += count;
- if (node->kind == EXPR_LIST ||
- node->kind == EXPR_TUPLE ||
- node->kind == EXPR_APP) {
+ if (node->kind == NODE_LIST ||
+ node->kind == NODE_TUPLE ||
+ node->kind == NODE_APP) {
use_node(node->var1, count);
use_node(node->var2, count);
}
@@ -24,18 +24,18 @@ void free_node(struct node* node, unsigned int count, unsigned free_first) {
node->used_count -= count;
- if (node->kind == EXPR_LIST ||
- node->kind == EXPR_TUPLE ||
- node->kind == EXPR_APP) {
+ if (node->kind == NODE_LIST ||
+ node->kind == NODE_TUPLE ||
+ node->kind == NODE_APP) {
free_node((struct node*) node->var1, count, 1);
free_node((struct node*) node->var2, count, 1);
}
if (node->used_count == 0) {
- if (node->kind == EXPR_INT || node->kind == EXPR_NAME)
+ if (node->kind == NODE_INT || node->kind == NODE_NAME)
my_free(node->var1);
- if (node->kind == EXPR_CODE)
+ if (node->kind == NODE_CODE)
my_free(node->var2);
if (free_first)
@@ -43,17 +43,6 @@ void free_node(struct node* node, unsigned int count, unsigned free_first) {
}
}
-nodes_array* push_node(nodes_array* nodes, struct node* node) {
- unsigned int i;
- for (i = 0; i < nodes->length && nodes->nodes[i]; i++);
- if (nodes->nodes[i])
- nodes = my_realloc(nodes, sizeof(nodes_array) +
- 2 * nodes->length * sizeof(*node));
- nodes->nodes[i] = node;
- nodes->nodes[i + 1] = NULL;
- return nodes;
-}
-
void cpy_expression_to_node(struct node* dst, expression* src) {
if (!dst || !src)
return;
@@ -102,25 +91,25 @@ void cpy_node_to_expression(expression* dst, struct node* src) {
dst->kind = src->kind;
switch (src->kind) {
- case EXPR_INT:
+ case NODE_INT:
dst->var1 = my_calloc(1, sizeof(int));
*((int*) dst->var1) = *((int*) src->var1);
break;
- case EXPR_NAME:
+ case NODE_NAME:
dst->var1 = my_calloc(1, 1 + strlen((char*) src->var1));
strcpy(dst->var1, src->var1);
break;
- case EXPR_CODE:
+ case NODE_CODE:
dst->var1 = src->var1;
dst->var2 = my_calloc(1, sizeof(unsigned char));
*((unsigned char*) dst->var2) = *((unsigned char*) src->var2);
break;
- case EXPR_LIST:
- case EXPR_TUPLE:
- case EXPR_APP:
+ case NODE_LIST:
+ case NODE_TUPLE:
+ case NODE_APP:
dst->var1 = dst->var2 = NULL;
if (src->var1) {
dst->var1 = my_calloc(1, sizeof(expression));
@@ -130,5 +119,6 @@ void cpy_node_to_expression(expression* dst, struct node* src) {
dst->var2 = my_calloc(1, sizeof(expression));
cpy_node_to_expression(dst->var2, src->var2);
}
+ break;
}
}
diff --git a/interpreter/graphs.h b/interpreter/graphs.h
index f127642..fcb314e 100644
--- a/interpreter/graphs.h
+++ b/interpreter/graphs.h
@@ -3,23 +3,25 @@
#include "syntax.h"
+typedef enum {
+ NODE_INT, /* See expr_kind in syntax.h */
+ NODE_NAME,
+ NODE_CODE,
+ NODE_LIST,
+ NODE_TUPLE,
+ NODE_APP,
+} node_kind;
+
struct node {
- expr_kind kind;
+ node_kind kind;
void* var1;
void* var2;
unsigned int used_count;
};
-typedef struct {
- unsigned int length;
- struct node* nodes[1];
-} nodes_array;
-
void use_node(struct node* node, unsigned int count);
void free_node(struct node* node, unsigned int count, unsigned free_first);
-nodes_array* push_node(nodes_array* nodes, struct node* node);
-
void cpy_expression_to_node(struct node* dst, expression* src);
void cpy_node_to_expression(expression* dst, struct node* src);
diff --git a/interpreter/print.c b/interpreter/print.c
index fa784ed..9b65a7f 100644
--- a/interpreter/print.c
+++ b/interpreter/print.c
@@ -126,14 +126,45 @@ void print_node(struct node* node) {
#ifdef _FUSPEL_DEBUG
static unsigned int file_count = 0;
-void print_node_to_file(struct node* node, FILE* f) {
+void free_visited_nodes(struct visited_nodes *list) {
+ if (list) {
+ free_visited_nodes(list->next);
+ my_free(list);
+ }
+}
+
+void push_visited_node(struct visited_nodes *list, struct node *node) {
+ while (list->next) list = list->next;
+ list->next = my_calloc(1, sizeof(struct visited_nodes));
+ list->next->node = node;
+}
+
+unsigned visited_node_exists(struct visited_nodes *list, struct node *node) {
+ while (list) {
+ if (list->node == node)
+ return 1;
+ list = list->next;
+ }
+ return 0;
+}
+
+void print_node_to_file(struct node* node, FILE* f, struct visited_nodes *visited) {
unsigned close = 0;
+ unsigned do_free_visited = 0;
- if (!node)
+ if (visited_node_exists(visited, node))
return;
+ if (!visited) {
+ visited = my_calloc(1, sizeof(struct visited_nodes));
+ do_free_visited = 1;
+ }
+
+ push_visited_node(visited, node);
+
if (!f) {
char fname[20];
+ printf(" === Drawing graph %d ===\n", file_count);
sprintf(fname, "graph-%03u.dot", file_count++);
f = fopen(fname, "w");
fprintf(f, "digraph {\n");
@@ -142,39 +173,39 @@ void print_node_to_file(struct node* node, FILE* f) {
}
switch (node->kind) {
- case EXPR_INT:
- fprintf(f, "%d [label=\"%d (%d)\"];\n",
- node, *((int*) node->var1), node->used_count);
+ case NODE_INT:
+ fprintf(f, "%d [label=\"%p: %d (%d)\", penwidth=%d];\n",
+ node, node, *((int*) node->var1), node->used_count, node->used_count);
break;
- case EXPR_NAME:
- fprintf(f, "%d [label=\"%s (%d)\"];\n",
- node, (char*) node->var1, node->used_count);
+ case NODE_NAME:
+ fprintf(f, "%d [label=\"%p: %s (%d)\", penwidth=%d];\n",
+ node, node, (char*) node->var1, node->used_count, node->used_count);
break;
- case EXPR_CODE:
- fprintf(f, "%d [label=\"code: %p (%d)\"];\n",
- node, node->var1, node->used_count);
+ case NODE_CODE:
+ fprintf(f, "%d [label=\"%p: code: %p (%d)\", penwidth=%d];\n",
+ node, node, node->var1, node->used_count, 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);
+ case NODE_LIST:
+ case NODE_TUPLE:
+ case NODE_APP:
+ if (node->kind == NODE_LIST)
+ fprintf(f, "%d [label=\"%p: List (%d)\", penwidth=%d];\n",
+ node, node, node->used_count, node->used_count);
+ else if (node->kind == NODE_TUPLE)
+ fprintf(f, "%d [label=\"%p: Tuple (%d)\", penwidth=%d];\n",
+ node, node, node->used_count, node->used_count);
+ else if (node->kind == NODE_APP)
+ fprintf(f, "%d [label=\"%p: App (%d)\", penwidth=%d];\n",
+ node, node, node->used_count, 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);
+ print_node_to_file((struct node*) node->var1, f, visited);
+ print_node_to_file((struct node*) node->var2, f, visited);
+ fprintf(f, "%d -> %d [label=\"l\", penwidth=%d];\n", node, node->var1, node->used_count);
+ fprintf(f, "%d -> %d [label=\"r\", penwidth=%d];\n", node, node->var2, node->used_count);
}
break;
}
@@ -183,5 +214,9 @@ void print_node_to_file(struct node* node, FILE* f) {
fprintf(f, "}");
fclose(f);
}
+
+ if (do_free_visited) {
+ free_visited_nodes(visited);
+ }
}
#endif
diff --git a/interpreter/print.h b/interpreter/print.h
index 047a7f7..cc191b9 100644
--- a/interpreter/print.h
+++ b/interpreter/print.h
@@ -16,7 +16,12 @@ void print_fuspel(fuspel*);
void print_node(struct node*);
#ifdef _FUSPEL_DEBUG
-void print_node_to_file(struct node*, FILE*);
+struct visited_nodes {
+ struct node* node;
+ struct visited_nodes* next;
+};
+
+void print_node_to_file(struct node*, FILE*, struct visited_nodes*);
#endif
#endif
diff --git a/interpreter/syntax.h b/interpreter/syntax.h
index f6b9f01..9153492 100644
--- a/interpreter/syntax.h
+++ b/interpreter/syntax.h
@@ -35,12 +35,13 @@ void free_token_list(token_list*);
/* ELEMENTS */
typedef enum {
- EXPR_INT,
- EXPR_NAME,
- EXPR_CODE,
- EXPR_LIST,
- EXPR_TUPLE,
- EXPR_APP
+ EXPR_INT, /* var1: pointer to int */
+ EXPR_NAME, /* var1: pointer to char* */
+ EXPR_CODE, /* var1: pointer to function;
+ var2: pointer to unsigned char (nr. of arguments) */
+ EXPR_LIST, /* var1, var2: pointers to expression OR (nil) */
+ EXPR_TUPLE, /* var1, var2: pointers to expression */
+ EXPR_APP, /* var1, var2: pointers to expression */
} expr_kind;
typedef struct {