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