aboutsummaryrefslogtreecommitdiffstats
path: root/src/viz.c
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2022-04-08 08:25:48 -0300
committerBad Diode <bd@badd10de.dev>2022-04-08 08:25:48 -0300
commit55ecfb3b7713172f76ddbff022fa4d6a80d0661a (patch)
tree6a6baae20d67824d5f79b801b27f58cc967a3ba1 /src/viz.c
parent9f934cbc0f0fd60a6938ac1c4c84edc270de94ca (diff)
downloadbdl-55ecfb3b7713172f76ddbff022fa4d6a80d0661a.tar.gz
bdl-55ecfb3b7713172f76ddbff022fa4d6a80d0661a.zip
Add initial implementation of AST vizualization
Diffstat (limited to 'src/viz.c')
-rw-r--r--src/viz.c152
1 files changed, 152 insertions, 0 deletions
diff --git a/src/viz.c b/src/viz.c
new file mode 100644
index 0000000..d409472
--- /dev/null
+++ b/src/viz.c
@@ -0,0 +1,152 @@
1static const char* node_str[] = {
2 [NODE_BUILTIN] = "BUILTIN",
3 [NODE_NUMBER] = "NUMBER",
4 [NODE_BOOL] = "BOOL",
5 [NODE_STRING] = "STRING",
6 [NODE_SYMBOL] = "SYMBOL",
7 [NODE_TYPE] = "TYPE",
8 [NODE_DEF] = "DEF",
9 [NODE_SET] = "SET",
10 [NODE_FUN] = "FUN",
11 [NODE_BLOCK] = "BLOCK",
12 [NODE_IF] = "IF",
13};
14
15void
16viz_node(Node *node) {
17 if (node == NULL) {
18 return;
19 }
20 printf("%zu [width=2.5,shape=Mrecord,label=\"", node->id);
21 printf("<top> %s -- [%4ld:%-4ld] ", node_str[node->type], node->line, node->col);
22 switch (node->type) {
23 case NODE_NUMBER: {
24 printf("| Value: ");
25 if (node->number.negative) {
26 printf("-");
27 }
28 if (node->number.fractional != 0) {
29 printf("%zu.%zu", node->number.integral, node->number.fractional);
30 } else {
31 printf("%zu", node->number.integral);
32 }
33 printf("\"];\n");
34 } break;
35 case NODE_SYMBOL:
36 case NODE_TYPE:
37 case NODE_STRING: {
38 printf(" | Value: ");
39 sv_write(&node->string);
40 printf("\"];\n");
41 } break;
42 case NODE_BOOL: {
43 printf(" | Value: ");
44 if (node->boolean) {
45 printf("true");
46 } else {
47 printf("false");
48 }
49 printf("\"];\n");
50 } break;
51 case NODE_BUILTIN: {
52 printf(" | Name: %s", token_str[node->builtin.type]);
53 printf(" | <args> Args: ");
54 printf("\"];\n");
55 size_t n_args = array_size(node->builtin.args);
56 for (size_t i = 0; i < n_args; ++i) {
57 viz_node(node->builtin.args[i]);
58 printf("%zu:args:e->%zu:top:w;\n", node->id, node->builtin.args[i]->id);
59 }
60 } break;
61 case NODE_DEF: {
62 printf(" | Name: ");
63 sv_write(&node->def.symbol->string);
64 printf(" | Type: ");
65 sv_write(&node->def.type->string);
66 printf(" | <val> Expr: ");
67 printf("\"];\n");
68 viz_node(node->def.value);
69 printf("%zu:val:e->%zu:top:w;\n", node->id, node->def.value->id);
70 } break;
71 case NODE_SET: {
72 printf(" | Name: ");
73 sv_write(&node->set.symbol->string);
74 printf(" | <val> Expr: ");
75 printf("\"];\n");
76 viz_node(node->set.value);
77 printf("%zu:val:e->%zu:top:w;\n", node->id, node->def.value->id);
78 } break;
79 case NODE_BLOCK: {
80 printf(" | <expr> Exprs: ");
81 printf("\"];\n");
82 size_t n_expr = array_size(node->block.expr);
83 for (size_t i = 0; i < n_expr; ++i) {
84 viz_node(node->block.expr[i]);
85 printf("%zu:expr:e->%zu:top:w;\n", node->id, node->block.expr[i]->id);
86 }
87 } break;
88 case NODE_IF: {
89 printf(" | <cond> Cond: ");
90 printf(" | <t> ExprTrue:");
91 if (node->ifexpr.expr_false != NULL) {
92 printf(" | <f> ExprFalse: ");
93 }
94 printf("\"];\n");
95 viz_node(node->ifexpr.cond);
96 printf("%zu:cond:e->%zu:top:w;\n", node->id, node->ifexpr.cond->id);
97 viz_node(node->ifexpr.expr_true);
98 printf("%zu:t:e->%zu:top:w;\n", node->id, node->ifexpr.expr_true->id);
99 if (node->ifexpr.expr_false != NULL) {
100 viz_node(node->ifexpr.expr_false);
101 printf("%zu:f:e->%zu:top:w;\n", node->id, node->ifexpr.expr_false->id);
102 }
103 } break;
104 case NODE_FUN: {
105 printf(" | Name: ");
106 sv_write(&node->fun.name->string);
107 printf(" | Type: ");
108 printf("(");
109 size_t n_params = array_size(node->fun.param_names);
110 for (size_t i = 0; i < n_params; ++i) {
111 printf(":");
112 sv_write(&node->fun.param_types[i]->string);
113 if (i < n_params - 1) {
114 printf(" ");
115 }
116 }
117 printf("):");
118 sv_write(&node->fun.return_type->string);
119 if (n_params > 0) {
120 printf(" | Parameters: (");
121 for (size_t i = 0; i < n_params; ++i) {
122 sv_write(&node->fun.param_names[i]->string);
123 if (i < n_params - 1) {
124 printf(" ");
125 }
126 }
127 printf(")");
128 }
129 printf(" | <bod> Body: ");
130 printf("\"];\n");
131 viz_node(node->fun.body);
132 printf("%zu:bod:e->%zu:top:w;\n", node->id, node->fun.body->id);
133 } break;
134 }
135}
136
137void
138viz_ast(ParseTree *parse_tree) {
139 printf("digraph ast {\n");
140 printf("rankdir=LR;\n");
141 printf("ranksep=\"0.95 equally\";\n");
142 printf("nodesep=\"0.5 equally\";\n");
143 printf("overlap=scale;\n");
144 for (size_t i = 0; i < array_size(parse_tree->roots); ++i) {
145 printf("subgraph %zu {\n", i);
146 Node *root = parse_tree->roots[array_size(parse_tree->roots) - 1 - i];
147 viz_node(root);
148 printf("}\n");
149 }
150 printf("}\n");
151}
152