1 //
2 // Copyright (c) 2006, Brian Frank and Andy Frank
3 // Licensed under the Academic Free License version 3.0
4 //
5 // History:
6 // 26 Dec 05 Brian Frank Creation
7 // 19 Aug 06 Brian Frank Ported from Java to Fan
8 //
9
10 **
11 ** FPrinter is used to pretty print fcode
12 **
13 class FPrinter : FConst
14 {
15
16 //////////////////////////////////////////////////////////////////////////
17 // Constructor
18 //////////////////////////////////////////////////////////////////////////
19
20 new make(FPod pod, OutStream out := Sys.out)
21 {
22 this.pod = pod
23 this.out = out
24 }
25
26 //////////////////////////////////////////////////////////////////////////
27 // Dump
28 //////////////////////////////////////////////////////////////////////////
29
30 Void all()
31 {
32 tables
33 ftypes
34 out.flush
35 }
36
37 //////////////////////////////////////////////////////////////////////////
38 // Const Tables
39 //////////////////////////////////////////////////////////////////////////
40
41 Void tables()
42 {
43 printLine("##### Tables #####");
44 table("--- names ---", pod.names)
45 table("--- typeRefs ---", pod.typeRefs)
46 table("--- fieldRefs ---", pod.fieldRefs)
47 table("--- methodRefs ---", pod.methodRefs)
48 table("--- ints ---", pod.ints)
49 table("--- floats ---", pod.floats)
50 table("--- strs ---", pod.strs)
51 table("--- durations ---", pod.durations)
52 table("--- uris ---", pod.uris)
53 out.flush
54 }
55
56 Void table(Str title, FTable table)
57 {
58 printLine(title)
59 table.table.each |Obj obj, Int index|
60 {
61 m := obj.type.method("format", false)
62 s := m != null ? m.call([obj, pod]) : obj.toStr
63 printLine(" [$index] $s")
64 }
65 }
66
67 //////////////////////////////////////////////////////////////////////////
68 // Types
69 //////////////////////////////////////////////////////////////////////////
70
71 Void ftypes()
72 {
73 printLine("##### Types #####")
74 pod.ftypes.each |FType t| { ftype(t) }
75 out.flush
76 }
77
78 Void ftype(FType t)
79 {
80 printLine("--" + typeRef(t.self) + " : " + typeRef(t.fbase) + "--")
81 if (!t.fmixins.isEmpty)
82 {
83 printLine(" mixin " + t.fmixins.join(", ") |Int m->Str| { return typeRef(m) });
84 }
85 attrs(t.fattrs)
86 printLine
87 t.ffields.each |FField f| { field(f) }
88 t.fmethods.each |FMethod m| { method(m) }
89 out.flush
90 }
91
92 Void slot(FSlot s)
93 {
94 if (s is FField)
95 field((FField)s)
96 else
97 method((FMethod)s)
98 out.flush
99 }
100
101 Void field(FField f)
102 {
103 printLine(" " + name(f.nameIndex) + " -> " + typeRef(f.typeRef) + " [" + flags(f.flags) + "]")
104 attrs(f.fattrs)
105 printLine
106 }
107
108 Void method(FMethod m)
109 {
110 print(" " + name(m.nameIndex) + " (")
111 print(m.fparams.join(", ") |FMethodVar p->Str| { return typeRef(p.typeRef) + " " + name(p.nameIndex) })
112 print(") -> " + typeRef(m.ret))
113 if (m.ret != m.inheritedRet) print(" {" + typeRef(m.inheritedRet) + "}")
114 printLine(" [" + flags(m.flags) + "]")
115 m.vars.each |FMethodVar v, Int reg|
116 {
117 role := v.isParam ? "Param" : "Local"
118 if (m.flags & FConst.Static == 0) reg++
119 printLine(" [" + role + " " + reg + "] " + pod.n(v.nameIndex) + " -> " + typeRef(v.typeRef))
120 if (v.def != null) code(v.def)
121 }
122 if (m.code != null)
123 {
124 printLine(" [Code]")
125 code(m.code)
126 }
127 attrs(m.fattrs)
128 printLine
129 }
130
131 Void code(Buf code)
132 {
133 if (!showCode) return;
134 out.flush
135 codePrinter := FCodePrinter.make(pod, out)
136 codePrinter.showIndex = showIndex
137 codePrinter.code(code)
138 }
139
140 //////////////////////////////////////////////////////////////////////////
141 // Attributes
142 //////////////////////////////////////////////////////////////////////////
143
144 Void attrs(FAttr[] attrs)
145 {
146 if (attrs == null) return
147 attrs.each |FAttr a| { attr(a) }
148 }
149
150 Void attr(FAttr attr)
151 {
152 name := name(attr.name)
153 if (name == LineNumbersAttr && !showLines) return
154 printLine(" [$name] size=$attr.data.size")
155 if (name == SourceFileAttr) sourceFileAttr(attr)
156 if (name == ErrTableAttr) errTableAttr(attr)
157 if (name == LineNumberAttr) lineNumberAttr(attr)
158 if (name == LineNumbersAttr) lineNumbersAttr(attr)
159 if (name == FacetsAttr) facetsAttr(attr)
160 }
161
162 Void sourceFileAttr(FAttr attr)
163 {
164 printLine(" $attr.utf")
165 }
166
167 Void lineNumberAttr(FAttr attr)
168 {
169 printLine(" $attr.u2")
170 }
171
172 Void facetsAttr(FAttr attr)
173 {
174 buf := attr.data
175 buf.seek(0)
176 buf.readU2.times |,|
177 {
178 name := name(buf.readU2)
179 val := buf.readUtf
180 printLine(" $name=$val")
181 }
182 }
183
184 Void errTableAttr(FAttr attr)
185 {
186 buf := attr.data
187 buf.seek(0)
188 buf.readU2.times |,|
189 {
190 start := buf.readU2
191 end := buf.readU2
192 handler := buf.readU2
193 tr := buf.readU2
194 printLine(" $start to $end -> $handler " + typeRef(tr))
195 }
196 }
197
198 Void lineNumbersAttr(FAttr attr)
199 {
200 buf := attr.data
201 buf.seek(0)
202 buf.readU2.times |,|
203 {
204 pc := buf.readU2
205 line := buf.readU2
206 printLine(" $pc: $line")
207 }
208 }
209
210 //////////////////////////////////////////////////////////////////////////
211 // Dump Utils
212 //////////////////////////////////////////////////////////////////////////
213
214 Str typeRef(Int i)
215 {
216 if (i == 65535) return "null"
217 return pod.typeRefStr(i) + index(i)
218 }
219
220 Str name(Int i)
221 {
222 return pod.n(i) + index(i)
223 }
224
225 Str flags(Int flags)
226 {
227 s := StrBuf.make
228 if (flags & FConst.Abstract != 0) s.add("abstract ")
229 if (flags & FConst.Const != 0) s.add("const ")
230 if (flags & FConst.Ctor != 0) s.add("ctor ")
231 if (flags & FConst.Enum != 0) s.add("enum ")
232 if (flags & FConst.Final != 0) s.add("final ")
233 if (flags & FConst.Getter != 0) s.add("getter ")
234 if (flags & FConst.Internal != 0) s.add("internal ")
235 if (flags & FConst.Mixin != 0) s.add("mixin ")
236 if (flags & FConst.Native != 0) s.add("native ")
237 if (flags & FConst.Override != 0) s.add("override ")
238 if (flags & FConst.Private != 0) s.add("private ")
239 if (flags & FConst.Protected != 0) s.add("protected ")
240 if (flags & FConst.Public != 0) s.add("public ")
241 if (flags & FConst.Setter != 0) s.add("setter ")
242 if (flags & FConst.Static != 0) s.add("static ")
243 if (flags & FConst.Storage != 0) s.add("storage ")
244 if (flags & FConst.Synthetic != 0) s.add("synthetic ")
245 if (flags & FConst.Virtual != 0) s.add("virtual ")
246 return s.toStr[0..-2]
247 }
248
249 Str index(Int index)
250 {
251 if (showIndex) return "[" + index + "]"
252 return ""
253 }
254
255 //////////////////////////////////////////////////////////////////////////
256 // Print
257 //////////////////////////////////////////////////////////////////////////
258
259 FPrinter print(Obj obj) { out.print(obj); return this }
260 FPrinter printLine(Obj obj := "") { out.printLine(obj); return this }
261
262 //////////////////////////////////////////////////////////////////////////
263 // Fields
264 //////////////////////////////////////////////////////////////////////////
265
266 FPod pod
267 OutStream out
268 Bool showIndex := false
269 Bool showCode := true
270 Bool showLines := false
271
272 }
2 // Copyright (c) 2006, Brian Frank and Andy Frank
3 // Licensed under the Academic Free License version 3.0
4 //
5 // History:
6 // 26 Dec 05 Brian Frank Creation
7 // 19 Aug 06 Brian Frank Ported from Java to Fan
8 //
9
10 **
11 ** FPrinter is used to pretty print fcode
12 **
13 class FPrinter : FConst
14 {
15
16 //////////////////////////////////////////////////////////////////////////
17 // Constructor
18 //////////////////////////////////////////////////////////////////////////
19
20 new make(FPod pod, OutStream out := Sys.out)
21 {
22 this.pod = pod
23 this.out = out
24 }
25
26 //////////////////////////////////////////////////////////////////////////
27 // Dump
28 //////////////////////////////////////////////////////////////////////////
29
30 Void all()
31 {
32 tables
33 ftypes
34 out.flush
35 }
36
37 //////////////////////////////////////////////////////////////////////////
38 // Const Tables
39 //////////////////////////////////////////////////////////////////////////
40
41 Void tables()
42 {
43 printLine("##### Tables #####");
44 table("--- names ---", pod.names)
45 table("--- typeRefs ---", pod.typeRefs)
46 table("--- fieldRefs ---", pod.fieldRefs)
47 table("--- methodRefs ---", pod.methodRefs)
48 table("--- ints ---", pod.ints)
49 table("--- floats ---", pod.floats)
50 table("--- strs ---", pod.strs)
51 table("--- durations ---", pod.durations)
52 table("--- uris ---", pod.uris)
53 out.flush
54 }
55
56 Void table(Str title, FTable table)
57 {
58 printLine(title)
59 table.table.each |Obj obj, Int index|
60 {
61 m := obj.type.method("format", false)
62 s := m != null ? m.call([obj, pod]) : obj.toStr
63 printLine(" [$index] $s")
64 }
65 }
66
67 //////////////////////////////////////////////////////////////////////////
68 // Types
69 //////////////////////////////////////////////////////////////////////////
70
71 Void ftypes()
72 {
73 printLine("##### Types #####")
74 pod.ftypes.each |FType t| { ftype(t) }
75 out.flush
76 }
77
78 Void ftype(FType t)
79 {
80 printLine("--" + typeRef(t.self) + " : " + typeRef(t.fbase) + "--")
81 if (!t.fmixins.isEmpty)
82 {
83 printLine(" mixin " + t.fmixins.join(", ") |Int m->Str| { return typeRef(m) });
84 }
85 attrs(t.fattrs)
86 printLine
87 t.ffields.each |FField f| { field(f) }
88 t.fmethods.each |FMethod m| { method(m) }
89 out.flush
90 }
91
92 Void slot(FSlot s)
93 {
94 if (s is FField)
95 field((FField)s)
96 else
97 method((FMethod)s)
98 out.flush
99 }
100
101 Void field(FField f)
102 {
103 printLine(" " + name(f.nameIndex) + " -> " + typeRef(f.typeRef) + " [" + flags(f.flags) + "]")
104 attrs(f.fattrs)
105 printLine
106 }
107
108 Void method(FMethod m)
109 {
110 print(" " + name(m.nameIndex) + " (")
111 print(m.fparams.join(", ") |FMethodVar p->Str| { return typeRef(p.typeRef) + " " + name(p.nameIndex) })
112 print(") -> " + typeRef(m.ret))
113 if (m.ret != m.inheritedRet) print(" {" + typeRef(m.inheritedRet) + "}")
114 printLine(" [" + flags(m.flags) + "]")
115 m.vars.each |FMethodVar v, Int reg|
116 {
117 role := v.isParam ? "Param" : "Local"
118 if (m.flags & FConst.Static == 0) reg++
119 printLine(" [" + role + " " + reg + "] " + pod.n(v.nameIndex) + " -> " + typeRef(v.typeRef))
120 if (v.def != null) code(v.def)
121 }
122 if (m.code != null)
123 {
124 printLine(" [Code]")
125 code(m.code)
126 }
127 attrs(m.fattrs)
128 printLine
129 }
130
131 Void code(Buf code)
132 {
133 if (!showCode) return;
134 out.flush
135 codePrinter := FCodePrinter.make(pod, out)
136 codePrinter.showIndex = showIndex
137 codePrinter.code(code)
138 }
139
140 //////////////////////////////////////////////////////////////////////////
141 // Attributes
142 //////////////////////////////////////////////////////////////////////////
143
144 Void attrs(FAttr[] attrs)
145 {
146 if (attrs == null) return
147 attrs.each |FAttr a| { attr(a) }
148 }
149
150 Void attr(FAttr attr)
151 {
152 name := name(attr.name)
153 if (name == LineNumbersAttr && !showLines) return
154 printLine(" [$name] size=$attr.data.size")
155 if (name == SourceFileAttr) sourceFileAttr(attr)
156 if (name == ErrTableAttr) errTableAttr(attr)
157 if (name == LineNumberAttr) lineNumberAttr(attr)
158 if (name == LineNumbersAttr) lineNumbersAttr(attr)
159 if (name == FacetsAttr) facetsAttr(attr)
160 }
161
162 Void sourceFileAttr(FAttr attr)
163 {
164 printLine(" $attr.utf")
165 }
166
167 Void lineNumberAttr(FAttr attr)
168 {
169 printLine(" $attr.u2")
170 }
171
172 Void facetsAttr(FAttr attr)
173 {
174 buf := attr.data
175 buf.seek(0)
176 buf.readU2.times |,|
177 {
178 name := name(buf.readU2)
179 val := buf.readUtf
180 printLine(" $name=$val")
181 }
182 }
183
184 Void errTableAttr(FAttr attr)
185 {
186 buf := attr.data
187 buf.seek(0)
188 buf.readU2.times |,|
189 {
190 start := buf.readU2
191 end := buf.readU2
192 handler := buf.readU2
193 tr := buf.readU2
194 printLine(" $start to $end -> $handler " + typeRef(tr))
195 }
196 }
197
198 Void lineNumbersAttr(FAttr attr)
199 {
200 buf := attr.data
201 buf.seek(0)
202 buf.readU2.times |,|
203 {
204 pc := buf.readU2
205 line := buf.readU2
206 printLine(" $pc: $line")
207 }
208 }
209
210 //////////////////////////////////////////////////////////////////////////
211 // Dump Utils
212 //////////////////////////////////////////////////////////////////////////
213
214 Str typeRef(Int i)
215 {
216 if (i == 65535) return "null"
217 return pod.typeRefStr(i) + index(i)
218 }
219
220 Str name(Int i)
221 {
222 return pod.n(i) + index(i)
223 }
224
225 Str flags(Int flags)
226 {
227 s := StrBuf.make
228 if (flags & FConst.Abstract != 0) s.add("abstract ")
229 if (flags & FConst.Const != 0) s.add("const ")
230 if (flags & FConst.Ctor != 0) s.add("ctor ")
231 if (flags & FConst.Enum != 0) s.add("enum ")
232 if (flags & FConst.Final != 0) s.add("final ")
233 if (flags & FConst.Getter != 0) s.add("getter ")
234 if (flags & FConst.Internal != 0) s.add("internal ")
235 if (flags & FConst.Mixin != 0) s.add("mixin ")
236 if (flags & FConst.Native != 0) s.add("native ")
237 if (flags & FConst.Override != 0) s.add("override ")
238 if (flags & FConst.Private != 0) s.add("private ")
239 if (flags & FConst.Protected != 0) s.add("protected ")
240 if (flags & FConst.Public != 0) s.add("public ")
241 if (flags & FConst.Setter != 0) s.add("setter ")
242 if (flags & FConst.Static != 0) s.add("static ")
243 if (flags & FConst.Storage != 0) s.add("storage ")
244 if (flags & FConst.Synthetic != 0) s.add("synthetic ")
245 if (flags & FConst.Virtual != 0) s.add("virtual ")
246 return s.toStr[0..-2]
247 }
248
249 Str index(Int index)
250 {
251 if (showIndex) return "[" + index + "]"
252 return ""
253 }
254
255 //////////////////////////////////////////////////////////////////////////
256 // Print
257 //////////////////////////////////////////////////////////////////////////
258
259 FPrinter print(Obj obj) { out.print(obj); return this }
260 FPrinter printLine(Obj obj := "") { out.printLine(obj); return this }
261
262 //////////////////////////////////////////////////////////////////////////
263 // Fields
264 //////////////////////////////////////////////////////////////////////////
265
266 FPod pod
267 OutStream out
268 Bool showIndex := false
269 Bool showCode := true
270 Bool showLines := false
271
272 }