]>
Commit | Line | Data |
---|---|---|
5999c315 JF |
1 | #include "Parser.hpp" |
2 | ||
5999c315 | 3 | #include <iomanip> |
4afefdd9 JF |
4 | #include <sstream> |
5 | ||
b09da87b JF |
6 | _finline CYFlags operator ~(CYFlags rhs) { |
7 | return static_cast<CYFlags>(~static_cast<unsigned>(rhs)); | |
8 | } | |
9 | ||
10 | _finline CYFlags operator &(CYFlags lhs, CYFlags rhs) { | |
11 | return static_cast<CYFlags>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs)); | |
12 | } | |
13 | ||
14 | _finline CYFlags operator |(CYFlags lhs, CYFlags rhs) { | |
15 | return static_cast<CYFlags>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs)); | |
16 | } | |
17 | ||
18 | _finline CYFlags &operator |=(CYFlags &lhs, CYFlags rhs) { | |
19 | return lhs = lhs | rhs; | |
20 | } | |
21 | ||
22 | _finline CYFlags CYLeft(CYFlags flags) { | |
d29365ce | 23 | return flags & ~CYNoDangle; |
b09da87b JF |
24 | } |
25 | ||
96a7e5c2 JF |
26 | _finline CYFlags CYRight(CYFlags flags) { |
27 | return flags & ~CYNoBF; | |
b09da87b JF |
28 | } |
29 | ||
96a7e5c2 | 30 | _finline CYFlags CYCenter(CYFlags flags) { |
d29365ce | 31 | return CYLeft(CYRight(flags)); |
b09da87b JF |
32 | } |
33 | ||
1fdca2fa JF |
34 | void CYOutput::Terminate() { |
35 | out_ << ';'; | |
36 | mode_ = NoMode; | |
37 | } | |
38 | ||
96a7e5c2 | 39 | CYOutput &CYOutput::operator <<(char rhs) { |
1fdca2fa JF |
40 | if (rhs == ' ' || rhs == '\n') |
41 | if (pretty_) | |
42 | out_ << rhs; | |
43 | else goto done; | |
44 | else if (rhs == '\t') | |
45 | if (pretty_) | |
46 | for (unsigned i(0); i != indent_; ++i) | |
47 | out_ << " "; | |
48 | else goto done; | |
49 | else goto work; | |
50 | ||
51 | mode_ = NoMode; | |
52 | goto done; | |
96a7e5c2 | 53 | |
1fdca2fa | 54 | work: |
96a7e5c2 JF |
55 | if (mode_ == Terminated && rhs != '}') |
56 | out_ << ';'; | |
57 | ||
58 | if (rhs == ';') { | |
59 | if (pretty_) | |
60 | goto none; | |
61 | else { | |
62 | mode_ = Terminated; | |
63 | goto done; | |
64 | } | |
c0bc320e JF |
65 | } else if (rhs == '+') { |
66 | if (mode_ == NoPlus) | |
67 | out_ << ' '; | |
68 | mode_ = NoPlus; | |
96a7e5c2 JF |
69 | } else if (rhs == '-') { |
70 | if (mode_ == NoHyphen) | |
71 | out_ << ' '; | |
72 | mode_ = NoHyphen; | |
73 | } else if (WordEndRange_[rhs]) { | |
74 | if (mode_ == NoLetter) | |
75 | out_ << ' '; | |
76 | mode_ = NoLetter; | |
77 | } else none: | |
78 | mode_ = NoMode; | |
79 | ||
80 | out_ << rhs; | |
81 | done: | |
82 | return *this; | |
83 | } | |
84 | ||
85 | CYOutput &CYOutput::operator <<(const char *rhs) { | |
86 | size_t size(strlen(rhs)); | |
87 | ||
88 | if (size == 1) | |
89 | return *this << *rhs; | |
90 | ||
91 | if (mode_ == Terminated) | |
92 | out_ << ';'; | |
93 | else if ( | |
c0bc320e | 94 | mode_ == NoPlus && *rhs == '+' || |
96a7e5c2 JF |
95 | mode_ == NoHyphen && *rhs == '-' || |
96 | mode_ == NoLetter && WordEndRange_[*rhs] | |
97 | ) | |
98 | out_ << ' '; | |
99 | ||
100 | if (WordEndRange_[rhs[size - 1]]) | |
101 | mode_ = NoLetter; | |
102 | else | |
103 | mode_ = NoMode; | |
104 | ||
105 | out_ << rhs; | |
106 | return *this; | |
107 | } | |
108 | ||
652ec1ba | 109 | void CYArgument::Output(CYOutput &out) const { |
d35a3b07 | 110 | if (name_ != NULL) { |
5999c315 | 111 | out << *name_; |
96a7e5c2 JF |
112 | if (value_ != NULL) |
113 | out << ':' << ' '; | |
5999c315 | 114 | } |
d35a3b07 | 115 | if (value_ != NULL) |
b09da87b | 116 | value_->Output(out, CYPA, CYNoFlags); |
5999c315 | 117 | if (next_ != NULL) { |
96a7e5c2 | 118 | if (next_->name_ == NULL) |
11c1cc16 | 119 | out << ','; |
96a7e5c2 | 120 | out << ' ' << *next_; |
5999c315 JF |
121 | } |
122 | } | |
123 | ||
652ec1ba | 124 | void CYArray::Output(CYOutput &out, CYFlags flags) const { |
96a7e5c2 | 125 | out << '[' << elements_ << ']'; |
5befe15e JF |
126 | } |
127 | ||
652ec1ba | 128 | void CYArrayComprehension::Output(CYOutput &out, CYFlags flags) const { |
75b0a457 JF |
129 | // XXX: I don't necc. need the ()s |
130 | out << "(function($cyv"; | |
131 | for (CYComprehension *comprehension(comprehensions_); comprehension != NULL; comprehension = comprehension->next_) | |
132 | if (const char *name = comprehension->Name()) | |
133 | out << ',' << name; | |
134 | out << "){"; | |
dc81e1c2 | 135 | out << "$cyv=[];"; |
75b0a457 | 136 | comprehensions_->Output(out); |
dc81e1c2 | 137 | out << "$cyv.push("; |
75b0a457 JF |
138 | expression_->Output(out, CYPA, CYNoFlags); |
139 | out << ");"; | |
140 | for (CYComprehension *comprehension(comprehensions_); comprehension != NULL; comprehension = comprehension->next_) | |
141 | comprehension->End_(out); | |
dc81e1c2 | 142 | out << "return $cyv;"; |
75b0a457 JF |
143 | out << "}())"; |
144 | } | |
145 | ||
652ec1ba | 146 | void CYAssignment::Output(CYOutput &out, CYFlags flags) const { |
fb98ac0c | 147 | lhs_->Output(out, Precedence() - 1, CYLeft(flags) | CYNoRightHand); |
96a7e5c2 | 148 | out << ' ' << Operator() << ' '; |
b09da87b | 149 | rhs_->Output(out, Precedence(), CYRight(flags)); |
d35a3b07 JF |
150 | } |
151 | ||
3b52fd1a JF |
152 | void CYBlock::Output(CYOutput &out) const { |
153 | out << '{' << '\n'; | |
154 | ++out.indent_; | |
155 | if (statements_ != NULL) | |
156 | statements_->Multiple(out); | |
157 | --out.indent_; | |
158 | out << '\t' << '}'; | |
159 | } | |
160 | ||
fb98ac0c | 161 | void CYBlock::Output(CYOutput &out, CYFlags flags) const { |
3b52fd1a JF |
162 | if (statements_ == NULL) |
163 | out.Terminate(); | |
164 | else if (statements_->next_ == NULL) | |
165 | statements_->Single(out, flags); | |
166 | else | |
167 | Output(out); | |
9e562cfc JF |
168 | } |
169 | ||
652ec1ba | 170 | void CYBoolean::Output(CYOutput &out, CYFlags flags) const { |
5999c315 JF |
171 | out << (Value() ? "true" : "false"); |
172 | } | |
173 | ||
fb98ac0c | 174 | void CYBreak::Output(CYOutput &out, CYFlags flags) const { |
5999c315 JF |
175 | out << "break"; |
176 | if (label_ != NULL) | |
177 | out << ' ' << *label_; | |
96a7e5c2 | 178 | out << ';'; |
5999c315 JF |
179 | } |
180 | ||
652ec1ba | 181 | void CYCall::Output(CYOutput &out, CYFlags flags) const { |
fb98ac0c JF |
182 | bool protect((flags & CYNoCall) != 0); |
183 | if (protect) | |
184 | out << '('; | |
185 | function_->Output(out, Precedence(), protect ? CYNoFlags : flags); | |
96a7e5c2 | 186 | out << '(' << arguments_ << ')'; |
fb98ac0c JF |
187 | if (protect) |
188 | out << ')'; | |
5999c315 JF |
189 | } |
190 | ||
652ec1ba | 191 | void CYCatch::Output(CYOutput &out) const { |
3b52fd1a | 192 | out << ' ' << "catch" << ' ' << '(' << *name_ << ')' << ' ' << code_; |
5999c315 JF |
193 | } |
194 | ||
652ec1ba | 195 | void CYCompound::Output(CYOutput &out, CYFlags flags) const { |
e5bc40db JF |
196 | if (CYExpression *expression = expressions_) |
197 | if (CYExpression *next = expression->next_) { | |
198 | expression->Output(out, CYLeft(flags)); | |
199 | CYFlags center(CYCenter(flags)); | |
200 | while (next != NULL) { | |
201 | expression = next; | |
96a7e5c2 | 202 | out << ',' << ' '; |
e5bc40db JF |
203 | next = expression->next_; |
204 | CYFlags right(next != NULL ? center : CYRight(flags)); | |
205 | expression->Output(out, right); | |
206 | } | |
207 | } else | |
208 | expression->Output(out, flags); | |
209 | } | |
210 | ||
652ec1ba | 211 | void CYComprehension::Output(CYOutput &out) const { |
75b0a457 | 212 | Begin_(out); |
96a7e5c2 | 213 | out << next_; |
75b0a457 JF |
214 | } |
215 | ||
652ec1ba | 216 | void CYCondition::Output(CYOutput &out, CYFlags flags) const { |
b09da87b | 217 | test_->Output(out, Precedence() - 1, CYLeft(flags)); |
96a7e5c2 | 218 | out << ' ' << '?' << ' '; |
5999c315 | 219 | if (true_ != NULL) |
b09da87b | 220 | true_->Output(out, CYPA, CYNoFlags); |
96a7e5c2 | 221 | out << ' ' << ':' << ' '; |
b09da87b | 222 | false_->Output(out, CYPA, CYRight(flags)); |
5999c315 JF |
223 | } |
224 | ||
fb98ac0c | 225 | void CYContinue::Output(CYOutput &out, CYFlags flags) const { |
5999c315 JF |
226 | out << "continue"; |
227 | if (label_ != NULL) | |
228 | out << ' ' << *label_; | |
96a7e5c2 | 229 | out << ';'; |
5999c315 JF |
230 | } |
231 | ||
652ec1ba | 232 | void CYClause::Output(CYOutput &out) const { |
96a7e5c2 JF |
233 | if (case_ != NULL) |
234 | out << "case" << ' ' << *case_; | |
235 | else | |
5999c315 | 236 | out << "default"; |
1fdca2fa | 237 | out << ':' << '\n'; |
3b52fd1a JF |
238 | if (statements_ != NULL) |
239 | statements_->Multiple(out); | |
96a7e5c2 | 240 | out << next_; |
cac61857 JF |
241 | } |
242 | ||
243 | const char *CYDeclaration::ForEachIn() const { | |
244 | return identifier_->Value(); | |
5999c315 JF |
245 | } |
246 | ||
652ec1ba | 247 | void CYDeclaration::ForIn(CYOutput &out, CYFlags flags) const { |
fb98ac0c | 248 | out << "var"; |
96a7e5c2 | 249 | Output(out, CYRight(flags)); |
75b0a457 JF |
250 | } |
251 | ||
652ec1ba | 252 | void CYDeclaration::ForEachIn(CYOutput &out) const { |
75b0a457 | 253 | out << *identifier_; |
5999c315 JF |
254 | } |
255 | ||
652ec1ba | 256 | void CYDeclaration::Output(CYOutput &out, CYFlags flags) const { |
5999c315 | 257 | out << *identifier_; |
d35a3b07 | 258 | if (initialiser_ != NULL) { |
96a7e5c2 | 259 | out << ' ' << '=' << ' '; |
75b0a457 | 260 | initialiser_->Output(out, CYPA, CYRight(flags)); |
96a7e5c2 | 261 | } |
5999c315 JF |
262 | } |
263 | ||
652ec1ba | 264 | void CYDeclarations::For(CYOutput &out) const { |
fb98ac0c | 265 | out << "var"; |
96a7e5c2 JF |
266 | Output(out, CYNoIn); |
267 | } | |
268 | ||
269 | void CYDeclarations::Output(CYOutput &out) const { | |
270 | Output(out, CYNoFlags); | |
cac61857 | 271 | } |
d35a3b07 | 272 | |
652ec1ba | 273 | void CYDeclarations::Output(CYOutput &out, CYFlags flags) const { |
5999c315 | 274 | const CYDeclarations *declaration(this); |
fb98ac0c | 275 | bool first(true); |
d35a3b07 | 276 | output: |
75b0a457 | 277 | CYDeclarations *next(declaration->next_); |
fb98ac0c JF |
278 | CYFlags jacks(first ? CYLeft(flags) : next == NULL ? CYRight(flags) : CYCenter(flags)); |
279 | first = false; | |
280 | declaration->declaration_->Output(out, jacks); | |
d35a3b07 | 281 | |
75b0a457 | 282 | if (next != NULL) { |
96a7e5c2 | 283 | out << ',' << ' '; |
75b0a457 | 284 | declaration = next; |
d35a3b07 JF |
285 | goto output; |
286 | } | |
5999c315 JF |
287 | } |
288 | ||
652ec1ba | 289 | void CYDirectMember::Output(CYOutput &out, CYFlags flags) const { |
9b5527f0 JF |
290 | object_->Output(out, Precedence(), CYLeft(flags)); |
291 | if (const char *word = property_->Word()) | |
292 | out << '.' << word; | |
96a7e5c2 JF |
293 | else |
294 | out << '[' << *property_ << ']'; | |
9b5527f0 JF |
295 | } |
296 | ||
fb98ac0c | 297 | void CYDoWhile::Output(CYOutput &out, CYFlags flags) const { |
fb98ac0c | 298 | out << "do"; |
d29365ce | 299 | code_->Single(out, CYCenter(flags)); |
96a7e5c2 | 300 | out << "while" << ' ' << '(' << *test_ << ')'; |
5999c315 JF |
301 | } |
302 | ||
652ec1ba | 303 | void CYElement::Output(CYOutput &out) const { |
5999c315 | 304 | if (value_ != NULL) |
b09da87b | 305 | value_->Output(out, CYPA, CYNoFlags); |
11c1cc16 | 306 | if (next_ != NULL || value_ == NULL) { |
5999c315 | 307 | out << ','; |
96a7e5c2 | 308 | if (next_ != NULL && next_->value_ != NULL) |
11c1cc16 JF |
309 | out << ' '; |
310 | } | |
5befe15e JF |
311 | if (next_ != NULL) |
312 | next_->Output(out); | |
5999c315 JF |
313 | } |
314 | ||
fb98ac0c | 315 | void CYEmpty::Output(CYOutput &out, CYFlags flags) const { |
1fdca2fa | 316 | out.Terminate(); |
5999c315 JF |
317 | } |
318 | ||
fb98ac0c | 319 | void CYExpress::Output(CYOutput &out, CYFlags flags) const { |
96a7e5c2 JF |
320 | expression_->Output(out, flags | CYNoBF); |
321 | out << ';'; | |
5999c315 JF |
322 | } |
323 | ||
652ec1ba | 324 | void CYExpression::ClassName(CYOutput &out, bool object) const { |
e5bc40db JF |
325 | Output(out, CYPA, CYNoFlags); |
326 | } | |
327 | ||
cac61857 JF |
328 | const char *CYExpression::ForEachIn() const { |
329 | return NULL; | |
330 | } | |
331 | ||
652ec1ba | 332 | void CYExpression::For(CYOutput &out) const { |
cac61857 JF |
333 | Output(out, CYNoIn); |
334 | } | |
335 | ||
652ec1ba | 336 | void CYExpression::ForEachIn(CYOutput &out) const { |
fb98ac0c | 337 | Output(out, CYPA, CYNoRightHand); |
75b0a457 JF |
338 | } |
339 | ||
652ec1ba | 340 | void CYExpression::ForIn(CYOutput &out, CYFlags flags) const { |
fb98ac0c | 341 | Output(out, flags | CYNoRightHand); |
d35a3b07 JF |
342 | } |
343 | ||
96a7e5c2 JF |
344 | void CYExpression::Output(CYOutput &out) const { |
345 | Output(out, CYNoFlags); | |
346 | } | |
347 | ||
652ec1ba | 348 | void CYExpression::Output(CYOutput &out, unsigned precedence, CYFlags flags) const { |
96a7e5c2 JF |
349 | if (precedence < Precedence() || (flags & CYNoRightHand) != 0 && RightHand()) |
350 | out << '(' << *this << ')'; | |
351 | else | |
b09da87b JF |
352 | Output(out, flags); |
353 | } | |
354 | ||
b10bd496 | 355 | void CYFinally::Output(CYOutput &out) const { |
3b52fd1a | 356 | out << ' ' << "finally" << ' ' << code_; |
b10bd496 JF |
357 | } |
358 | ||
fb98ac0c | 359 | void CYFor::Output(CYOutput &out, CYFlags flags) const { |
96a7e5c2 | 360 | out << "for" << ' ' << '('; |
5999c315 | 361 | if (initialiser_ != NULL) |
cac61857 | 362 | initialiser_->For(out); |
1fdca2fa | 363 | out.Terminate(); |
96a7e5c2 | 364 | out << test_; |
1fdca2fa | 365 | out.Terminate(); |
96a7e5c2 | 366 | out << increment_; |
5999c315 | 367 | out << ')'; |
d29365ce | 368 | code_->Single(out, CYRight(flags)); |
5999c315 JF |
369 | } |
370 | ||
fb98ac0c | 371 | void CYForEachIn::Output(CYOutput &out, CYFlags flags) const { |
6f926cee | 372 | out << "with({$cys:0,$cyt:0}){"; |
75b0a457 | 373 | |
75b0a457 JF |
374 | out << "$cys="; |
375 | set_->Output(out, CYPA, CYNoFlags); | |
11c1cc16 | 376 | out << ';'; |
75b0a457 JF |
377 | |
378 | out << "for($cyt in $cys){"; | |
379 | ||
380 | initialiser_->ForEachIn(out); | |
381 | out << "=$cys[$cyt];"; | |
382 | ||
fb98ac0c | 383 | code_->Multiple(out); |
75b0a457 | 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); | |
11c1cc16 | 394 | out << ';'; |
75b0a457 JF |
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 | ||
fb98ac0c | 404 | void CYForIn::Output(CYOutput &out, CYFlags flags) const { |
96a7e5c2 JF |
405 | out << "for" << ' ' << '('; |
406 | initialiser_->ForIn(out, CYNoIn); | |
407 | out << "in" << *set_ << ')'; | |
fb98ac0c | 408 | code_->Single(out, CYRight(flags)); |
5999c315 JF |
409 | } |
410 | ||
652ec1ba | 411 | void CYForInComprehension::Begin_(CYOutput &out) const { |
96a7e5c2 | 412 | out << "for" << ' ' << '(' << *name_ << "in" << *set_ << ')'; |
75b0a457 JF |
413 | } |
414 | ||
fb98ac0c | 415 | void CYFunction::Output(CYOutput &out, CYFlags flags) const { |
1fdca2fa | 416 | // XXX: one could imagine using + here to save a byte |
fb98ac0c JF |
417 | bool protect((flags & CYNoFunction) != 0); |
418 | if (protect) | |
419 | out << '('; | |
fb98ac0c JF |
420 | out << "function"; |
421 | if (name_ != NULL) | |
422 | out << ' ' << *name_; | |
1fdca2fa | 423 | out << '(' << parameters_ << ')'; |
3b52fd1a | 424 | out << ' ' << code_; |
fb98ac0c JF |
425 | if (protect) |
426 | out << ')'; | |
427 | } | |
428 | ||
429 | void CYFunctionExpression::Output(CYOutput &out, CYFlags flags) const { | |
430 | CYFunction::Output(out, flags); | |
431 | } | |
432 | ||
433 | void CYFunctionStatement::Output(CYOutput &out, CYFlags flags) const { | |
434 | CYFunction::Output(out, flags); | |
b09da87b JF |
435 | } |
436 | ||
652ec1ba | 437 | void CYFunctionParameter::Output(CYOutput &out) const { |
b09da87b | 438 | out << *name_; |
96a7e5c2 JF |
439 | if (next_ != NULL) |
440 | out << ',' << ' ' << *next_; | |
5999c315 JF |
441 | } |
442 | ||
fb98ac0c JF |
443 | void CYIf::Output(CYOutput &out, CYFlags flags) const { |
444 | bool protect(false); | |
445 | if (false_ == NULL && (flags & CYNoDangle) != 0) { | |
446 | protect = true; | |
447 | out << '{'; | |
96a7e5c2 | 448 | } |
1fdca2fa JF |
449 | |
450 | out << "if" << ' ' << '(' << *test_ << ')'; | |
451 | ||
fb98ac0c | 452 | CYFlags right(protect ? CYNoFlags : CYRight(flags)); |
d29365ce | 453 | |
fb98ac0c | 454 | CYFlags jacks(CYNoDangle); |
96a7e5c2 JF |
455 | if (false_ == NULL) |
456 | jacks |= right; | |
d29365ce JF |
457 | else |
458 | jacks |= protect ? CYNoFlags : CYCenter(flags); | |
1fdca2fa | 459 | |
3b52fd1a | 460 | true_->Single(out, jacks); |
1fdca2fa | 461 | |
5999c315 | 462 | if (false_ != NULL) { |
fb98ac0c | 463 | out << "else"; |
96a7e5c2 | 464 | false_->Single(out, right); |
5999c315 | 465 | } |
1fdca2fa | 466 | |
fb98ac0c JF |
467 | if (protect) |
468 | out << '}'; | |
5999c315 JF |
469 | } |
470 | ||
652ec1ba | 471 | void CYIfComprehension::Begin_(CYOutput &out) const { |
96a7e5c2 | 472 | out << "if" << '(' << *test_ << ')'; |
75b0a457 JF |
473 | } |
474 | ||
652ec1ba | 475 | void CYIndirectMember::Output(CYOutput &out, CYFlags flags) const { |
9b5527f0 | 476 | object_->Output(out, Precedence(), CYLeft(flags)); |
9b5527f0 | 477 | if (const char *word = property_->Word()) |
3b52fd1a | 478 | out << "->" << word; |
96a7e5c2 | 479 | else |
3b52fd1a | 480 | out << "->" << '[' << *property_ << ']'; |
5999c315 JF |
481 | } |
482 | ||
652ec1ba | 483 | void CYInfix::Output(CYOutput &out, CYFlags flags) const { |
b09da87b | 484 | const char *name(Operator()); |
d09e527c | 485 | bool protect((flags & CYNoIn) != 0 && strcmp(name, "in") == 0); |
b09da87b JF |
486 | if (protect) |
487 | out << '('; | |
b09da87b | 488 | CYFlags left(protect ? CYNoFlags : CYLeft(flags)); |
b09da87b | 489 | lhs_->Output(out, Precedence(), left); |
96a7e5c2 | 490 | out << ' ' << name << ' '; |
b09da87b | 491 | CYFlags right(protect ? CYNoFlags : CYRight(flags)); |
b09da87b JF |
492 | rhs_->Output(out, Precedence() - 1, right); |
493 | if (protect) | |
494 | out << ')'; | |
5999c315 JF |
495 | } |
496 | ||
3b52fd1a JF |
497 | void CYLabel::Output(CYOutput &out, CYFlags flags) const { |
498 | out << *name_ << ':' << ' '; | |
499 | statement_->Single(out, CYRight(flags)); | |
500 | } | |
501 | ||
fb98ac0c | 502 | void CYLet::Output(CYOutput &out, CYFlags flags) const { |
3b52fd1a | 503 | out << "let" << ' ' << '(' << *declarations_ << ')' << ' ' << code_; |
cac61857 JF |
504 | } |
505 | ||
652ec1ba | 506 | void CYNew::Output(CYOutput &out, CYFlags flags) const { |
96a7e5c2 | 507 | out << "new" << ' '; |
11c1cc16 | 508 | CYFlags jacks(CYNoCall | CYCenter(flags)); |
11c1cc16 | 509 | constructor_->Output(out, Precedence(), jacks); |
96a7e5c2 JF |
510 | if (arguments_ != NULL) |
511 | out << '(' << *arguments_ << ')'; | |
5999c315 JF |
512 | } |
513 | ||
652ec1ba | 514 | void CYNull::Output(CYOutput &out, CYFlags flags) const { |
5999c315 JF |
515 | CYWord::Output(out); |
516 | } | |
517 | ||
652ec1ba | 518 | void CYNumber::Output(CYOutput &out, CYFlags flags) const { |
96a7e5c2 JF |
519 | char value[32]; |
520 | sprintf(value, "%.17g", Value()); | |
521 | out << value; | |
5999c315 JF |
522 | } |
523 | ||
652ec1ba | 524 | void CYNumber::PropertyName(CYOutput &out) const { |
fb98ac0c | 525 | Output(out, CYNoFlags); |
e5bc40db JF |
526 | } |
527 | ||
652ec1ba | 528 | void CYObject::Output(CYOutput &out, CYFlags flags) const { |
b09da87b JF |
529 | bool protect((flags & CYNoBrace) != 0); |
530 | if (protect) | |
531 | out << '('; | |
c0bc320e JF |
532 | out << '{' << '\n'; |
533 | ++out.indent_; | |
3b52fd1a | 534 | out << properties_; |
c0bc320e JF |
535 | --out.indent_; |
536 | out << '\t' << '}'; | |
b09da87b JF |
537 | if (protect) |
538 | out << ')'; | |
693d501b JF |
539 | } |
540 | ||
652ec1ba | 541 | void CYPostfix::Output(CYOutput &out, CYFlags flags) const { |
b09da87b | 542 | lhs_->Output(out, Precedence(), CYLeft(flags)); |
d35a3b07 | 543 | out << Operator(); |
5999c315 JF |
544 | } |
545 | ||
652ec1ba | 546 | void CYPrefix::Output(CYOutput &out, CYFlags flags) const { |
1ef7d061 | 547 | const char *name(Operator()); |
1ef7d061 | 548 | out << name; |
96a7e5c2 | 549 | if (Alphabetic()) |
11c1cc16 | 550 | out << ' '; |
96a7e5c2 | 551 | rhs_->Output(out, Precedence(), CYRight(flags)); |
5999c315 JF |
552 | } |
553 | ||
3b52fd1a JF |
554 | void CYProgram::Output(CYOutput &out) const { |
555 | if (statements_ != NULL) | |
556 | statements_->Multiple(out); | |
557 | } | |
558 | ||
652ec1ba | 559 | void CYProperty::Output(CYOutput &out) const { |
c0bc320e | 560 | out << '\t'; |
e5bc40db | 561 | name_->PropertyName(out); |
96a7e5c2 | 562 | out << ':' << ' '; |
b09da87b | 563 | value_->Output(out, CYPA, CYNoFlags); |
96a7e5c2 | 564 | if (next_ != NULL) |
c0bc320e JF |
565 | out << ',' << '\n' << *next_; |
566 | else | |
567 | out << '\n'; | |
5999c315 JF |
568 | } |
569 | ||
63cd45c9 JF |
570 | void CYRegEx::Output(CYOutput &out, CYFlags flags) const { |
571 | out << Value(); | |
63cd45c9 JF |
572 | } |
573 | ||
fb98ac0c | 574 | void CYReturn::Output(CYOutput &out, CYFlags flags) const { |
c0bc320e JF |
575 | out << "return"; |
576 | if (value_ != NULL) | |
577 | out << ' ' << *value_; | |
578 | out << ';'; | |
5999c315 JF |
579 | } |
580 | ||
fb98ac0c JF |
581 | void CYStatement::Multiple(CYOutput &out, CYFlags flags) const { |
582 | bool first(true); | |
583 | for (const CYStatement *next(this); next != NULL; next = next->next_) { | |
584 | bool last(next->next_ == NULL); | |
585 | CYFlags jacks(first ? last ? flags : CYLeft(flags) : last ? CYCenter(flags) : CYRight(flags)); | |
fb98ac0c | 586 | first = false; |
1fdca2fa | 587 | out << '\t'; |
fb98ac0c | 588 | next->Output(out, jacks); |
1fdca2fa | 589 | out << '\n'; |
fb98ac0c | 590 | } |
5999c315 JF |
591 | } |
592 | ||
3b52fd1a JF |
593 | void CYStatement::Single(CYOutput &out, CYFlags flags) const { |
594 | _assert(next_ == NULL); | |
595 | out << '\n'; | |
596 | ++out.indent_; | |
597 | out << '\t'; | |
598 | Output(out, flags); | |
599 | out << '\n'; | |
600 | --out.indent_; | |
5999c315 JF |
601 | } |
602 | ||
652ec1ba | 603 | void CYString::Output(CYOutput &out, CYFlags flags) const { |
b4aa79af JF |
604 | unsigned quot(0), apos(0); |
605 | for (const char *value(value_), *end(value_ + size_); value != end; ++value) | |
606 | if (*value == '"') | |
607 | ++quot; | |
608 | else if (*value == '\'') | |
609 | ++apos; | |
610 | ||
611 | bool single(quot > apos); | |
612 | ||
96a7e5c2 JF |
613 | std::ostringstream str; |
614 | ||
615 | str << (single ? '\'' : '"'); | |
5999c315 JF |
616 | for (const char *value(value_), *end(value_ + size_); value != end; ++value) |
617 | switch (*value) { | |
96a7e5c2 JF |
618 | case '\\': str << "\\\\"; break; |
619 | case '\b': str << "\\b"; break; | |
620 | case '\f': str << "\\f"; break; | |
621 | case '\n': str << "\\n"; break; | |
622 | case '\r': str << "\\r"; break; | |
623 | case '\t': str << "\\t"; break; | |
624 | case '\v': str << "\\v"; break; | |
5999c315 | 625 | |
b4aa79af JF |
626 | case '"': |
627 | if (!single) | |
96a7e5c2 | 628 | str << "\\\""; |
b4aa79af JF |
629 | else goto simple; |
630 | break; | |
631 | ||
632 | case '\'': | |
633 | if (single) | |
96a7e5c2 | 634 | str << "\\'"; |
b4aa79af JF |
635 | else goto simple; |
636 | break; | |
637 | ||
5999c315 JF |
638 | default: |
639 | if (*value < 0x20 || *value >= 0x7f) | |
96a7e5c2 | 640 | str << "\\x" << std::setbase(16) << std::setw(2) << std::setfill('0') << unsigned(*value); |
b4aa79af | 641 | else simple: |
96a7e5c2 | 642 | str << *value; |
5999c315 | 643 | } |
96a7e5c2 JF |
644 | str << (single ? '\'' : '"'); |
645 | ||
646 | out << str.str().c_str(); | |
5999c315 JF |
647 | } |
648 | ||
652ec1ba | 649 | void CYString::PropertyName(CYOutput &out) const { |
e5bc40db JF |
650 | if (const char *word = Word()) |
651 | out << word; | |
652 | else | |
96a7e5c2 | 653 | out << *this; |
e5bc40db JF |
654 | } |
655 | ||
c0bc320e JF |
656 | static const char *Reserved_[] = { |
657 | "false", "null", "true", | |
658 | ||
659 | "break", "case", "catch", "continue", "default", | |
660 | "delete", "do", "else", "finally", "for", "function", | |
661 | "if", "in", "instanceof", "new", "return", "switch", | |
662 | "this", "throw", "try", "typeof", "var", "void", | |
663 | "while", "with", | |
664 | ||
665 | "debugger", "const", | |
666 | ||
667 | "class", "enum", "export", "extends", "import", "super", | |
668 | ||
669 | "abstract", "boolean", "byte", "char", "double", "final", | |
670 | "float", "goto", "int", "long", "native", "short", | |
671 | "synchronized", "throws", "transient", "volatile", | |
672 | ||
673 | "let", "yield", | |
674 | ||
675 | "each", | |
676 | ||
677 | NULL | |
678 | }; | |
679 | ||
11c1cc16 JF |
680 | const char *CYString::Word() const { |
681 | if (size_ == 0 || !WordStartRange_[value_[0]]) | |
682 | return NULL; | |
683 | for (size_t i(1); i != size_; ++i) | |
684 | if (!WordEndRange_[value_[i]]) | |
685 | return NULL; | |
686 | const char *value(Value()); | |
c0bc320e | 687 | for (const char **reserved(Reserved_); *reserved != NULL; ++reserved) |
11c1cc16 JF |
688 | if (strcmp(*reserved, value) == 0) |
689 | return NULL; | |
690 | return value; | |
691 | } | |
692 | ||
fb98ac0c | 693 | void CYSwitch::Output(CYOutput &out, CYFlags flags) const { |
96a7e5c2 JF |
694 | out << "switch" << ' ' << '(' << *value_ << ')' << ' ' << '{'; |
695 | out << clauses_; | |
5999c315 JF |
696 | out << '}'; |
697 | } | |
698 | ||
652ec1ba | 699 | void CYThis::Output(CYOutput &out, CYFlags flags) const { |
5999c315 JF |
700 | CYWord::Output(out); |
701 | } | |
702 | ||
fb98ac0c | 703 | void CYThrow::Output(CYOutput &out, CYFlags flags) const { |
c0bc320e JF |
704 | out << "throw"; |
705 | if (value_ != NULL) | |
706 | out << ' ' << *value_; | |
707 | out << ';'; | |
5999c315 JF |
708 | } |
709 | ||
fb98ac0c | 710 | void CYTry::Output(CYOutput &out, CYFlags flags) const { |
3b52fd1a | 711 | out << "try" << ' ' << code_ << catch_ << finally_; |
5999c315 JF |
712 | } |
713 | ||
fb98ac0c | 714 | void CYVar::Output(CYOutput &out, CYFlags flags) const { |
fb98ac0c | 715 | out << "var"; |
96a7e5c2 JF |
716 | declarations_->Output(out, flags); |
717 | out << ';'; | |
cac61857 JF |
718 | } |
719 | ||
652ec1ba | 720 | void CYVariable::Output(CYOutput &out, CYFlags flags) const { |
5999c315 JF |
721 | out << *name_; |
722 | } | |
723 | ||
fb98ac0c | 724 | void CYWhile::Output(CYOutput &out, CYFlags flags) const { |
96a7e5c2 | 725 | out << "while" << '(' << *test_ << ')'; |
fb98ac0c | 726 | code_->Single(out, CYRight(flags)); |
5999c315 JF |
727 | } |
728 | ||
fb98ac0c | 729 | void CYWith::Output(CYOutput &out, CYFlags flags) const { |
96a7e5c2 | 730 | out << "with" << '(' << *scope_ << ')'; |
fb98ac0c | 731 | code_->Single(out, CYRight(flags)); |
5999c315 JF |
732 | } |
733 | ||
652ec1ba | 734 | void CYWord::ClassName(CYOutput &out, bool object) const { |
367eebb1 JF |
735 | if (object) |
736 | out << "objc_getClass("; | |
737 | out << '"' << Value() << '"'; | |
738 | if (object) | |
739 | out << ')'; | |
e5bc40db JF |
740 | } |
741 | ||
652ec1ba | 742 | void CYWord::Output(CYOutput &out) const { |
5999c315 JF |
743 | out << Value(); |
744 | } | |
e5bc40db | 745 | |
652ec1ba | 746 | void CYWord::PropertyName(CYOutput &out) const { |
e5bc40db JF |
747 | Output(out); |
748 | } |