]> git.saurik.com Git - cycript.git/blob - Output.cpp
Further normalization and fixed some output cases.
[cycript.git] / Output.cpp
1 #include "Parser.hpp"
2
3 #include <iostream>
4 #include <iomanip>
5
6 #define CYPA 16
7
8 void CYAddressOf::Output(std::ostream &out) const {
9 rhs_->Output(out, 1);
10 out << ".$()";
11 }
12
13 void CYArgument::Output(std::ostream &out) const {
14 if (name_ != NULL) {
15 out << *name_;
16 if (value_ != NULL)
17 out << ":";
18 }
19 if (value_ != NULL)
20 value_->Output(out, false);
21 if (next_ != NULL) {
22 if (next_->name_ == NULL)
23 out << ',';
24 else
25 out << ' ';
26 next_->Output(out);
27 }
28 }
29
30 void CYArray::Output(std::ostream &out) const {
31 out << '[';
32 if (elements_ != NULL)
33 elements_->Output(out);
34 out << ']';
35 }
36
37 void CYAssignment::Output(std::ostream &out) const {
38 lhs_->Output(out, Precedence() - 1);
39 out << Operator();
40 rhs_->Output(out, Precedence());
41 }
42
43 void CYBoolean::Output(std::ostream &out) const {
44 out << (Value() ? "true" : "false");
45 }
46
47 void CYBreak::Output(std::ostream &out) const {
48 out << "break";
49 if (label_ != NULL)
50 out << ' ' << *label_;
51 out << ';';
52 }
53
54 void CYCall::Output(std::ostream &out) const {
55 function_->Output(out, Precedence());
56 out << '(';
57 if (arguments_ != NULL)
58 arguments_->Output(out);
59 out << ')';
60 }
61
62 void CYCatch::Output(std::ostream &out) const {
63 out << "catch(" << *name_ << ')';
64 code_->Output(out, true);
65 }
66
67 void CYCondition::Output(std::ostream &out) const {
68 test_->Output(out, Precedence() - 1);
69 out << '?';
70 if (true_ != NULL)
71 true_->Output(out, CYPA);
72 out << ':';
73 false_->Output(out, CYPA);
74 }
75
76 void CYContinue::Output(std::ostream &out) const {
77 out << "continue";
78 if (label_ != NULL)
79 out << ' ' << *label_;
80 out << ';';
81 }
82
83 void CYClause::Output(std::ostream &out) const {
84 if (case_ != NULL) {
85 out << "case";
86 case_->Output(out);
87 } else
88 out << "default";
89 out << ':';
90 if (code_ != NULL)
91 code_->Output(out, false);
92 out << *next_;
93 }
94
95 void CYDeclaration::Part(std::ostream &out) const {
96 out << "var ";
97 Output(out);
98 }
99
100 void CYDeclaration::Output(std::ostream &out) const {
101 out << *identifier_;
102 if (initialiser_ != NULL) {
103 out << '=';
104 initialiser_->Output(out, CYPA);
105 }
106 }
107
108 void CYDeclarations::Part(std::ostream &out) const {
109 out << "var ";
110
111 const CYDeclarations *declaration(this);
112 output:
113 out << *declaration->declaration_;
114 declaration = declaration->next_;
115
116 if (declaration != NULL) {
117 out << ',';
118 goto output;
119 }
120 }
121
122 void CYDeclarations::Output(std::ostream &out) const {
123 Part(out);
124 out << ';';
125 }
126
127 void CYDoWhile::Output(std::ostream &out) const {
128 out << "do ";
129 code_->Output(out, false);
130 out << "while(";
131 test_->Output(out);
132 out << ';';
133 }
134
135 void CYElement::Output(std::ostream &out) const {
136 if (value_ != NULL)
137 value_->Output(out, CYPA);
138 if (next_ != NULL || value_ == NULL)
139 out << ',';
140 if (next_ != NULL)
141 next_->Output(out);
142 }
143
144 void CYEmpty::Output(std::ostream &out) const {
145 out << ';';
146 }
147
148 void CYEmpty::Output(std::ostream &out, bool block) const {
149 if (next_ != NULL)
150 CYSource::Output(out, block);
151 else
152 out << "{}";
153 }
154
155 void CYExpress::Output(std::ostream &out) const {
156 expression_->Output(out);
157 out << ';';
158 }
159
160 void CYExpression::Part(std::ostream &out) const {
161 // XXX: this should notice "in" expressions
162 // XXX: this should handle LeftHandSideExpression
163 Output(out);
164 }
165
166 void CYCompound::Output(std::ostream &out) const {
167 if (CYExpression *expression = expressions_)
168 for (;;) {
169 expression->Output(out);
170 expression = expression->next_;
171 if (expression == NULL)
172 break;
173 out << ',';
174 }
175 }
176
177 void CYExpression::Output(std::ostream &out, unsigned precedence) const {
178 bool protect(precedence < Precedence());
179 if (protect)
180 out << '(';
181 Output(out);
182 if (protect)
183 out << ')';
184 }
185
186 void CYFor::Output(std::ostream &out) const {
187 out << "for(";
188 if (initialiser_ != NULL)
189 initialiser_->Part(out);
190 out << ';';
191 if (test_ != NULL)
192 test_->Output(out);
193 out << ';';
194 if (increment_ != NULL)
195 increment_->Output(out);
196 out << ')';
197 code_->Output(out, false);
198 }
199
200 void CYForIn::Output(std::ostream &out) const {
201 out << "for(";
202 initialiser_->Part(out);
203 out << " in ";
204 set_->Output(out);
205 out << ')';
206 code_->Output(out, false);
207 }
208
209 void CYFunction::Output(std::ostream &out) const {
210 CYLambda::Output(out);
211 }
212
213 void CYIf::Output(std::ostream &out) const {
214 out << "if(";
215 test_->Output(out);
216 out << ')';
217 true_->Output(out, true);
218 if (false_ != NULL) {
219 out << "else ";
220 false_->Output(out, false);
221 }
222 }
223
224 void CYIndirect::Output(std::ostream &out) const {
225 rhs_->Output(out, 1);
226 out << "[0]";
227 }
228
229 void CYInfix::Output(std::ostream &out) const {
230 lhs_->Output(out, Precedence());
231 out << Operator();
232 rhs_->Output(out, Precedence() - 1);
233 }
234
235 void CYLambda::Output(std::ostream &out) const {
236 out << "function";
237 if (name_ != NULL)
238 out << ' ' << *name_;
239 out << '(';
240 if (parameters_ != NULL)
241 out << *parameters_;
242 out << ')';
243 body_->Output(out, true);
244 }
245
246 void CYMember::Output(std::ostream &out) const {
247 object_->Output(out, Precedence());
248 if (const char *word = property_->Word())
249 out << '.' << word;
250 else {
251 out << '[';
252 property_->Output(out);
253 out << ']';
254 }
255 }
256
257 void CYMessage::Output(std::ostream &out) const {
258 out << "objc_msgSend(";
259 self_->Output(out, CYPA);
260 out << ",\"";
261 for (CYArgument *argument(arguments_); argument != NULL; argument = argument->next_)
262 if (argument->name_ != NULL) {
263 out << *argument->name_;
264 if (argument->value_ != NULL)
265 out << ':';
266 }
267 out << "\"";
268 for (CYArgument *argument(arguments_); argument != NULL; argument = argument->next_)
269 if (argument->value_ != NULL) {
270 out << ",";
271 argument->value_->Output(out, CYPA);
272 }
273 out << ')';
274 }
275
276 void CYNew::Output(std::ostream &out) const {
277 out << "new";
278 // XXX: I don't /always/ need this character
279 out << ' ';
280 constructor_->Output(out, Precedence());
281 out << '(';
282 if (arguments_ != NULL)
283 arguments_->Output(out);
284 out << ')';
285 }
286
287 void CYNull::Output(std::ostream &out) const {
288 CYWord::Output(out);
289 }
290
291 void CYNumber::Output(std::ostream &out) const {
292 // XXX: this is not a useful formatting
293 out << Value();
294 }
295
296 void CYObject::Output(std::ostream &out) const {
297 out << '{';
298 if (property_ != NULL)
299 property_->Output(out);
300 out << '}';
301 }
302
303 void CYParameter::Output(std::ostream &out) const {
304 out << *name_;
305 if (next_ != NULL) {
306 out << ',';
307 out << *next_;
308 }
309 }
310
311 void CYPostfix::Output(std::ostream &out) const {
312 lhs_->Output(out, Precedence());
313 out << Operator();
314 }
315
316 void CYPrefix::Output(std::ostream &out) const {
317 out << Operator();
318 rhs_->Output(out, Precedence());
319 }
320
321 void CYProperty::Output(std::ostream &out) const {
322 out << *name_ << ':';
323 value_->Output(out, CYPA);
324 if (next_ != NULL) {
325 out << ',';
326 next_->Output(out);
327 }
328 }
329
330 void CYReturn::Output(std::ostream &out) const {
331 out << "return";
332 if (value_ != NULL) {
333 out << ' ';
334 value_->Output(out);
335 }
336 out << ';';
337 }
338
339 void CYSelector::Output(std::ostream &out) const {
340 out << "new SEL(\"";
341 if (name_ != NULL)
342 name_->Output(out);
343 out << "\")";
344 }
345
346 void CYSelectorPart::Output(std::ostream &out) const {
347 if (name_ != NULL)
348 out << *name_;
349 if (value_)
350 out << ':';
351 if (next_ != NULL)
352 next_->Output(out);
353 }
354
355 void CYSource::Show(std::ostream &out) const {
356 for (const CYSource *next(this); next != NULL; next = next->next_)
357 next->Output(out, false);
358 }
359
360 void CYSource::Output(std::ostream &out, bool block) const {
361 if (!block && next_ == NULL)
362 Output(out);
363 else {
364 out << '{';
365 Show(out);
366 out << '}';
367 }
368 }
369
370 void CYString::Output(std::ostream &out) const {
371 out << '\"';
372 for (const char *value(value_), *end(value_ + size_); value != end; ++value)
373 switch (*value) {
374 case '"': out << "\\\""; break;
375 case '\\': out << "\\\\"; break;
376 case '\b': out << "\\b"; break;
377 case '\f': out << "\\f"; break;
378 case '\n': out << "\\n"; break;
379 case '\r': out << "\\r"; break;
380 case '\t': out << "\\t"; break;
381 case '\v': out << "\\v"; break;
382
383 default:
384 if (*value < 0x20 || *value >= 0x7f)
385 out << "\\x" << std::setbase(16) << std::setw(2) << std::setfill('0') << unsigned(*value);
386 else
387 out << *value;
388 }
389 out << '\"';
390 }
391
392 void CYSwitch::Output(std::ostream &out) const {
393 out << "switch(";
394 value_->Output(out);
395 out << "){";
396 if (clauses_ != NULL)
397 out << *clauses_;
398 out << '}';
399 }
400
401 void CYThis::Output(std::ostream &out) const {
402 CYWord::Output(out);
403 }
404
405 void CYThrow::Output(std::ostream &out) const {
406 out << "throw";
407 if (value_ != NULL) {
408 out << ' ';
409 value_->Output(out);
410 }
411 out << ';';
412 }
413
414 void CYTry::Output(std::ostream &out) const {
415 out << "try";
416 try_->Output(out, true);
417 if (catch_ != NULL)
418 out << catch_;
419 if (finally_ != NULL) {
420 out << "finally";
421 finally_->Output(out, true);
422 }
423 }
424
425 void CYVariable::Output(std::ostream &out) const {
426 out << *name_;
427 }
428
429 void CYWhile::Output(std::ostream &out) const {
430 out << "while(";
431 test_->Output(out);
432 out << ')';
433 code_->Output(out, false);
434 }
435
436 void CYWith::Output(std::ostream &out) const {
437 out << "with(";
438 scope_->Output(out);
439 out << ')';
440 code_->Output(out, false);
441 }
442
443 void CYWord::Output(std::ostream &out) const {
444 out << Value();
445 }