1 /**
2  * Provides an AST printer for debugging.
3  *
4  * Copyright:   Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved
5  * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)
6  * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
7  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/printast.d, _printast.d)
8  * Documentation:  https://dlang.org/phobos/dmd_printast.html
9  * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/printast.d
10  */
11 
12 module dmd.printast;
13 
14 import core.stdc.stdio;
15 
16 import dmd.expression;
17 import dmd.tokens;
18 import dmd.visitor;
19 
20 /********************
21  * Print AST data structure in a nice format.
22  * Params:
23  *  e = expression AST to print
24  *  indent = indentation level
25  */
26 void printAST(Expression e, int indent = 0)
27 {
28     scope PrintASTVisitor pav = new PrintASTVisitor(indent);
29     e.accept(pav);
30 }
31 
32 private:
33 
34 extern (C++) final class PrintASTVisitor : Visitor
35 {
36     alias visit = Visitor.visit;
37 
38     int indent;
39 
40     extern (D) this(int indent)
41     {
42         this.indent = indent;
43     }
44 
45     override void visit(Expression e)
46     {
47         printIndent(indent);
48         printf("%s %s\n", Token.toChars(e.op), e.type ? e.type.toChars() : "");
49     }
50 
51     override void visit(IntegerExp e)
52     {
53         printIndent(indent);
54         printf("Integer %lld %s\n", e.toInteger(), e.type ? e.type.toChars() : "");
55     }
56 
57     override void visit(RealExp e)
58     {
59         printIndent(indent);
60 
61         import dmd.hdrgen : floatToBuffer;
62         import dmd.root.outbuffer : OutBuffer;
63         OutBuffer buf;
64         floatToBuffer(e.type, e.value, &buf, false);
65         printf("Real %s %s\n", buf.peekChars(), e.type ? e.type.toChars() : "");
66     }
67 
68     override void visit(StructLiteralExp e)
69     {
70         printIndent(indent);
71         printf("%s %s, %s\n", Token.toChars(e.op), e.type ? e.type.toChars() : "", e.toChars());
72     }
73 
74     override void visit(SymbolExp e)
75     {
76         printIndent(indent);
77         printf("Symbol %s\n", e.type ? e.type.toChars() : "");
78         printIndent(indent + 2);
79         printf(".var: %s\n", e.var ? e.var.toChars() : "");
80     }
81 
82     override void visit(DsymbolExp e)
83     {
84         visit(cast(Expression)e);
85         printIndent(indent + 2);
86         printf(".s: %s\n", e.s ? e.s.toChars() : "");
87     }
88 
89     override void visit(DotIdExp e)
90     {
91         printIndent(indent);
92         printf("DotId %s\n", e.type ? e.type.toChars() : "");
93         printIndent(indent + 2);
94         printf(".ident: %s\n", e.ident.toChars());
95         printAST(e.e1, indent + 2);
96     }
97 
98     override void visit(UnaExp e)
99     {
100         visit(cast(Expression)e);
101         printAST(e.e1, indent + 2);
102     }
103 
104     override void visit(VectorExp e)
105     {
106         printIndent(indent);
107         printf("Vector %s\n", e.type ? e.type.toChars() : "");
108         printIndent(indent + 2);
109         printf(".to: %s\n", e.to.toChars());
110         printAST(e.e1, indent + 2);
111     }
112 
113     override void visit(VectorArrayExp e)
114     {
115         printIndent(indent);
116         printf("VectorArray %s\n", e.type ? e.type.toChars() : "");
117         printAST(e.e1, indent + 2);
118     }
119 
120     override void visit(BinExp e)
121     {
122         visit(cast(Expression)e);
123         printAST(e.e1, indent + 2);
124         printAST(e.e2, indent + 2);
125     }
126 
127     override void visit(AssignExp e)
128     {
129         printIndent(indent);
130         printf("Assign %s\n", e.type ? e.type.toChars() : "");
131         printAST(e.e1, indent + 2);
132         printAST(e.e2, indent + 2);
133     }
134 
135     override void visit(ConstructExp e)
136     {
137         printIndent(indent);
138         printf("Construct %s\n", e.type ? e.type.toChars() : "");
139         printAST(e.e1, indent + 2);
140         printAST(e.e2, indent + 2);
141     }
142 
143     override void visit(BlitExp e)
144     {
145         printIndent(indent);
146         printf("Blit %s\n", e.type ? e.type.toChars() : "");
147         printAST(e.e1, indent + 2);
148         printAST(e.e2, indent + 2);
149     }
150 
151     override void visit(IndexExp e)
152     {
153         printIndent(indent);
154         printf("Index %s\n", e.type ? e.type.toChars() : "");
155         printAST(e.e1, indent + 2);
156         printAST(e.e2, indent + 2);
157     }
158 
159     override void visit(DelegateExp e)
160     {
161         visit(cast(Expression)e);
162         printIndent(indent + 2);
163         printf(".func: %s\n", e.func ? e.func.toChars() : "");
164     }
165 
166     static void printIndent(int indent)
167     {
168         foreach (i; 0 .. indent)
169             putc(' ', stdout);
170     }
171 }
172 
173