aboutsummaryrefslogtreecommitdiff
path: root/interpreter/print.c
diff options
context:
space:
mode:
Diffstat (limited to 'interpreter/print.c')
-rw-r--r--interpreter/print.c89
1 files changed, 62 insertions, 27 deletions
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