]>
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 | ||
652ec1ba | 47 | void CYAddressOf::Output(CYOutput &out, CYFlags flags) const { |
b09da87b | 48 | rhs_->Output(out, 1, CYLeft(flags)); |
9b5527f0 | 49 | out << ".$cya()"; |
5999c315 JF |
50 | } |
51 | ||
652ec1ba | 52 | void CYArgument::Output(CYOutput &out) const { |
d35a3b07 | 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 | ||
652ec1ba | 69 | void CYArray::Output(CYOutput &out, CYFlags flags) const { |
5befe15e JF |
70 | out << '['; |
71 | if (elements_ != NULL) | |
72 | elements_->Output(out); | |
73 | out << ']'; | |
74 | } | |
75 | ||
652ec1ba | 76 | void CYArrayComprehension::Output(CYOutput &out, CYFlags flags) const { |
75b0a457 JF |
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 | ||
652ec1ba | 94 | void CYAssignment::Output(CYOutput &out, CYFlags flags) const { |
b09da87b | 95 | lhs_->Output(out, Precedence() - 1, CYLeft(flags)); |
d35a3b07 | 96 | out << Operator(); |
b09da87b | 97 | rhs_->Output(out, Precedence(), CYRight(flags)); |
d35a3b07 JF |
98 | } |
99 | ||
652ec1ba | 100 | void CYBlock::Output(CYOutput &out) const { |
9e562cfc JF |
101 | for (CYSource *statement(statements_); statement != NULL; statement = statement->next_) |
102 | statement->Output(out); | |
103 | } | |
104 | ||
652ec1ba | 105 | void CYBoolean::Output(CYOutput &out, CYFlags flags) const { |
b09da87b JF |
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 | ||
652ec1ba | 113 | void CYBreak::Output(CYOutput &out) const { |
5999c315 JF |
114 | out << "break"; |
115 | if (label_ != NULL) | |
116 | out << ' ' << *label_; | |
117 | out << ';'; | |
118 | } | |
119 | ||
652ec1ba | 120 | void CYCall::Output(CYOutput &out, CYFlags flags) const { |
b09da87b | 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 | ||
652ec1ba | 128 | void CYCatch::Output(CYOutput &out) const { |
5999c315 JF |
129 | out << "catch(" << *name_ << ')'; |
130 | code_->Output(out, true); | |
131 | } | |
132 | ||
652ec1ba | 133 | void CYCategory::Output(CYOutput &out) const { |
e5bc40db JF |
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 | ||
652ec1ba | 144 | void CYClass::Output(CYOutput &out) const { |
365abb0a JF |
145 | Output(out, CYNoBF); |
146 | out << ";"; | |
147 | } | |
148 | ||
652ec1ba | 149 | void CYClass::Output(CYOutput &out, CYFlags flags) const { |
367eebb1 | 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 | ||
652ec1ba | 174 | void CYCompound::Output(CYOutput &out, CYFlags flags) const { |
e5bc40db JF |
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 | ||
652ec1ba | 190 | void CYComprehension::Output(CYOutput &out) const { |
75b0a457 JF |
191 | Begin_(out); |
192 | if (next_ != NULL) | |
193 | next_->Output(out); | |
194 | } | |
195 | ||
652ec1ba | 196 | void CYCondition::Output(CYOutput &out, CYFlags flags) const { |
b09da87b | 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 | ||
652ec1ba | 205 | void CYContinue::Output(CYOutput &out) const { |
5999c315 JF |
206 | out << "continue"; |
207 | if (label_ != NULL) | |
208 | out << ' ' << *label_; | |
209 | out << ';'; | |
210 | } | |
211 | ||
652ec1ba | 212 | void CYClause::Output(CYOutput &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 | ||
652ec1ba | 229 | void CYDeclaration::ForIn(CYOutput &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 | ||
652ec1ba | 236 | void CYDeclaration::ForEachIn(CYOutput &out) const { |
75b0a457 | 237 | out << *identifier_; |
5999c315 JF |
238 | } |
239 | ||
652ec1ba | 240 | void CYDeclaration::Output(CYOutput &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 | ||
652ec1ba | 249 | void CYDeclarations::For(CYOutput &out) const { |
5999c315 | 250 | out << "var "; |
cac61857 JF |
251 | Output(out, CYNoIn); |
252 | } | |
d35a3b07 | 253 | |
652ec1ba | 254 | void CYDeclarations::Output(CYOutput &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 | ||
652ec1ba | 268 | void CYDirectMember::Output(CYOutput &out, CYFlags flags) const { |
9b5527f0 JF |
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 | ||
652ec1ba | 279 | void CYDoWhile::Output(CYOutput &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 | ||
652ec1ba | 288 | void CYElement::Output(CYOutput &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 | ||
652ec1ba | 297 | void CYEmpty::Output(CYOutput &out) const { |
5999c315 JF |
298 | out << ';'; |
299 | } | |
300 | ||
652ec1ba | 301 | void CYEmpty::Output(CYOutput &out, bool block) const { |
5999c315 JF |
302 | if (next_ != NULL) |
303 | CYSource::Output(out, block); | |
304 | else | |
305 | out << "{}"; | |
306 | } | |
307 | ||
652ec1ba | 308 | void CYExpress::Output(CYOutput &out) const { |
365abb0a | 309 | expression_->Output(out, CYNoBF); |
5999c315 JF |
310 | out << ';'; |
311 | } | |
312 | ||
652ec1ba | 313 | void CYExpression::ClassName(CYOutput &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 | ||
652ec1ba | 321 | void CYExpression::For(CYOutput &out) const { |
cac61857 JF |
322 | Output(out, CYNoIn); |
323 | } | |
324 | ||
652ec1ba | 325 | void CYExpression::ForEachIn(CYOutput &out) const { |
75b0a457 JF |
326 | // XXX: this should handle LeftHandSideExpression |
327 | Output(out, CYPA, CYNoFlags); | |
328 | } | |
329 | ||
652ec1ba | 330 | void CYExpression::ForIn(CYOutput &out, CYFlags flags) const { |
d35a3b07 | 331 | // XXX: this should handle LeftHandSideExpression |
75b0a457 | 332 | Output(out, flags); |
d35a3b07 JF |
333 | } |
334 | ||
652ec1ba | 335 | void CYExpression::Output(CYOutput &out, unsigned precedence, CYFlags flags) const { |
b09da87b | 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 | ||
652ec1ba | 344 | void CYField::Output(CYOutput &out) const { |
b09da87b | 345 | // XXX: implement! |
5999c315 JF |
346 | } |
347 | ||
652ec1ba | 348 | void CYFor::Output(CYOutput &out) const { |
5999c315 JF |
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 | ||
652ec1ba | 362 | void CYForEachIn::Output(CYOutput &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 | ||
652ec1ba | 381 | void CYForEachInComprehension::Begin_(CYOutput &out) const { |
75b0a457 JF |
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 | ||
652ec1ba | 391 | void CYForEachInComprehension::End_(CYOutput &out) const { |
75b0a457 JF |
392 | out << "}}());"; |
393 | } | |
394 | ||
652ec1ba | 395 | void CYForIn::Output(CYOutput &out) const { |
5999c315 | 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 | ||
652ec1ba | 404 | void CYForInComprehension::Begin_(CYOutput &out) const { |
75b0a457 JF |
405 | out << "for(" << *name_ << " in"; |
406 | set_->Output(out, CYNoLeader); | |
407 | out << ')'; | |
408 | } | |
409 | ||
652ec1ba | 410 | void CYFunction::Output(CYOutput &out) const { |
b09da87b JF |
411 | CYLambda::Output(out, CYNoFlags); |
412 | } | |
413 | ||
652ec1ba | 414 | void CYFunctionParameter::Output(CYOutput &out) const { |
b09da87b JF |
415 | out << *name_; |
416 | if (next_ != NULL) { | |
417 | out << ','; | |
418 | out << *next_; | |
419 | } | |
5999c315 JF |
420 | } |
421 | ||
652ec1ba | 422 | void CYIf::Output(CYOutput &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 | ||
652ec1ba | 433 | void CYIfComprehension::Begin_(CYOutput &out) const { |
75b0a457 JF |
434 | out << "if("; |
435 | test_->Output(out, CYNoFlags); | |
436 | out << ')'; | |
437 | } | |
438 | ||
652ec1ba | 439 | void CYIndirect::Output(CYOutput &out, CYFlags flags) const { |
b09da87b | 440 | rhs_->Output(out, 1, CYLeft(flags)); |
9b5527f0 JF |
441 | out << ".$cyi"; |
442 | } | |
443 | ||
652ec1ba | 444 | void CYIndirectMember::Output(CYOutput &out, CYFlags flags) const { |
9b5527f0 JF |
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 | ||
652ec1ba | 456 | void CYInfix::Output(CYOutput &out, CYFlags flags) const { |
b09da87b JF |
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 | ||
652ec1ba | 477 | void CYLambda::Output(CYOutput &out, CYFlags flags) const { |
b09da87b JF |
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 | ||
652ec1ba | 497 | void CYLet::Output(CYOutput &out) const { |
cac61857 JF |
498 | out << "let("; |
499 | declarations_->Output(out, CYNoFlags); | |
500 | out << "){"; | |
501 | if (statements_ != NULL) | |
502 | statements_->Show(out); | |
503 | out << "}"; | |
504 | } | |
505 | ||
652ec1ba | 506 | void CYMessage::Output(CYOutput &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 | ||
652ec1ba | 529 | void CYNew::Output(CYOutput &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 | ||
652ec1ba | 540 | void CYNull::Output(CYOutput &out, CYFlags flags) const { |
b09da87b JF |
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 | ||
652ec1ba | 548 | void CYNumber::Output(CYOutput &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 |
652ec1ba | 553 | out.out_ << std::setprecision(9) << value; |
b09da87b JF |
554 | if ((flags & CYNoTrailer) != 0) |
555 | out << ' '; | |
5999c315 JF |
556 | } |
557 | ||
652ec1ba | 558 | void CYNumber::PropertyName(CYOutput &out) const { |
e5bc40db JF |
559 | Output(out); |
560 | } | |
561 | ||
652ec1ba | 562 | void CYObject::Output(CYOutput &out, CYFlags flags) const { |
b09da87b JF |
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 | ||
652ec1ba | 574 | void CYPostfix::Output(CYOutput &out, CYFlags flags) const { |
b09da87b | 575 | lhs_->Output(out, Precedence(), CYLeft(flags)); |
d35a3b07 | 576 | out << Operator(); |
5999c315 JF |
577 | } |
578 | ||
652ec1ba | 579 | void CYPrefix::Output(CYOutput &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 | ||
652ec1ba | 591 | void CYProperty::Output(CYOutput &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 | ||
63cd45c9 JF |
601 | void CYRegEx::Output(CYOutput &out, CYFlags flags) const { |
602 | out << Value(); | |
603 | if ((flags & CYNoTrailer) != 0) | |
604 | out << ' '; | |
605 | } | |
606 | ||
652ec1ba | 607 | void CYReturn::Output(CYOutput &out) const { |
5999c315 | 608 | out << "return"; |
b09da87b JF |
609 | if (value_ != NULL) |
610 | value_->Output(out, CYNoLeader); | |
5999c315 JF |
611 | out << ';'; |
612 | } | |
613 | ||
652ec1ba | 614 | void CYSelector::Output(CYOutput &out, CYFlags flags) const { |
bce8339b JF |
615 | if ((flags & CYNoLeader) != 0) |
616 | out << ' '; | |
b09da87b | 617 | out << "new Selector(\""; |
62014ea9 JF |
618 | if (name_ != NULL) |
619 | name_->Output(out); | |
dea834b0 | 620 | out << "\")"; |
e7ed5354 JF |
621 | } |
622 | ||
652ec1ba | 623 | void CYSelectorPart::Output(CYOutput &out) const { |
62014ea9 JF |
624 | if (name_ != NULL) |
625 | out << *name_; | |
626 | if (value_) | |
627 | out << ':'; | |
628 | if (next_ != NULL) | |
629 | next_->Output(out); | |
630 | } | |
631 | ||
652ec1ba | 632 | void CYSend::Output(CYOutput &out, CYFlags flags) const { |
c239b9f8 JF |
633 | if ((flags & CYNoLeader) != 0) |
634 | out << ' '; | |
b09da87b JF |
635 | out << "objc_msgSend("; |
636 | self_->Output(out, CYPA, CYNoFlags); | |
4afefdd9 JF |
637 | out << ","; |
638 | std::ostringstream name; | |
b09da87b JF |
639 | for (CYArgument *argument(arguments_); argument != NULL; argument = argument->next_) |
640 | if (argument->name_ != NULL) { | |
4afefdd9 | 641 | name << *argument->name_; |
b09da87b | 642 | if (argument->value_ != NULL) |
4afefdd9 | 643 | name << ':'; |
b09da87b | 644 | } |
652ec1ba | 645 | out.out_ << reinterpret_cast<void *>(sel_registerName(name.str().c_str())); |
b09da87b JF |
646 | for (CYArgument *argument(arguments_); argument != NULL; argument = argument->next_) |
647 | if (argument->value_ != NULL) { | |
648 | out << ","; | |
649 | argument->value_->Output(out, CYPA, CYNoFlags); | |
650 | } | |
651 | out << ')'; | |
652 | } | |
653 | ||
652ec1ba | 654 | void CYSource::Show(CYOutput &out) const { |
5999c315 | 655 | for (const CYSource *next(this); next != NULL; next = next->next_) |
9e562cfc | 656 | next->Output_(out); |
5999c315 JF |
657 | } |
658 | ||
652ec1ba | 659 | void CYSource::Output(CYOutput &out, bool block) const { |
9e562cfc | 660 | if (!block && !IsBlock()) |
5999c315 JF |
661 | Output(out); |
662 | else { | |
663 | out << '{'; | |
b1ff2d78 | 664 | Show(out); |
5999c315 JF |
665 | out << '}'; |
666 | } | |
667 | } | |
668 | ||
652ec1ba | 669 | void CYSource::Output_(CYOutput &out) const { |
9e562cfc JF |
670 | Output(out); |
671 | } | |
672 | ||
652ec1ba | 673 | void CYStatement::Output_(CYOutput &out) const { |
9e562cfc JF |
674 | for (CYLabel *label(labels_); label != NULL; label = label->next_) |
675 | out << *label->name_ << ':'; | |
676 | Output(out); | |
677 | } | |
678 | ||
652ec1ba | 679 | void CYString::Output(CYOutput &out, CYFlags flags) const { |
b4aa79af JF |
680 | unsigned quot(0), apos(0); |
681 | for (const char *value(value_), *end(value_ + size_); value != end; ++value) | |
682 | if (*value == '"') | |
683 | ++quot; | |
684 | else if (*value == '\'') | |
685 | ++apos; | |
686 | ||
687 | bool single(quot > apos); | |
688 | ||
689 | out << (single ? '\'' : '"'); | |
5999c315 JF |
690 | for (const char *value(value_), *end(value_ + size_); value != end; ++value) |
691 | switch (*value) { | |
5999c315 JF |
692 | case '\\': out << "\\\\"; break; |
693 | case '\b': out << "\\b"; break; | |
694 | case '\f': out << "\\f"; break; | |
695 | case '\n': out << "\\n"; break; | |
696 | case '\r': out << "\\r"; break; | |
697 | case '\t': out << "\\t"; break; | |
698 | case '\v': out << "\\v"; break; | |
699 | ||
b4aa79af JF |
700 | case '"': |
701 | if (!single) | |
702 | out << "\\\""; | |
703 | else goto simple; | |
704 | break; | |
705 | ||
706 | case '\'': | |
707 | if (single) | |
708 | out << "\\'"; | |
709 | else goto simple; | |
710 | break; | |
711 | ||
5999c315 JF |
712 | default: |
713 | if (*value < 0x20 || *value >= 0x7f) | |
652ec1ba | 714 | out.out_ << "\\x" << std::setbase(16) << std::setw(2) << std::setfill('0') << unsigned(*value); |
b4aa79af | 715 | else simple: |
5999c315 JF |
716 | out << *value; |
717 | } | |
b4aa79af | 718 | out << (single ? '\'' : '"'); |
5999c315 JF |
719 | } |
720 | ||
652ec1ba | 721 | void CYString::PropertyName(CYOutput &out) const { |
e5bc40db JF |
722 | if (const char *word = Word()) |
723 | out << word; | |
724 | else | |
725 | Output(out); | |
726 | } | |
727 | ||
652ec1ba | 728 | void CYSwitch::Output(CYOutput &out) const { |
d35a3b07 | 729 | out << "switch("; |
b09da87b | 730 | value_->Output(out, CYNoFlags); |
d35a3b07 | 731 | out << "){"; |
5999c315 JF |
732 | if (clauses_ != NULL) |
733 | out << *clauses_; | |
734 | out << '}'; | |
735 | } | |
736 | ||
652ec1ba | 737 | void CYThis::Output(CYOutput &out, CYFlags flags) const { |
b09da87b JF |
738 | if ((flags & CYNoLeader) != 0) |
739 | out << ' '; | |
5999c315 | 740 | CYWord::Output(out); |
b09da87b JF |
741 | if ((flags & CYNoTrailer) != 0) |
742 | out << ' '; | |
5999c315 JF |
743 | } |
744 | ||
652ec1ba | 745 | void CYThrow::Output(CYOutput &out) const { |
d35a3b07 | 746 | out << "throw"; |
b09da87b JF |
747 | if (value_ != NULL) |
748 | value_->Output(out, CYNoLeader); | |
5999c315 JF |
749 | out << ';'; |
750 | } | |
751 | ||
652ec1ba | 752 | void CYTry::Output(CYOutput &out) const { |
5999c315 JF |
753 | out << "try"; |
754 | try_->Output(out, true); | |
755 | if (catch_ != NULL) | |
9b5527f0 | 756 | catch_->Output(out); |
5999c315 JF |
757 | if (finally_ != NULL) { |
758 | out << "finally"; | |
759 | finally_->Output(out, true); | |
760 | } | |
761 | } | |
762 | ||
652ec1ba | 763 | void CYVar::Output(CYOutput &out) const { |
cac61857 JF |
764 | out << "var "; |
765 | declarations_->Output(out, CYNoFlags); | |
766 | out << ';'; | |
767 | } | |
768 | ||
652ec1ba | 769 | void CYVariable::Output(CYOutput &out, CYFlags flags) const { |
478d4ed0 JF |
770 | if ((flags & CYNoLeader) != 0) |
771 | out << ' '; | |
5999c315 | 772 | out << *name_; |
478d4ed0 JF |
773 | if ((flags & CYNoTrailer) != 0) |
774 | out << ' '; | |
5999c315 JF |
775 | } |
776 | ||
652ec1ba | 777 | void CYWhile::Output(CYOutput &out) const { |
d35a3b07 | 778 | out << "while("; |
b09da87b | 779 | test_->Output(out, CYNoFlags); |
d35a3b07 | 780 | out << ')'; |
5999c315 JF |
781 | code_->Output(out, false); |
782 | } | |
783 | ||
652ec1ba | 784 | void CYWith::Output(CYOutput &out) const { |
d35a3b07 | 785 | out << "with("; |
b09da87b | 786 | scope_->Output(out, CYNoFlags); |
d35a3b07 | 787 | out << ')'; |
5999c315 JF |
788 | code_->Output(out, false); |
789 | } | |
790 | ||
652ec1ba | 791 | void CYWord::ClassName(CYOutput &out, bool object) const { |
367eebb1 JF |
792 | if (object) |
793 | out << "objc_getClass("; | |
794 | out << '"' << Value() << '"'; | |
795 | if (object) | |
796 | out << ')'; | |
e5bc40db JF |
797 | } |
798 | ||
652ec1ba | 799 | void CYWord::Output(CYOutput &out) const { |
5999c315 JF |
800 | out << Value(); |
801 | } | |
e5bc40db | 802 | |
652ec1ba | 803 | void CYWord::PropertyName(CYOutput &out) const { |
e5bc40db JF |
804 | Output(out); |
805 | } |