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