]>
Commit | Line | Data |
---|---|---|
5999c315 JF |
1 | #include "Parser.hpp" |
2 | ||
3 | #include <iostream> | |
4 | #include <iomanip> | |
5 | ||
4afefdd9 JF |
6 | #include <objc/runtime.h> |
7 | #include <sstream> | |
8 | ||
b09da87b JF |
9 | _finline CYFlags operator ~(CYFlags rhs) { |
10 | return static_cast<CYFlags>(~static_cast<unsigned>(rhs)); | |
11 | } | |
12 | ||
13 | _finline CYFlags operator &(CYFlags lhs, CYFlags rhs) { | |
14 | return static_cast<CYFlags>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs)); | |
15 | } | |
16 | ||
17 | _finline CYFlags operator |(CYFlags lhs, CYFlags rhs) { | |
18 | return static_cast<CYFlags>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs)); | |
19 | } | |
20 | ||
21 | _finline CYFlags &operator |=(CYFlags &lhs, CYFlags rhs) { | |
22 | return lhs = lhs | rhs; | |
23 | } | |
24 | ||
25 | _finline CYFlags CYLeft(CYFlags flags) { | |
26 | return flags & ~CYNoTrailer; | |
27 | } | |
28 | ||
29 | _finline CYFlags CYCenter(CYFlags flags) { | |
30 | return flags & CYNoIn; | |
31 | } | |
32 | ||
33 | _finline CYFlags CYRight(CYFlags flags) { | |
34 | return flags & (CYNoIn | CYNoTrailer); | |
35 | } | |
36 | ||
37 | bool CYFalse::Value() const { | |
38 | return false; | |
39 | } | |
40 | ||
41 | bool CYTrue::Value() const { | |
42 | return true; | |
43 | } | |
44 | ||
d35a3b07 JF |
45 | #define CYPA 16 |
46 | ||
b09da87b JF |
47 | void CYAddressOf::Output(std::ostream &out, CYFlags flags) const { |
48 | rhs_->Output(out, 1, CYLeft(flags)); | |
9b5527f0 | 49 | out << ".$cya()"; |
5999c315 JF |
50 | } |
51 | ||
d35a3b07 JF |
52 | void CYArgument::Output(std::ostream &out) const { |
53 | if (name_ != NULL) { | |
5999c315 JF |
54 | out << *name_; |
55 | if (value_ != NULL) | |
56 | out << ":"; | |
57 | } | |
d35a3b07 | 58 | if (value_ != NULL) |
b09da87b | 59 | value_->Output(out, CYPA, CYNoFlags); |
5999c315 | 60 | if (next_ != NULL) { |
d35a3b07 JF |
61 | if (next_->name_ == NULL) |
62 | out << ','; | |
63 | else | |
64 | out << ' '; | |
65 | next_->Output(out); | |
5999c315 JF |
66 | } |
67 | } | |
68 | ||
b09da87b | 69 | void CYArray::Output(std::ostream &out, CYFlags flags) const { |
5befe15e JF |
70 | out << '['; |
71 | if (elements_ != NULL) | |
72 | elements_->Output(out); | |
73 | out << ']'; | |
74 | } | |
75 | ||
75b0a457 JF |
76 | void CYArrayComprehension::Output(std::ostream &out, CYFlags flags) const { |
77 | // XXX: I don't necc. need the ()s | |
78 | out << "(function($cyv"; | |
79 | for (CYComprehension *comprehension(comprehensions_); comprehension != NULL; comprehension = comprehension->next_) | |
80 | if (const char *name = comprehension->Name()) | |
81 | out << ',' << name; | |
82 | out << "){"; | |
dc81e1c2 | 83 | out << "$cyv=[];"; |
75b0a457 | 84 | comprehensions_->Output(out); |
dc81e1c2 | 85 | out << "$cyv.push("; |
75b0a457 JF |
86 | expression_->Output(out, CYPA, CYNoFlags); |
87 | out << ");"; | |
88 | for (CYComprehension *comprehension(comprehensions_); comprehension != NULL; comprehension = comprehension->next_) | |
89 | comprehension->End_(out); | |
dc81e1c2 | 90 | out << "return $cyv;"; |
75b0a457 JF |
91 | out << "}())"; |
92 | } | |
93 | ||
b09da87b JF |
94 | void CYAssignment::Output(std::ostream &out, CYFlags flags) const { |
95 | lhs_->Output(out, Precedence() - 1, CYLeft(flags)); | |
d35a3b07 | 96 | out << Operator(); |
b09da87b | 97 | rhs_->Output(out, Precedence(), CYRight(flags)); |
d35a3b07 JF |
98 | } |
99 | ||
9e562cfc JF |
100 | void CYBlock::Output(std::ostream &out) const { |
101 | for (CYSource *statement(statements_); statement != NULL; statement = statement->next_) | |
102 | statement->Output(out); | |
103 | } | |
104 | ||
b09da87b JF |
105 | void CYBoolean::Output(std::ostream &out, CYFlags flags) const { |
106 | if ((flags & CYNoLeader) != 0) | |
107 | out << ' '; | |
5999c315 | 108 | out << (Value() ? "true" : "false"); |
b09da87b JF |
109 | if ((flags & CYNoTrailer) != 0) |
110 | out << ' '; | |
5999c315 JF |
111 | } |
112 | ||
113 | void CYBreak::Output(std::ostream &out) const { | |
114 | out << "break"; | |
115 | if (label_ != NULL) | |
116 | out << ' ' << *label_; | |
117 | out << ';'; | |
118 | } | |
119 | ||
b09da87b JF |
120 | void CYCall::Output(std::ostream &out, CYFlags flags) const { |
121 | function_->Output(out, Precedence(), CYLeft(flags)); | |
d35a3b07 | 122 | out << '('; |
5999c315 | 123 | if (arguments_ != NULL) |
d35a3b07 | 124 | arguments_->Output(out); |
5999c315 JF |
125 | out << ')'; |
126 | } | |
127 | ||
128 | void CYCatch::Output(std::ostream &out) const { | |
129 | out << "catch(" << *name_ << ')'; | |
130 | code_->Output(out, true); | |
131 | } | |
132 | ||
e5bc40db JF |
133 | void CYCategory::Output(std::ostream &out) const { |
134 | out << "(function($cys,$cyp,$cyc,$cyn,$cyt){"; | |
135 | out << "$cyp=object_getClass($cys);"; | |
136 | out << "$cyc=$cys;"; | |
137 | if (messages_ != NULL) | |
138 | messages_->Output(out, true); | |
139 | out << "})("; | |
367eebb1 | 140 | name_->ClassName(out, true); |
e5bc40db JF |
141 | out << ");"; |
142 | } | |
143 | ||
365abb0a JF |
144 | void CYClass::Output(std::ostream &out) const { |
145 | Output(out, CYNoBF); | |
146 | out << ";"; | |
147 | } | |
148 | ||
367eebb1 JF |
149 | void CYClass::Output(std::ostream &out, CYFlags flags) const { |
150 | // XXX: I don't necc. need the ()s | |
e5bc40db JF |
151 | out << "(function($cys,$cyp,$cyc,$cyn,$cyt,$cym){"; |
152 | out << "$cyp=object_getClass($cys);"; | |
367eebb1 JF |
153 | out << "$cyc=objc_allocateClassPair($cys,"; |
154 | if (name_ != NULL) | |
155 | name_->ClassName(out, false); | |
156 | else | |
157 | out << "$cyq(\"CY$\")"; | |
158 | out << ",0);"; | |
b09da87b JF |
159 | out << "$cym=object_getClass($cyc);"; |
160 | if (fields_ != NULL) | |
161 | fields_->Output(out); | |
162 | if (messages_ != NULL) | |
e5bc40db | 163 | messages_->Output(out, false); |
b09da87b | 164 | out << "objc_registerClassPair($cyc);"; |
367eebb1 JF |
165 | out << "return $cyc;"; |
166 | out << "}("; | |
b09da87b JF |
167 | if (super_ != NULL) |
168 | super_->Output(out, CYPA, CYNoFlags); | |
169 | else | |
170 | out << "null"; | |
367eebb1 | 171 | out << "))"; |
b09da87b JF |
172 | } |
173 | ||
e5bc40db JF |
174 | void CYCompound::Output(std::ostream &out, CYFlags flags) const { |
175 | if (CYExpression *expression = expressions_) | |
176 | if (CYExpression *next = expression->next_) { | |
177 | expression->Output(out, CYLeft(flags)); | |
178 | CYFlags center(CYCenter(flags)); | |
179 | while (next != NULL) { | |
180 | expression = next; | |
181 | out << ','; | |
182 | next = expression->next_; | |
183 | CYFlags right(next != NULL ? center : CYRight(flags)); | |
184 | expression->Output(out, right); | |
185 | } | |
186 | } else | |
187 | expression->Output(out, flags); | |
188 | } | |
189 | ||
75b0a457 JF |
190 | void CYComprehension::Output(std::ostream &out) const { |
191 | Begin_(out); | |
192 | if (next_ != NULL) | |
193 | next_->Output(out); | |
194 | } | |
195 | ||
b09da87b JF |
196 | void CYCondition::Output(std::ostream &out, CYFlags flags) const { |
197 | test_->Output(out, Precedence() - 1, CYLeft(flags)); | |
d35a3b07 | 198 | out << '?'; |
5999c315 | 199 | if (true_ != NULL) |
b09da87b | 200 | true_->Output(out, CYPA, CYNoFlags); |
d35a3b07 | 201 | out << ':'; |
b09da87b | 202 | false_->Output(out, CYPA, CYRight(flags)); |
5999c315 JF |
203 | } |
204 | ||
205 | void CYContinue::Output(std::ostream &out) const { | |
206 | out << "continue"; | |
207 | if (label_ != NULL) | |
208 | out << ' ' << *label_; | |
209 | out << ';'; | |
210 | } | |
211 | ||
212 | void CYClause::Output(std::ostream &out) const { | |
d35a3b07 JF |
213 | if (case_ != NULL) { |
214 | out << "case"; | |
cac61857 | 215 | case_->Output(out, CYNoLeader); |
d35a3b07 | 216 | } else |
5999c315 JF |
217 | out << "default"; |
218 | out << ':'; | |
219 | if (code_ != NULL) | |
220 | code_->Output(out, false); | |
cac61857 JF |
221 | if (next_ != NULL) |
222 | out << *next_; | |
223 | } | |
224 | ||
225 | const char *CYDeclaration::ForEachIn() const { | |
226 | return identifier_->Value(); | |
5999c315 JF |
227 | } |
228 | ||
cac61857 | 229 | void CYDeclaration::ForIn(std::ostream &out, CYFlags flags) const { |
75b0a457 JF |
230 | if ((flags & CYNoLeader) != 0) |
231 | out << ' '; | |
5999c315 | 232 | out << "var "; |
75b0a457 JF |
233 | Output(out, CYRight(flags)); |
234 | } | |
235 | ||
236 | void CYDeclaration::ForEachIn(std::ostream &out) const { | |
237 | out << *identifier_; | |
5999c315 JF |
238 | } |
239 | ||
75b0a457 | 240 | void CYDeclaration::Output(std::ostream &out, CYFlags flags) const { |
5999c315 | 241 | out << *identifier_; |
d35a3b07 JF |
242 | if (initialiser_ != NULL) { |
243 | out << '='; | |
75b0a457 JF |
244 | initialiser_->Output(out, CYPA, CYRight(flags)); |
245 | } else if ((flags & CYNoTrailer) != 0) | |
246 | out << ' '; | |
5999c315 JF |
247 | } |
248 | ||
cac61857 | 249 | void CYDeclarations::For(std::ostream &out) const { |
5999c315 | 250 | out << "var "; |
cac61857 JF |
251 | Output(out, CYNoIn); |
252 | } | |
d35a3b07 | 253 | |
cac61857 | 254 | void CYDeclarations::Output(std::ostream &out, CYFlags flags) const { |
5999c315 | 255 | const CYDeclarations *declaration(this); |
d35a3b07 | 256 | output: |
75b0a457 JF |
257 | CYDeclarations *next(declaration->next_); |
258 | CYFlags right(next == NULL ? CYRight(flags) : CYCenter(flags)); | |
259 | declaration->declaration_->Output(out, right); | |
d35a3b07 | 260 | |
75b0a457 | 261 | if (next != NULL) { |
d35a3b07 | 262 | out << ','; |
75b0a457 | 263 | declaration = next; |
d35a3b07 JF |
264 | goto output; |
265 | } | |
5999c315 JF |
266 | } |
267 | ||
9b5527f0 JF |
268 | void CYDirectMember::Output(std::ostream &out, CYFlags flags) const { |
269 | object_->Output(out, Precedence(), CYLeft(flags)); | |
270 | if (const char *word = property_->Word()) | |
271 | out << '.' << word; | |
272 | else { | |
273 | out << '['; | |
274 | property_->Output(out, CYNoFlags); | |
275 | out << ']'; | |
276 | } | |
277 | } | |
278 | ||
5999c315 | 279 | void CYDoWhile::Output(std::ostream &out) const { |
b09da87b | 280 | // XXX: extra space character! |
5999c315 JF |
281 | out << "do "; |
282 | code_->Output(out, false); | |
d35a3b07 | 283 | out << "while("; |
b09da87b JF |
284 | test_->Output(out, CYNoFlags); |
285 | out << ')'; | |
5999c315 JF |
286 | } |
287 | ||
5befe15e | 288 | void CYElement::Output(std::ostream &out) const { |
5999c315 | 289 | if (value_ != NULL) |
b09da87b | 290 | value_->Output(out, CYPA, CYNoFlags); |
5befe15e | 291 | if (next_ != NULL || value_ == NULL) |
5999c315 | 292 | out << ','; |
5befe15e JF |
293 | if (next_ != NULL) |
294 | next_->Output(out); | |
5999c315 JF |
295 | } |
296 | ||
297 | void CYEmpty::Output(std::ostream &out) const { | |
298 | out << ';'; | |
299 | } | |
300 | ||
301 | void CYEmpty::Output(std::ostream &out, bool block) const { | |
302 | if (next_ != NULL) | |
303 | CYSource::Output(out, block); | |
304 | else | |
305 | out << "{}"; | |
306 | } | |
307 | ||
308 | void CYExpress::Output(std::ostream &out) const { | |
365abb0a | 309 | expression_->Output(out, CYNoBF); |
5999c315 JF |
310 | out << ';'; |
311 | } | |
312 | ||
367eebb1 | 313 | void CYExpression::ClassName(std::ostream &out, bool object) const { |
e5bc40db JF |
314 | Output(out, CYPA, CYNoFlags); |
315 | } | |
316 | ||
cac61857 JF |
317 | const char *CYExpression::ForEachIn() const { |
318 | return NULL; | |
319 | } | |
320 | ||
321 | void CYExpression::For(std::ostream &out) const { | |
322 | Output(out, CYNoIn); | |
323 | } | |
324 | ||
75b0a457 JF |
325 | void CYExpression::ForEachIn(std::ostream &out) const { |
326 | // XXX: this should handle LeftHandSideExpression | |
327 | Output(out, CYPA, CYNoFlags); | |
328 | } | |
329 | ||
cac61857 | 330 | void CYExpression::ForIn(std::ostream &out, CYFlags flags) const { |
d35a3b07 | 331 | // XXX: this should handle LeftHandSideExpression |
75b0a457 | 332 | Output(out, flags); |
d35a3b07 JF |
333 | } |
334 | ||
b09da87b JF |
335 | void CYExpression::Output(std::ostream &out, unsigned precedence, CYFlags flags) const { |
336 | if (precedence < Precedence()) { | |
5999c315 | 337 | out << '('; |
b09da87b | 338 | Output(out, CYNoFlags); |
5999c315 | 339 | out << ')'; |
b09da87b JF |
340 | } else |
341 | Output(out, flags); | |
342 | } | |
343 | ||
344 | void CYField::Output(std::ostream &out) const { | |
345 | // XXX: implement! | |
5999c315 JF |
346 | } |
347 | ||
348 | void CYFor::Output(std::ostream &out) const { | |
349 | out << "for("; | |
350 | if (initialiser_ != NULL) | |
cac61857 | 351 | initialiser_->For(out); |
5999c315 JF |
352 | out << ';'; |
353 | if (test_ != NULL) | |
b09da87b | 354 | test_->Output(out, CYNoFlags); |
5999c315 JF |
355 | out << ';'; |
356 | if (increment_ != NULL) | |
b09da87b | 357 | increment_->Output(out, CYNoFlags); |
5999c315 JF |
358 | out << ')'; |
359 | code_->Output(out, false); | |
360 | } | |
361 | ||
75b0a457 | 362 | void CYForEachIn::Output(std::ostream &out) const { |
6f926cee | 363 | out << "with({$cys:0,$cyt:0}){"; |
75b0a457 | 364 | |
75b0a457 JF |
365 | out << "$cys="; |
366 | set_->Output(out, CYPA, CYNoFlags); | |
367 | out << ";"; | |
368 | ||
369 | out << "for($cyt in $cys){"; | |
370 | ||
371 | initialiser_->ForEachIn(out); | |
372 | out << "=$cys[$cyt];"; | |
373 | ||
374 | code_->Show(out); | |
375 | ||
6f926cee | 376 | out << '}'; |
75b0a457 | 377 | |
6f926cee | 378 | out << '}'; |
75b0a457 JF |
379 | } |
380 | ||
381 | void CYForEachInComprehension::Begin_(std::ostream &out) const { | |
382 | out << "(function($cys){"; | |
383 | out << "$cys="; | |
384 | set_->Output(out, CYPA, CYNoFlags); | |
385 | out << ";"; | |
386 | ||
387 | out << "for(" << *name_ << " in $cys){"; | |
388 | out << *name_ << "=$cys[" << *name_ << "];"; | |
389 | } | |
390 | ||
391 | void CYForEachInComprehension::End_(std::ostream &out) const { | |
392 | out << "}}());"; | |
393 | } | |
394 | ||
5999c315 JF |
395 | void CYForIn::Output(std::ostream &out) const { |
396 | out << "for("; | |
cac61857 | 397 | initialiser_->ForIn(out, CYNoIn | CYNoTrailer); |
b09da87b JF |
398 | out << "in"; |
399 | set_->Output(out, CYNoLeader); | |
5999c315 JF |
400 | out << ')'; |
401 | code_->Output(out, false); | |
402 | } | |
403 | ||
75b0a457 JF |
404 | void CYForInComprehension::Begin_(std::ostream &out) const { |
405 | out << "for(" << *name_ << " in"; | |
406 | set_->Output(out, CYNoLeader); | |
407 | out << ')'; | |
408 | } | |
409 | ||
5999c315 | 410 | void CYFunction::Output(std::ostream &out) const { |
b09da87b JF |
411 | CYLambda::Output(out, CYNoFlags); |
412 | } | |
413 | ||
414 | void CYFunctionParameter::Output(std::ostream &out) const { | |
415 | out << *name_; | |
416 | if (next_ != NULL) { | |
417 | out << ','; | |
418 | out << *next_; | |
419 | } | |
5999c315 JF |
420 | } |
421 | ||
422 | void CYIf::Output(std::ostream &out) const { | |
d35a3b07 | 423 | out << "if("; |
b09da87b | 424 | test_->Output(out, CYNoFlags); |
d35a3b07 | 425 | out << ')'; |
5999c315 JF |
426 | true_->Output(out, true); |
427 | if (false_ != NULL) { | |
428 | out << "else "; | |
429 | false_->Output(out, false); | |
430 | } | |
431 | } | |
432 | ||
75b0a457 JF |
433 | void CYIfComprehension::Begin_(std::ostream &out) const { |
434 | out << "if("; | |
435 | test_->Output(out, CYNoFlags); | |
436 | out << ')'; | |
437 | } | |
438 | ||
b09da87b JF |
439 | void CYIndirect::Output(std::ostream &out, CYFlags flags) const { |
440 | rhs_->Output(out, 1, CYLeft(flags)); | |
9b5527f0 JF |
441 | out << ".$cyi"; |
442 | } | |
443 | ||
444 | void CYIndirectMember::Output(std::ostream &out, CYFlags flags) const { | |
445 | object_->Output(out, Precedence(), CYLeft(flags)); | |
446 | out << ".$cyi"; | |
447 | if (const char *word = property_->Word()) | |
448 | out << '.' << word; | |
449 | else { | |
450 | out << '['; | |
451 | property_->Output(out, CYNoFlags); | |
452 | out << ']'; | |
453 | } | |
5999c315 JF |
454 | } |
455 | ||
b09da87b JF |
456 | void CYInfix::Output(std::ostream &out, CYFlags flags) const { |
457 | const char *name(Operator()); | |
458 | bool protect((flags & CYNoIn) != 0 && strcmp(name, "in")); | |
459 | if (protect) | |
460 | out << '('; | |
461 | bool alphabetic(Alphabetic()); | |
462 | CYFlags left(protect ? CYNoFlags : CYLeft(flags)); | |
463 | if (alphabetic) | |
464 | left |= CYNoTrailer; | |
465 | lhs_->Output(out, Precedence(), left); | |
466 | out << name; | |
467 | CYFlags right(protect ? CYNoFlags : CYRight(flags)); | |
468 | if (alphabetic) | |
469 | right |= CYNoLeader; | |
1ef7d061 JF |
470 | if (strcmp(name, "-") == 0) |
471 | right |= CYNoHyphen; | |
b09da87b JF |
472 | rhs_->Output(out, Precedence() - 1, right); |
473 | if (protect) | |
474 | out << ')'; | |
5999c315 JF |
475 | } |
476 | ||
b09da87b JF |
477 | void CYLambda::Output(std::ostream &out, CYFlags flags) const { |
478 | bool protect((flags & CYNoFunction) != 0); | |
479 | if (protect) | |
480 | out << '('; | |
83b5afe2 JF |
481 | else if ((flags & CYNoLeader) != 0) |
482 | out << ' '; | |
5999c315 JF |
483 | out << "function"; |
484 | if (name_ != NULL) | |
485 | out << ' ' << *name_; | |
486 | out << '('; | |
487 | if (parameters_ != NULL) | |
488 | out << *parameters_; | |
b09da87b JF |
489 | out << "){"; |
490 | if (body_ != NULL) | |
491 | body_->Show(out); | |
492 | out << '}'; | |
493 | if (protect) | |
494 | out << ')'; | |
5999c315 JF |
495 | } |
496 | ||
cac61857 JF |
497 | void CYLet::Output(std::ostream &out) const { |
498 | out << "let("; | |
499 | declarations_->Output(out, CYNoFlags); | |
500 | out << "){"; | |
501 | if (statements_ != NULL) | |
502 | statements_->Show(out); | |
503 | out << "}"; | |
504 | } | |
505 | ||
e5bc40db | 506 | void CYMessage::Output(std::ostream &out, bool replace) const { |
4e8c99fb | 507 | if (next_ != NULL) |
e5bc40db | 508 | next_->Output(out, replace); |
b09da87b JF |
509 | out << "$cyn=new Selector(\""; |
510 | for (CYMessageParameter *parameter(parameter_); parameter != NULL; parameter = parameter->next_) | |
511 | if (parameter->tag_ != NULL) { | |
512 | out << *parameter->tag_; | |
513 | if (parameter->name_ != NULL) | |
5999c315 JF |
514 | out << ':'; |
515 | } | |
b09da87b | 516 | out << "\");"; |
e5bc40db JF |
517 | out << "$cyt=$cyn.type($cy" << (instance_ ? 's' : 'p') << ");"; |
518 | out << "class_" << (replace ? "replace" : "add") << "Method($cy" << (instance_ ? 'c' : 'm') << ",$cyn,"; | |
478d4ed0 | 519 | out << "new Functor(function(self,_cmd"; |
b09da87b | 520 | for (CYMessageParameter *parameter(parameter_); parameter != NULL; parameter = parameter->next_) |
478d4ed0 JF |
521 | if (parameter->name_ != NULL) |
522 | out << ',' << *parameter->name_; | |
523 | out << "){return function(){"; | |
b09da87b JF |
524 | if (body_ != NULL) |
525 | body_->Show(out); | |
478d4ed0 | 526 | out << "}.call(self);},$cyt),$cyt);"; |
5999c315 JF |
527 | } |
528 | ||
b09da87b | 529 | void CYNew::Output(std::ostream &out, CYFlags flags) const { |
bce8339b JF |
530 | if ((flags & CYNoLeader) != 0) |
531 | out << ' '; | |
d35a3b07 | 532 | out << "new"; |
b09da87b | 533 | constructor_->Output(out, Precedence(), CYCenter(flags) | CYNoLeader); |
d35a3b07 | 534 | out << '('; |
5999c315 | 535 | if (arguments_ != NULL) |
d35a3b07 | 536 | arguments_->Output(out); |
5999c315 JF |
537 | out << ')'; |
538 | } | |
539 | ||
b09da87b JF |
540 | void CYNull::Output(std::ostream &out, CYFlags flags) const { |
541 | if ((flags & CYNoLeader) != 0) | |
542 | out << ' '; | |
5999c315 | 543 | CYWord::Output(out); |
b09da87b JF |
544 | if ((flags & CYNoTrailer) != 0) |
545 | out << ' '; | |
5999c315 JF |
546 | } |
547 | ||
b09da87b | 548 | void CYNumber::Output(std::ostream &out, CYFlags flags) const { |
1ef7d061 JF |
549 | double value(Value()); |
550 | if ((flags & CYNoLeader) != 0 || value < 0 && (flags & CYNoHyphen) != 0) | |
b09da87b | 551 | out << ' '; |
18401062 | 552 | // XXX: decide on correct precision |
1ef7d061 | 553 | out << std::setprecision(9) << value; |
b09da87b JF |
554 | if ((flags & CYNoTrailer) != 0) |
555 | out << ' '; | |
5999c315 JF |
556 | } |
557 | ||
e5bc40db JF |
558 | void CYNumber::PropertyName(std::ostream &out) const { |
559 | Output(out); | |
560 | } | |
561 | ||
b09da87b JF |
562 | void CYObject::Output(std::ostream &out, CYFlags flags) const { |
563 | bool protect((flags & CYNoBrace) != 0); | |
564 | if (protect) | |
565 | out << '('; | |
693d501b JF |
566 | out << '{'; |
567 | if (property_ != NULL) | |
568 | property_->Output(out); | |
569 | out << '}'; | |
b09da87b JF |
570 | if (protect) |
571 | out << ')'; | |
693d501b JF |
572 | } |
573 | ||
b09da87b JF |
574 | void CYPostfix::Output(std::ostream &out, CYFlags flags) const { |
575 | lhs_->Output(out, Precedence(), CYLeft(flags)); | |
d35a3b07 | 576 | out << Operator(); |
5999c315 JF |
577 | } |
578 | ||
b09da87b | 579 | void CYPrefix::Output(std::ostream &out, CYFlags flags) const { |
1ef7d061 | 580 | const char *name(Operator()); |
b09da87b | 581 | bool alphabetic(Alphabetic()); |
1ef7d061 JF |
582 | if (alphabetic && (flags & CYNoLeader) != 0 || name[0] == '-' && (flags & CYNoHyphen) != 0) |
583 | out << ' '; | |
584 | out << name; | |
b09da87b JF |
585 | CYFlags right(CYRight(flags)); |
586 | if (alphabetic) | |
587 | right |= CYNoLeader; | |
588 | rhs_->Output(out, Precedence(), right); | |
5999c315 JF |
589 | } |
590 | ||
693d501b | 591 | void CYProperty::Output(std::ostream &out) const { |
e5bc40db | 592 | name_->PropertyName(out); |
579ed526 | 593 | out << ':'; |
b09da87b | 594 | value_->Output(out, CYPA, CYNoFlags); |
5999c315 JF |
595 | if (next_ != NULL) { |
596 | out << ','; | |
693d501b | 597 | next_->Output(out); |
5999c315 | 598 | } |
5999c315 JF |
599 | } |
600 | ||
601 | void CYReturn::Output(std::ostream &out) const { | |
602 | out << "return"; | |
b09da87b JF |
603 | if (value_ != NULL) |
604 | value_->Output(out, CYNoLeader); | |
5999c315 JF |
605 | out << ';'; |
606 | } | |
607 | ||
b09da87b | 608 | void CYSelector::Output(std::ostream &out, CYFlags flags) const { |
bce8339b JF |
609 | if ((flags & CYNoLeader) != 0) |
610 | out << ' '; | |
b09da87b | 611 | out << "new Selector(\""; |
62014ea9 JF |
612 | if (name_ != NULL) |
613 | name_->Output(out); | |
dea834b0 | 614 | out << "\")"; |
e7ed5354 JF |
615 | } |
616 | ||
62014ea9 JF |
617 | void CYSelectorPart::Output(std::ostream &out) const { |
618 | if (name_ != NULL) | |
619 | out << *name_; | |
620 | if (value_) | |
621 | out << ':'; | |
622 | if (next_ != NULL) | |
623 | next_->Output(out); | |
624 | } | |
625 | ||
b09da87b | 626 | void CYSend::Output(std::ostream &out, CYFlags flags) const { |
c239b9f8 JF |
627 | if ((flags & CYNoLeader) != 0) |
628 | out << ' '; | |
b09da87b JF |
629 | out << "objc_msgSend("; |
630 | self_->Output(out, CYPA, CYNoFlags); | |
4afefdd9 JF |
631 | out << ","; |
632 | std::ostringstream name; | |
b09da87b JF |
633 | for (CYArgument *argument(arguments_); argument != NULL; argument = argument->next_) |
634 | if (argument->name_ != NULL) { | |
4afefdd9 | 635 | name << *argument->name_; |
b09da87b | 636 | if (argument->value_ != NULL) |
4afefdd9 | 637 | name << ':'; |
b09da87b | 638 | } |
4afefdd9 | 639 | out << reinterpret_cast<void *>(sel_registerName(name.str().c_str())); |
b09da87b JF |
640 | for (CYArgument *argument(arguments_); argument != NULL; argument = argument->next_) |
641 | if (argument->value_ != NULL) { | |
642 | out << ","; | |
643 | argument->value_->Output(out, CYPA, CYNoFlags); | |
644 | } | |
645 | out << ')'; | |
646 | } | |
647 | ||
b1ff2d78 | 648 | void CYSource::Show(std::ostream &out) const { |
5999c315 | 649 | for (const CYSource *next(this); next != NULL; next = next->next_) |
9e562cfc | 650 | next->Output_(out); |
5999c315 JF |
651 | } |
652 | ||
653 | void CYSource::Output(std::ostream &out, bool block) const { | |
9e562cfc | 654 | if (!block && !IsBlock()) |
5999c315 JF |
655 | Output(out); |
656 | else { | |
657 | out << '{'; | |
b1ff2d78 | 658 | Show(out); |
5999c315 JF |
659 | out << '}'; |
660 | } | |
661 | } | |
662 | ||
9e562cfc JF |
663 | void CYSource::Output_(std::ostream &out) const { |
664 | Output(out); | |
665 | } | |
666 | ||
667 | void CYStatement::Output_(std::ostream &out) const { | |
668 | for (CYLabel *label(labels_); label != NULL; label = label->next_) | |
669 | out << *label->name_ << ':'; | |
670 | Output(out); | |
671 | } | |
672 | ||
b09da87b | 673 | void CYString::Output(std::ostream &out, CYFlags flags) const { |
b4aa79af JF |
674 | unsigned quot(0), apos(0); |
675 | for (const char *value(value_), *end(value_ + size_); value != end; ++value) | |
676 | if (*value == '"') | |
677 | ++quot; | |
678 | else if (*value == '\'') | |
679 | ++apos; | |
680 | ||
681 | bool single(quot > apos); | |
682 | ||
683 | out << (single ? '\'' : '"'); | |
5999c315 JF |
684 | for (const char *value(value_), *end(value_ + size_); value != end; ++value) |
685 | switch (*value) { | |
5999c315 JF |
686 | case '\\': out << "\\\\"; break; |
687 | case '\b': out << "\\b"; break; | |
688 | case '\f': out << "\\f"; break; | |
689 | case '\n': out << "\\n"; break; | |
690 | case '\r': out << "\\r"; break; | |
691 | case '\t': out << "\\t"; break; | |
692 | case '\v': out << "\\v"; break; | |
693 | ||
b4aa79af JF |
694 | case '"': |
695 | if (!single) | |
696 | out << "\\\""; | |
697 | else goto simple; | |
698 | break; | |
699 | ||
700 | case '\'': | |
701 | if (single) | |
702 | out << "\\'"; | |
703 | else goto simple; | |
704 | break; | |
705 | ||
5999c315 JF |
706 | default: |
707 | if (*value < 0x20 || *value >= 0x7f) | |
708 | out << "\\x" << std::setbase(16) << std::setw(2) << std::setfill('0') << unsigned(*value); | |
b4aa79af | 709 | else simple: |
5999c315 JF |
710 | out << *value; |
711 | } | |
b4aa79af | 712 | out << (single ? '\'' : '"'); |
5999c315 JF |
713 | } |
714 | ||
e5bc40db JF |
715 | void CYString::PropertyName(std::ostream &out) const { |
716 | if (const char *word = Word()) | |
717 | out << word; | |
718 | else | |
719 | Output(out); | |
720 | } | |
721 | ||
5999c315 | 722 | void CYSwitch::Output(std::ostream &out) const { |
d35a3b07 | 723 | out << "switch("; |
b09da87b | 724 | value_->Output(out, CYNoFlags); |
d35a3b07 | 725 | out << "){"; |
5999c315 JF |
726 | if (clauses_ != NULL) |
727 | out << *clauses_; | |
728 | out << '}'; | |
729 | } | |
730 | ||
b09da87b JF |
731 | void CYThis::Output(std::ostream &out, CYFlags flags) const { |
732 | if ((flags & CYNoLeader) != 0) | |
733 | out << ' '; | |
5999c315 | 734 | CYWord::Output(out); |
b09da87b JF |
735 | if ((flags & CYNoTrailer) != 0) |
736 | out << ' '; | |
5999c315 JF |
737 | } |
738 | ||
739 | void CYThrow::Output(std::ostream &out) const { | |
d35a3b07 | 740 | out << "throw"; |
b09da87b JF |
741 | if (value_ != NULL) |
742 | value_->Output(out, CYNoLeader); | |
5999c315 JF |
743 | out << ';'; |
744 | } | |
745 | ||
746 | void CYTry::Output(std::ostream &out) const { | |
747 | out << "try"; | |
748 | try_->Output(out, true); | |
749 | if (catch_ != NULL) | |
9b5527f0 | 750 | catch_->Output(out); |
5999c315 JF |
751 | if (finally_ != NULL) { |
752 | out << "finally"; | |
753 | finally_->Output(out, true); | |
754 | } | |
755 | } | |
756 | ||
cac61857 JF |
757 | void CYVar::Output(std::ostream &out) const { |
758 | out << "var "; | |
759 | declarations_->Output(out, CYNoFlags); | |
760 | out << ';'; | |
761 | } | |
762 | ||
b09da87b | 763 | void CYVariable::Output(std::ostream &out, CYFlags flags) const { |
478d4ed0 JF |
764 | if ((flags & CYNoLeader) != 0) |
765 | out << ' '; | |
5999c315 | 766 | out << *name_; |
478d4ed0 JF |
767 | if ((flags & CYNoTrailer) != 0) |
768 | out << ' '; | |
5999c315 JF |
769 | } |
770 | ||
771 | void CYWhile::Output(std::ostream &out) const { | |
d35a3b07 | 772 | out << "while("; |
b09da87b | 773 | test_->Output(out, CYNoFlags); |
d35a3b07 | 774 | out << ')'; |
5999c315 JF |
775 | code_->Output(out, false); |
776 | } | |
777 | ||
778 | void CYWith::Output(std::ostream &out) const { | |
d35a3b07 | 779 | out << "with("; |
b09da87b | 780 | scope_->Output(out, CYNoFlags); |
d35a3b07 | 781 | out << ')'; |
5999c315 JF |
782 | code_->Output(out, false); |
783 | } | |
784 | ||
367eebb1 JF |
785 | void CYWord::ClassName(std::ostream &out, bool object) const { |
786 | if (object) | |
787 | out << "objc_getClass("; | |
788 | out << '"' << Value() << '"'; | |
789 | if (object) | |
790 | out << ')'; | |
e5bc40db JF |
791 | } |
792 | ||
5999c315 JF |
793 | void CYWord::Output(std::ostream &out) const { |
794 | out << Value(); | |
795 | } | |
e5bc40db JF |
796 | |
797 | void CYWord::PropertyName(std::ostream &out) const { | |
798 | Output(out); | |
799 | } |