aboutsummaryrefslogtreecommitdiff
path: root/interpreter
diff options
context:
space:
mode:
Diffstat (limited to 'interpreter')
-rw-r--r--interpreter/code.c73
-rw-r--r--interpreter/code.h4
-rw-r--r--interpreter/eval.c43
-rw-r--r--interpreter/graphs.c29
-rw-r--r--interpreter/graphs.h2
-rw-r--r--interpreter/print.c107
6 files changed, 164 insertions, 94 deletions
diff --git a/interpreter/code.c b/interpreter/code.c
index be9ece0..ddd8402 100644
--- a/interpreter/code.c
+++ b/interpreter/code.c
@@ -104,42 +104,49 @@ void code_ne(struct node** result, struct node* a, struct node* b) {
fill_node_bool(result, *((int*) a->var1) != *((int*) b->var1));
}
+struct code_mapping {
+ char* name;
+ void* f;
+ unsigned char arity;
+};
+
+static struct code_mapping code_table[] = {
+ { "time", code_time, 0 },
+ { "trace", code_trace, 2 },
+ { "add", code_add, 2 },
+ { "mul", code_mul, 2 },
+ { "sub", code_sub, 2 },
+ { "eq", code_eq, 2 },
+ { "ge", code_ge, 2 },
+ { "gt", code_gt, 2 },
+ { "le", code_le, 2 },
+ { "lt", code_lt, 2 },
+ { "ne", code_ne, 2 },
+ { NULL }
+};
+
unsigned char code_find(char* name, void** function) {
- if (!strcmp(name, "time")) {
- *function = (void(*)(void)) code_time;
- return 0;
- } else if (!strcmp(name, "trace")) {
- *function = (void(*)(void)) code_trace;
- return 2;
- } else if (!strcmp(name, "add")) {
- *function = (void(*)(void)) code_add;
- return 2;
- } else if (!strcmp(name, "mul")) {
- *function = (void(*)(void)) code_mul;
- return 2;
- } else if (!strcmp(name, "sub")) {
- *function = (void(*)(void)) code_sub;
- return 2;
- } else if (!strcmp(name, "eq")) {
- *function = (void(*)(void)) code_eq;
- return 2;
- } else if (!strcmp(name, "ge")) {
- *function = (void(*)(void)) code_ge;
- return 2;
- } else if (!strcmp(name, "gt")) {
- *function = (void(*)(void)) code_gt;
- return 2;
- } else if (!strcmp(name, "le")) {
- *function = (void(*)(void)) code_le;
- return 2;
- } else if (!strcmp(name, "lt")) {
- *function = (void(*)(void)) code_lt;
- return 2;
- } else if (!strcmp(name, "ne")) {
- *function = (void(*)(void)) code_ne;
- return 2;
+ struct code_mapping *entry = code_table;
+ while (entry) {
+ if (!strcmp(name, entry->name)) {
+ *function = entry->f;
+ return entry->arity;
+ }
+ entry++;
}
*function = NULL;
return 0;
}
+
+#ifdef _FUSPEL_DEBUG
+char *code_find_name(void* f) {
+ struct code_mapping *entry = code_table;
+ while (entry) {
+ if (f == entry->f)
+ return entry->name;
+ entry++;
+ }
+ return NULL;
+}
+#endif
diff --git a/interpreter/code.h b/interpreter/code.h
index 144a7c3..8b7d060 100644
--- a/interpreter/code.h
+++ b/interpreter/code.h
@@ -10,4 +10,8 @@ typedef void (Code_2) (struct node**, struct node*, struct node*);
unsigned char code_find(char* name, void** function);
+#ifdef _FUSPEL_DEBUG
+char *code_find_name(void* f);
+#endif
+
#endif
diff --git a/interpreter/eval.c b/interpreter/eval.c
index cd72f40..a9d2edc 100644
--- a/interpreter/eval.c
+++ b/interpreter/eval.c
@@ -89,33 +89,6 @@ void replace_all(fuspel *rules, replacements* repls, struct node** node) {
}
}
-struct node*** flatten_app_args(struct node** from) {
- struct node ***result;
- unsigned int i;
- unsigned char len = 0;
- struct node* _from = *from;
-
- remove_redirects(_from);
-
- while (_from->kind == NODE_APP) {
- len++;
- _from = _from->var1;
- remove_redirects(_from);
- }
- len++;
-
- result = my_calloc(1, sizeof(struct node**) * (len + 1));
- i = 1;
- while ((*from)->kind == NODE_APP) {
- result[len - i] = (struct node**) &(*from)->var2;
- from = (struct node**) &(*from)->var1;
- i++;
- }
- result[0] = from;
- result[len] = NULL;
- return result;
-}
-
bool match_expr(fuspel* rules, expression* expr, struct node** node,
replacements* repls) {
replacements* _repls;
@@ -164,7 +137,7 @@ int match_rule(fuspel* rules, rewrite_rule* rule, struct node** node,
break;
case NODE_APP:
- node_args = flatten_app_args(node);
+ node_args = flatten_app_args(node, true);
i = 0;
if (!strcmp((*node_args[0])->var1, rule->name)) {
struct node** node = node_args[++i];
@@ -218,7 +191,7 @@ void eval_code_app(fuspel* rules, struct node** node) {
if (root->kind != NODE_CODE || !root->var1)
return;
- args = flatten_app_args(node);
+ args = flatten_app_args(node, true);
for (i = 1; i <= *((unsigned char*) root->var2); i++)
eval(rules, args[i], 0);
@@ -242,6 +215,9 @@ struct node** root_node;
void eval(fuspel* rules, struct node** node, bool to_rnf) {
fuspel* _rules;
bool rerun;
+#ifdef _FUSPEL_DEBUG
+ bool print_graph;
+#endif
replacements* repls;
if (!node || !*node)
@@ -258,6 +234,9 @@ void eval(fuspel* rules, struct node** node, bool to_rnf) {
do {
rerun = 0;
+#ifdef _FUSPEL_DEBUG
+ print_graph = true;
+#endif
switch ((*node)->kind) {
case NODE_INT:
@@ -316,6 +295,10 @@ void eval(fuspel* rules, struct node** node, bool to_rnf) {
free_node(_repls->replacement.node, 1, 1);
rerun = 1;
+#ifdef _FUSPEL_DEBUG
+ if (is_code_app(*node))
+ print_graph = false;
+#endif
break;
}
@@ -354,7 +337,7 @@ void eval(fuspel* rules, struct node** node, bool to_rnf) {
}
#ifdef _FUSPEL_DEBUG
- if (rerun)
+ if (rerun && print_graph)
print_node_to_file(*root_node, NULL, NULL);
#endif
} while (rerun);
diff --git a/interpreter/graphs.c b/interpreter/graphs.c
index 3871a50..48284ec 100644
--- a/interpreter/graphs.c
+++ b/interpreter/graphs.c
@@ -63,6 +63,35 @@ void free_node(struct node* node, unsigned int count, bool free_first) {
}
}
+struct node*** flatten_app_args(struct node** from, bool remove_redirs) {
+ struct node ***result;
+ unsigned int i;
+ unsigned char len = 0;
+ struct node* _from = *from;
+
+ if (remove_redirs)
+ remove_redirects(_from);
+
+ while (_from->kind == NODE_APP) {
+ len++;
+ _from = _from->var1;
+ if (remove_redirs)
+ remove_redirects(_from);
+ }
+ len++;
+
+ result = my_calloc(1, sizeof(struct node**) * (len + 1));
+ i = 1;
+ while ((*from)->kind == NODE_APP) {
+ result[len - i] = (struct node**) &(*from)->var2;
+ from = (struct node**) &(*from)->var1;
+ i++;
+ }
+ result[0] = from;
+ result[len] = NULL;
+ return result;
+}
+
void remove_redirects(struct node *node) {
while (node->kind == NODE_REDIRECT) {
struct node *child = (struct node*) node->var1;
diff --git a/interpreter/graphs.h b/interpreter/graphs.h
index a577095..204993c 100644
--- a/interpreter/graphs.h
+++ b/interpreter/graphs.h
@@ -25,6 +25,8 @@ struct node {
void use_node(struct node* node, unsigned int count);
void free_node(struct node* node, unsigned int count, bool free_first);
+struct node*** flatten_app_args(struct node** from, bool remove_redirs);
+
void remove_redirects(struct node *node);
void cpy_expression_to_node(struct node* dst, expression* src);
diff --git a/interpreter/print.c b/interpreter/print.c
index 40df756..bc1f6dc 100644
--- a/interpreter/print.c
+++ b/interpreter/print.c
@@ -3,6 +3,8 @@
#ifdef _FUSPEL_DEBUG
#include <inttypes.h>
#include <stdbool.h>
+#include <string.h>
+#include "code.h"
#endif
#include "log.h"
@@ -159,10 +161,34 @@ bool visited_node_exists(struct visited_nodes *list, struct node *node) {
return 0;
}
+char *get_app_name(struct node *node) {
+ char *name;
+ if (node->kind == NODE_NAME) {
+ name = my_calloc(strlen(node->var1) + 1, 1);
+ strcpy(name, (char*) node->var1);
+ } else if (node->kind == NODE_CODE) {
+ name = my_calloc(24, 1);
+ strncpy(name, code_find_name(node->var1), 23);
+ } else {
+ name = my_calloc(9, 1);
+ strcpy(name, "Redirect");
+ }
+ return name;
+}
+
+void *get_app_root(struct node *node) {
+ while (node->kind == NODE_APP)
+ node = node->var1;
+ return node;
+}
+
void print_node_to_file(struct node* node, FILE* f, struct visited_nodes *visited) {
bool close = 0;
bool do_free_visited = 0;
- unsigned int borderwidth, edgewidth;
+
+ struct node ***args_list;
+ unsigned int arg_i;
+ char *app_name;
if (visited_node_exists(visited, node))
return;
@@ -179,58 +205,77 @@ void print_node_to_file(struct node* node, FILE* f, struct visited_nodes *visite
sprintf(fname, "graph-%03u.dot", file_count++);
f = fopen(fname, "w");
fprintf(f, "digraph {\n");
- fprintf(f, "node [shape=rectangle];\n");
+ fprintf(f, "node [shape=record];\n");
close = 1;
}
- borderwidth = node->used_count > 20 ? 20 : node->used_count;
- edgewidth = borderwidth > 5 ? 5 : borderwidth;
-
switch (node->kind) {
case NODE_INT:
- fprintf(f, "%" PRIuPTR " [label=\"%d (%d)\", penwidth=%d];\n",
- (uintptr_t) node, *((int*) node->var1), node->used_count, borderwidth);
+ fprintf(f, "%" PRIuPTR " [label=\"%d\"];\n",
+ (uintptr_t) node, *((int*) node->var1));
break;
case NODE_NAME:
- fprintf(f, "%" PRIuPTR " [label=\"%s (%d)\", penwidth=%d];\n",
- (uintptr_t) node, (char*) node->var1, node->used_count, borderwidth);
+ fprintf(f, "%" PRIuPTR " [label=\"%s\"];\n",
+ (uintptr_t) node, (char*) node->var1);
break;
case NODE_CODE:
- fprintf(f, "%" PRIuPTR " [label=\"code: %p (%d)\", penwidth=%d];\n",
- (uintptr_t) node, node->var1, node->used_count, borderwidth);
+ fprintf(f, "%" PRIuPTR " [label=\"%s\"];\n",
+ (uintptr_t) node, code_find_name(node->var1));
+ break;
+
+ case NODE_APP:
+ args_list = flatten_app_args(&node, false);
+ app_name = get_app_name(*args_list[0]);
+ fprintf(f, "%" PRIuPTR " [label=\"%s",
+ (uintptr_t) node,
+ app_name);
+ my_free(app_name);
+ for (arg_i = 1; args_list[arg_i]; arg_i++)
+ fprintf(f, "|<%u>", arg_i);
+ fprintf(f, "\"];\n");
+ for (arg_i = 1; args_list[arg_i]; arg_i++) {
+ print_node_to_file(*args_list[arg_i], f, visited);
+ fprintf(f, "%" PRIuPTR ":%d -> %" PRIuPTR ";\n",
+ (uintptr_t) node, //(*args_list[0])->var1,
+ arg_i,
+ (uintptr_t) *args_list[arg_i]);
+ }
+ my_free(args_list);
break;
case NODE_LIST:
+ if (!node->var1) {
+ fprintf(f, "%" PRIuPTR " [label=\"Nil\"];\n",
+ (uintptr_t) node);
+ break;
+ }
case NODE_TUPLE:
- case NODE_APP:
if (node->kind == NODE_LIST)
- fprintf(f, "%" PRIuPTR " [label=\"List (%d)\", color=gray, fontcolor=gray, penwidth=%d];\n",
- (uintptr_t) node, node->used_count, borderwidth);
+ fprintf(f, "%" PRIuPTR " [label=\"Cons|<l>|<r>\", color=gray, fontcolor=gray];\n",
+ (uintptr_t) node);
else if (node->kind == NODE_TUPLE)
- fprintf(f, "%" PRIuPTR " [label=\"Tuple (%d)\", color=gray, fontcolor=gray, penwidth=%d];\n",
- (uintptr_t) node, node->used_count, borderwidth);
+ fprintf(f, "%" PRIuPTR " [label=\"Tuple|<l>|<r>\", color=gray, fontcolor=gray];\n",
+ (uintptr_t) node);
else if (node->kind == NODE_APP)
- fprintf(f, "%" PRIuPTR " [label=\"App (%d)\", color=gray, fontcolor=gray, penwidth=%d];\n",
- (uintptr_t) node, node->used_count, borderwidth);
-
- if (node->var1) {
- print_node_to_file((struct node*) node->var1, f, visited);
- print_node_to_file((struct node*) node->var2, f, visited);
- fprintf(f, "%" PRIuPTR " -> %" PRIuPTR " [color=blue, penwidth=%d];\n",
- (uintptr_t) node, (uintptr_t) node->var1, edgewidth);
- fprintf(f, "%" PRIuPTR " -> %" PRIuPTR " [color=red, penwidth=%d];\n",
- (uintptr_t) node, (uintptr_t) node->var2, edgewidth);
- }
+ fprintf(f, "%" PRIuPTR " [label=\"App|<l>|<r>\", color=gray, fontcolor=gray];\n",
+ (uintptr_t) node);
+
+ print_node_to_file((struct node*) node->var1, f, visited);
+ print_node_to_file((struct node*) node->var2, f, visited);
+ fprintf(f, "%" PRIuPTR ":l -> %" PRIuPTR ";\n",
+ (uintptr_t) node, (uintptr_t) node->var1);
+ fprintf(f, "%" PRIuPTR ":r -> %" PRIuPTR ";\n",
+ (uintptr_t) node, (uintptr_t) node->var2);
break;
case NODE_REDIRECT:
- fprintf(f, "%" PRIuPTR " [label=\"Redirection (%d)\", color=gray, fontcolor=gray, penwidth=%d];\n",
- (uintptr_t) node, node->used_count, borderwidth);
+ fprintf(f, "%" PRIuPTR " [label=\"Redirection\", color=gray, fontcolor=gray];\n",
+ (uintptr_t) node);
print_node_to_file((struct node*) node->var1, f, visited);
- fprintf(f, "%" PRIuPTR " -> %" PRIuPTR " [penwidth=%d];\n",
- (uintptr_t) node, (uintptr_t) node->var1, edgewidth);
+ fprintf(f, "%" PRIuPTR " -> %" PRIuPTR ";\n",
+ (uintptr_t) node, (uintptr_t) node->var1);
break;
}