|
1 | 1 | import { ICompilerContext } from "../CompilerContext";
|
2 |
| -import { digraph } from "../graphviz"; |
3 |
| -import { Node } from "../graphviz/node"; |
4 | 2 | import { Block } from "./block";
|
5 | 3 | import { traverse } from "./graph";
|
6 | 4 | import { ValueId } from "./id";
|
7 | 5 | import { TBlockInstruction, TBlockEndInstruction } from "./instructions";
|
8 | 6 |
|
| 7 | +/** |
| 8 | + * Debug function that you can use to visualize the compiler's intermediate |
| 9 | + * representation during compilation as a directed graph in DOT notation. |
| 10 | + */ |
9 | 11 | export function generateGraphVizDOTString(c: ICompilerContext, entry: Block) {
|
| 12 | + let result = "digraph mlogjs_cfg {\n"; |
10 | 13 | const ids = new Map<Block, string>();
|
11 |
| - const nodes = new Map<Block, Node>(); |
12 |
| - const graph = digraph("G"); |
| 14 | + |
| 15 | + traverse(entry, block => { |
| 16 | + const id = `block${ids.size}`; |
| 17 | + ids.set(block, id); |
| 18 | + }); |
13 | 19 |
|
14 | 20 | const n = (id: ValueId) => c.getValueOrTemp(id)?.toMlogString();
|
15 | 21 | function instToString(
|
@@ -51,38 +57,35 @@ export function generateGraphVizDOTString(c: ICompilerContext, entry: Block) {
|
51 | 57 | return "end";
|
52 | 58 | case "stop":
|
53 | 59 | return "stop";
|
| 60 | + case "end-if": |
| 61 | + return `end-if ${n(inst.condition)} ${ids.get(inst.alternate.block)}`; |
54 | 62 | default:
|
55 | 63 | throw new Error(
|
56 | 64 | `Missing representation for instruction of type ${
|
| 65 | + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any |
57 | 66 | (inst as any).type
|
58 | 67 | }`,
|
59 | 68 | );
|
60 | 69 | }
|
61 | 70 | }
|
62 | 71 |
|
63 |
| - traverse(entry, block => { |
64 |
| - const id = `block${ids.size}`; |
65 |
| - ids.set(block, id); |
66 |
| - nodes.set(block, graph.addNode(id)); |
67 |
| - }); |
68 |
| - |
69 | 72 | traverse(entry, block => {
|
70 | 73 | const id = ids.get(block)!;
|
71 |
| - const node = nodes.get(block)!; |
72 |
| - node.set( |
73 |
| - "label", |
74 |
| - `${id}\n\n${[...block.instructions, block.endInstruction] |
75 |
| - .filter((value): value is NonNullable<typeof value> => !!value) |
76 |
| - .map(instToString) |
77 |
| - .join("\n") |
78 |
| - .replace(/"/g, "'")}`, |
79 |
| - ); |
| 74 | + result += `${id} [label="${id}\n\n${[ |
| 75 | + ...block.instructions, |
| 76 | + block.endInstruction, |
| 77 | + ] |
| 78 | + .filter((value): value is NonNullable<typeof value> => !!value) |
| 79 | + .map(instToString) |
| 80 | + .join("\n") |
| 81 | + .replace(/"/g, "'")}"];\n`; |
| 82 | + |
80 | 83 | for (const edge of block.childEdges) {
|
81 |
| - const target = ids.get(edge.block); |
82 |
| - console.log(target); |
83 |
| - graph.addEdge(id, ids.get(edge.block)!, undefined); |
| 84 | + result += `${id} -> ${ids.get(edge.block)};\n`; |
84 | 85 | }
|
85 | 86 | });
|
86 | 87 |
|
87 |
| - return graph.to_dot(); |
| 88 | + result += "}\n"; |
| 89 | + |
| 90 | + return result; |
88 | 91 | }
|
0 commit comments