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