1 /** 2 * Provides an AST printer for debugging. 3 * 4 * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved 5 * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) 6 * License: $(LINK2 https://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.ctfeexpr; 18 import dmd.tokens; 19 import dmd.visitor; 20 import dmd.hdrgen; 21 22 /******************** 23 * Print AST data structure in a nice format. 24 * Params: 25 * e = expression AST to print 26 * indent = indentation level 27 */ 28 void printAST(Expression e, int indent = 0) 29 { 30 scope PrintASTVisitor pav = new PrintASTVisitor(indent); 31 e.accept(pav); 32 } 33 34 private: 35 36 extern (C++) final class PrintASTVisitor : Visitor 37 { 38 alias visit = Visitor.visit; 39 40 int indent; 41 42 extern (D) this(int indent) scope @safe 43 { 44 this.indent = indent; 45 } 46 47 override void visit(Expression e) 48 { 49 printIndent(indent); 50 auto s = EXPtoString(e.op); 51 printf("%.*s %s\n", cast(int)s.length, s.ptr, e.type ? e.type.toChars() : ""); 52 } 53 54 override void visit(IntegerExp e) 55 { 56 printIndent(indent); 57 printf("Integer %lld %s\n", e.toInteger(), e.type ? e.type.toChars() : ""); 58 } 59 60 override void visit(RealExp e) 61 { 62 printIndent(indent); 63 64 import dmd.hdrgen : floatToBuffer; 65 import dmd.common.outbuffer : OutBuffer; 66 OutBuffer buf; 67 floatToBuffer(e.type, e.value, buf, false); 68 printf("Real %s %s\n", buf.peekChars(), e.type ? e.type.toChars() : ""); 69 } 70 71 override void visit(StructLiteralExp e) 72 { 73 printIndent(indent); 74 auto s = EXPtoString(e.op); 75 printf("%.*s %s, %s\n", cast(int)s.length, s.ptr, e.type ? e.type.toChars() : "", e.toChars()); 76 } 77 78 override void visit(SymbolExp e) 79 { 80 printIndent(indent); 81 printf("Symbol %s\n", e.type ? e.type.toChars() : ""); 82 printIndent(indent + 2); 83 printf(".var: %s\n", e.var ? e.var.toChars() : ""); 84 } 85 86 override void visit(SymOffExp e) 87 { 88 printIndent(indent); 89 printf("SymOff %s\n", e.type ? e.type.toChars() : ""); 90 printIndent(indent + 2); 91 printf(".var: %s\n", e.var ? e.var.toChars() : ""); 92 printIndent(indent + 2); 93 printf(".offset: %llx\n", e.offset); 94 } 95 96 override void visit(VarExp e) 97 { 98 printIndent(indent); 99 printf("Var %s\n", e.type ? e.type.toChars() : ""); 100 printIndent(indent + 2); 101 printf(".var: %s\n", e.var ? e.var.toChars() : ""); 102 } 103 104 override void visit(DsymbolExp e) 105 { 106 visit(cast(Expression)e); 107 printIndent(indent + 2); 108 printf(".s: %s\n", e.s ? e.s.toChars() : ""); 109 } 110 111 override void visit(DotIdExp e) 112 { 113 printIndent(indent); 114 printf("DotId %s\n", e.type ? e.type.toChars() : ""); 115 printIndent(indent + 2); 116 printf(".ident: %s\n", e.ident.toChars()); 117 printAST(e.e1, indent + 2); 118 } 119 120 override void visit(UnaExp e) 121 { 122 visit(cast(Expression)e); 123 printAST(e.e1, indent + 2); 124 } 125 126 override void visit(CastExp e) 127 { 128 printIndent(indent); 129 auto s = EXPtoString(e.op); 130 printf("%.*s %s\n", cast(int)s.length, s.ptr, e.type ? e.type.toChars() : ""); 131 printIndent(indent + 2); 132 printf(".to: %s\n", e.to.toChars()); 133 printAST(e.e1, indent + 2); 134 } 135 136 override void visit(VectorExp e) 137 { 138 printIndent(indent); 139 printf("Vector %s\n", e.type ? e.type.toChars() : ""); 140 printIndent(indent + 2); 141 printf(".to: %s\n", e.to.toChars()); 142 printAST(e.e1, indent + 2); 143 } 144 145 override void visit(VectorArrayExp e) 146 { 147 printIndent(indent); 148 printf("VectorArray %s\n", e.type ? e.type.toChars() : ""); 149 printAST(e.e1, indent + 2); 150 } 151 152 override void visit(DotVarExp e) 153 { 154 printIndent(indent); 155 printf("DotVar %s\n", e.type ? e.type.toChars() : ""); 156 printIndent(indent + 2); 157 printf(".var: %s\n", e.var.toChars()); 158 printAST(e.e1, indent + 2); 159 } 160 161 override void visit(BinExp e) 162 { 163 visit(cast(Expression)e); 164 printAST(e.e1, indent + 2); 165 printAST(e.e2, indent + 2); 166 } 167 168 override void visit(AssignExp e) 169 { 170 printIndent(indent); 171 printf("Assign %s\n", e.type ? e.type.toChars() : ""); 172 printAST(e.e1, indent + 2); 173 printAST(e.e2, indent + 2); 174 } 175 176 override void visit(ConstructExp e) 177 { 178 printIndent(indent); 179 printf("Construct %s\n", e.type ? e.type.toChars() : ""); 180 printAST(e.e1, indent + 2); 181 printAST(e.e2, indent + 2); 182 } 183 184 override void visit(BlitExp e) 185 { 186 printIndent(indent); 187 printf("Blit %s\n", e.type ? e.type.toChars() : ""); 188 printAST(e.e1, indent + 2); 189 printAST(e.e2, indent + 2); 190 } 191 192 override void visit(IndexExp e) 193 { 194 printIndent(indent); 195 printf("Index %s\n", e.type ? e.type.toChars() : ""); 196 printAST(e.e1, indent + 2); 197 printAST(e.e2, indent + 2); 198 } 199 200 override void visit(DelegateExp e) 201 { 202 visit(cast(Expression)e); 203 printIndent(indent + 2); 204 printf(".func: %s\n", e.func ? e.func.toChars() : ""); 205 } 206 207 override void visit(CompoundLiteralExp e) 208 { 209 visit(cast(Expression)e); 210 printIndent(indent + 2); 211 printf(".init: %s\n", e.initializer ? e.initializer.toChars() : ""); 212 } 213 214 override void visit(ClassReferenceExp e) 215 { 216 visit(cast(Expression)e); 217 printIndent(indent + 2); 218 printf(".value: %s\n", e.value ? e.value.toChars() : ""); 219 printAST(e.value, indent + 2); 220 } 221 222 override void visit(ArrayLiteralExp e) 223 { 224 visit(cast(Expression)e); 225 printIndent(indent + 2); 226 printf(".basis : %s\n", e.basis ? e.basis.toChars() : ""); 227 if (e.elements) 228 { 229 printIndent(indent + 2); 230 printf("["); 231 foreach (i, element; (*e.elements)[]) 232 { 233 if (i) 234 printf(", "); 235 printf("%s", element.toChars()); 236 } 237 printf("]\n"); 238 } 239 } 240 241 static void printIndent(int indent) 242 { 243 foreach (i; 0 .. indent) 244 putc(' ', stdout); 245 } 246 }