]> git.saurik.com Git - cycript.git/blame - Output.cpp
Instance's toPointer() should return as CFTypeRef.
[cycript.git] / Output.cpp
CommitLineData
7341eedb
JF
1/* Cycript - The Truly Universal Scripting Language
2 * Copyright (C) 2009-2016 Jay Freeman (saurik)
4644480a
JF
3*/
4
f95d2598 5/* GNU Affero General Public License, Version 3 {{{ */
4644480a 6/*
f95d2598
JF
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
c15969fd 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
f95d2598
JF
15 * GNU Affero General Public License for more details.
16
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
b3378a02 19**/
4644480a
JF
20/* }}} */
21
2e43a0b0
JF
22#include <cmath>
23#include <iomanip>
4afefdd9
JF
24#include <sstream>
25
20052ff7
JF
26#include "Syntax.hpp"
27
37dadc21
JF
28enum CYStringType {
29 CYStringTypeSingle,
30 CYStringTypeDouble,
31 CYStringTypeTemplate,
32};
33
34void CYStringify(std::ostringstream &str, const char *data, size_t size, CYStringifyMode mode) {
35 if (size == 0) {
36 str << "\"\"";
37 return;
38 }
39
40 unsigned quot(0), apos(0), tick(0), line(0);
41 for (const char *value(data), *end(data + size); value != end; ++value)
42 switch (*value) {
43 case '"': ++quot; break;
44 case '\'': ++apos; break;
45 case '`': ++tick; break;
46 case '$': ++tick; break;
47 case '\n': ++line; break;
48 }
49
50 bool split;
51 if (mode != CYStringifyModeCycript)
52 split = false;
2e43a0b0 53 else {
37dadc21
JF
54 double ratio(double(line) / size);
55 split = size > 10 && line > 2 && ratio > 0.005 && ratio < 0.10;
56 }
57
58 CYStringType type;
59 if (mode == CYStringifyModeNative)
60 type = CYStringTypeDouble;
61 else if (split)
62 type = CYStringTypeTemplate;
63 else if (quot > apos)
64 type = CYStringTypeSingle;
65 else
66 type = CYStringTypeDouble;
67
68 bool parens(split && mode != CYStringifyModeNative && type != CYStringTypeTemplate);
69 if (parens)
70 str << '(';
71
72 char border;
73 switch (type) {
74 case CYStringTypeSingle: border = '\''; break;
75 case CYStringTypeDouble: border = '"'; break;
76 case CYStringTypeTemplate: border = '`'; break;
2e43a0b0
JF
77 }
78
37dadc21
JF
79 str << border;
80
81 bool space(false);
2e43a0b0
JF
82
83 for (const char *value(data), *end(data + size); value != end; ++value)
37dadc21
JF
84 if (*value == ' ') {
85 space = true;
86 str << ' ';
87 } else { switch (uint8_t next = *value) {
2e43a0b0
JF
88 case '\\': str << "\\\\"; break;
89 case '\b': str << "\\b"; break;
90 case '\f': str << "\\f"; break;
2e43a0b0
JF
91 case '\r': str << "\\r"; break;
92 case '\t': str << "\\t"; break;
93 case '\v': str << "\\v"; break;
94
a0666306
JF
95 case '\a':
96 if (mode == CYStringifyModeNative)
97 str << "\\a";
98 else goto simple;
99 break;
100
37dadc21
JF
101 case '\n':
102 if (!split)
103 str << "\\n";
104 /*else if (mode == CYStringifyModeNative)
105 str << border << "\\\n" << border;*/
106 else if (type != CYStringTypeTemplate)
107 str << border << '+' << border;
108 else if (!space)
109 str << '\n';
110 else
111 str << "\\n\\\n";
112 break;
113
114 case '$':
115 if (type == CYStringTypeTemplate)
116 str << "\\$";
117 else goto simple;
118 break;
119
120 case '`':
121 if (type == CYStringTypeTemplate)
122 str << "\\`";
123 else goto simple;
124 break;
125
2e43a0b0 126 case '"':
37dadc21 127 if (type == CYStringTypeDouble)
2e43a0b0
JF
128 str << "\\\"";
129 else goto simple;
130 break;
131
132 case '\'':
37dadc21 133 if (type == CYStringTypeSingle)
2e43a0b0
JF
134 str << "\\'";
135 else goto simple;
136 break;
137
138 case '\0':
a0666306 139 if (mode != CYStringifyModeNative && value[1] >= '0' && value[1] <= '9')
2e43a0b0
JF
140 str << "\\x00";
141 else
142 str << "\\0";
143 break;
144
145 default:
146 if (next >= 0x20 && next < 0x7f) simple:
147 str << *value;
a0666306
JF
148 else if (mode == CYStringifyModeNative)
149 str << "\\x" << std::setbase(16) << std::setw(2) << std::setfill('0') << unsigned(*value & 0xff);
2e43a0b0
JF
150 else {
151 unsigned levels(1);
152 if ((next & 0x80) != 0)
153 while ((next & 0x80 >> ++levels) != 0);
154
155 unsigned point(next & 0xff >> levels);
156 while (--levels != 0)
157 point = point << 6 | uint8_t(*++value) & 0x3f;
158
159 if (point < 0x100)
160 str << "\\x" << std::setbase(16) << std::setw(2) << std::setfill('0') << point;
161 else if (point < 0x10000)
162 str << "\\u" << std::setbase(16) << std::setw(4) << std::setfill('0') << point;
163 else {
164 point -= 0x10000;
165 str << "\\u" << std::setbase(16) << std::setw(4) << std::setfill('0') << (0xd800 | point >> 0x0a);
166 str << "\\u" << std::setbase(16) << std::setw(4) << std::setfill('0') << (0xdc00 | point & 0x3ff);
167 }
168 }
37dadc21
JF
169 } space = false; }
170
171 str << border;
2e43a0b0 172
37dadc21
JF
173 if (parens)
174 str << ')';
2e43a0b0
JF
175}
176
177void CYNumerify(std::ostringstream &str, double value) {
178 if (std::isinf(value)) {
179 if (value < 0)
180 str << '-';
181 str << "Infinity";
182 return;
183 }
184
185 char string[32];
186 // XXX: I want this to print 1e3 rather than 1000
187 sprintf(string, "%.17g", value);
188 str << string;
189}
190
1fdca2fa 191void CYOutput::Terminate() {
efd689d8 192 operator ()(';');
1fdca2fa
JF
193 mode_ = NoMode;
194}
195
96a7e5c2 196CYOutput &CYOutput::operator <<(char rhs) {
1fdca2fa
JF
197 if (rhs == ' ' || rhs == '\n')
198 if (pretty_)
efd689d8 199 operator ()(rhs);
1fdca2fa
JF
200 else goto done;
201 else if (rhs == '\t')
202 if (pretty_)
203 for (unsigned i(0); i != indent_; ++i)
efd689d8 204 operator ()(" ", 4);
1fdca2fa 205 else goto done;
320ce753
JF
206 else if (rhs == '\r') {
207 if (right_) {
efd689d8 208 operator ()('\n');
320ce753 209 right_ = false;
14ec9e00 210 } goto done;
320ce753 211 } else goto work;
1fdca2fa 212
320ce753 213 right_ = true;
1fdca2fa
JF
214 mode_ = NoMode;
215 goto done;
96a7e5c2 216
1fdca2fa 217 work:
320ce753
JF
218 if (mode_ == Terminated && rhs != '}') {
219 right_ = true;
efd689d8 220 operator ()(';');
320ce753 221 }
96a7e5c2
JF
222
223 if (rhs == ';') {
224 if (pretty_)
225 goto none;
226 else {
227 mode_ = Terminated;
228 goto done;
229 }
c0bc320e
JF
230 } else if (rhs == '+') {
231 if (mode_ == NoPlus)
efd689d8 232 operator ()(' ');
c0bc320e 233 mode_ = NoPlus;
96a7e5c2
JF
234 } else if (rhs == '-') {
235 if (mode_ == NoHyphen)
efd689d8 236 operator ()(' ');
96a7e5c2
JF
237 mode_ = NoHyphen;
238 } else if (WordEndRange_[rhs]) {
239 if (mode_ == NoLetter)
efd689d8 240 operator ()(' ');
96a7e5c2
JF
241 mode_ = NoLetter;
242 } else none:
243 mode_ = NoMode;
244
320ce753 245 right_ = true;
efd689d8 246 operator ()(rhs);
96a7e5c2
JF
247 done:
248 return *this;
249}
250
251CYOutput &CYOutput::operator <<(const char *rhs) {
252 size_t size(strlen(rhs));
253
254 if (size == 1)
255 return *this << *rhs;
256
257 if (mode_ == Terminated)
efd689d8 258 operator ()(';');
96a7e5c2 259 else if (
c0bc320e 260 mode_ == NoPlus && *rhs == '+' ||
96a7e5c2
JF
261 mode_ == NoHyphen && *rhs == '-' ||
262 mode_ == NoLetter && WordEndRange_[*rhs]
263 )
efd689d8 264 operator ()(' ');
96a7e5c2 265
0482072a
JF
266 char last(rhs[size - 1]);
267 if (WordEndRange_[last] || last == '/')
96a7e5c2
JF
268 mode_ = NoLetter;
269 else
270 mode_ = NoMode;
271
320ce753 272 right_ = true;
efd689d8 273 operator ()(rhs, size);
96a7e5c2
JF
274 return *this;
275}
276
652ec1ba 277void CYArgument::Output(CYOutput &out) const {
d35a3b07 278 if (name_ != NULL) {
5999c315 279 out << *name_;
96a7e5c2
JF
280 if (value_ != NULL)
281 out << ':' << ' ';
5999c315 282 }
d35a3b07 283 if (value_ != NULL)
8351aa30 284 value_->Output(out, CYAssign::Precedence_, CYNoFlags);
5999c315 285 if (next_ != NULL) {
068fc9b8 286 out << ',';
96a7e5c2 287 out << ' ' << *next_;
5999c315
JF
288 }
289}
290
652ec1ba 291void CYArray::Output(CYOutput &out, CYFlags flags) const {
96a7e5c2 292 out << '[' << elements_ << ']';
5befe15e
JF
293}
294
652ec1ba 295void CYArrayComprehension::Output(CYOutput &out, CYFlags flags) const {
4644480a 296 out << '[' << *expression_ << ' ' << *comprehensions_ << ']';
75b0a457
JF
297}
298
652ec1ba 299void CYAssignment::Output(CYOutput &out, CYFlags flags) const {
fb98ac0c 300 lhs_->Output(out, Precedence() - 1, CYLeft(flags) | CYNoRightHand);
96a7e5c2 301 out << ' ' << Operator() << ' ';
b09da87b 302 rhs_->Output(out, Precedence(), CYRight(flags));
d35a3b07
JF
303}
304
beb979b4
JF
305void CYAttemptMember::Output(CYOutput &out, CYFlags flags) const {
306 object_->Output(out, Precedence(), CYLeft(flags) | CYNoInteger);
307 if (const char *word = property_->Word())
308 out << "?." << word;
309 else
310 _assert(false);
311}
312
b0385401 313void CYBlock::Output(CYOutput &out, CYFlags flags) const {
3b52fd1a
JF
314 out << '{' << '\n';
315 ++out.indent_;
b0385401 316 out << code_;
3b52fd1a
JF
317 --out.indent_;
318 out << '\t' << '}';
319}
320
652ec1ba 321void CYBoolean::Output(CYOutput &out, CYFlags flags) const {
76284c74
JF
322 out << '!' << (Value() ? "0" : "1");
323 if ((flags & CYNoInteger) != 0)
324 out << '.';
5999c315
JF
325}
326
fb98ac0c 327void CYBreak::Output(CYOutput &out, CYFlags flags) const {
5999c315
JF
328 out << "break";
329 if (label_ != NULL)
330 out << ' ' << *label_;
96a7e5c2 331 out << ';';
5999c315
JF
332}
333
652ec1ba 334void CYCall::Output(CYOutput &out, CYFlags flags) const {
fb98ac0c
JF
335 bool protect((flags & CYNoCall) != 0);
336 if (protect)
337 out << '(';
338 function_->Output(out, Precedence(), protect ? CYNoFlags : flags);
96a7e5c2 339 out << '(' << arguments_ << ')';
fb98ac0c
JF
340 if (protect)
341 out << ')';
5999c315
JF
342}
343
37954781
JF
344namespace cy {
345namespace Syntax {
346
347void Catch::Output(CYOutput &out) const {
b0385401
JF
348 out << ' ' << "catch" << ' ' << '(' << *name_ << ')' << ' ';
349 out << '{' << '\n';
350 ++out.indent_;
351 out << code_;
352 --out.indent_;
353 out << '\t' << '}';
5999c315
JF
354}
355
37954781
JF
356} }
357
c5b15840
JF
358void CYClassExpression::Output(CYOutput &out, CYFlags flags) const {
359 bool protect((flags & CYNoClass) != 0);
360 if (protect)
361 out << '(';
362 out << "class";
363 if (name_ != NULL)
364 out << ' ' << *name_;
365 out << *tail_;;
366 if (protect)
367 out << ')';
368}
369
370void CYClassStatement::Output(CYOutput &out, CYFlags flags) const {
371 out << "class" << ' ' << *name_ << *tail_;
372}
373
374void CYClassTail::Output(CYOutput &out) const {
375 if (extends_ == NULL)
376 out << ' ';
377 else {
378 out << '\n';
379 ++out.indent_;
380 out << "extends" << ' ';
381 extends_->Output(out, CYAssign::Precedence_ - 1, CYNoFlags);
382 out << '\n';
383 --out.indent_;
384 }
385
386 out << '{' << '\n';
387 ++out.indent_;
388
389 --out.indent_;
390 out << '}';
391}
392
652ec1ba 393void CYCompound::Output(CYOutput &out, CYFlags flags) const {
fd5cdf97
JF
394 if (next_ == NULL)
395 expression_->Output(out, flags);
396 else {
397 expression_->Output(out, CYLeft(flags));
398 out << ',' << ' ';
399 next_->Output(out, CYRight(flags));
400 }
e5bc40db
JF
401}
402
c5b15840
JF
403void CYComputed::PropertyName(CYOutput &out) const {
404 out << '[';
405 expression_->Output(out, CYAssign::Precedence_, CYNoFlags);
406 out << ']';
407}
408
652ec1ba 409void CYCondition::Output(CYOutput &out, CYFlags flags) const {
b09da87b 410 test_->Output(out, Precedence() - 1, CYLeft(flags));
96a7e5c2 411 out << ' ' << '?' << ' ';
5999c315 412 if (true_ != NULL)
2fad14e5 413 true_->Output(out, CYAssign::Precedence_, CYNoColon);
96a7e5c2 414 out << ' ' << ':' << ' ';
8351aa30 415 false_->Output(out, CYAssign::Precedence_, CYRight(flags));
5999c315
JF
416}
417
fb98ac0c 418void CYContinue::Output(CYOutput &out, CYFlags flags) const {
5999c315
JF
419 out << "continue";
420 if (label_ != NULL)
421 out << ' ' << *label_;
96a7e5c2 422 out << ';';
5999c315
JF
423}
424
652ec1ba 425void CYClause::Output(CYOutput &out) const {
efd689d8 426 out << '\t';
2fad14e5 427 if (value_ == NULL)
5999c315 428 out << "default";
2fad14e5
JF
429 else {
430 out << "case" << ' ';
431 value_->Output(out, CYNoColon);
432 }
1fdca2fa 433 out << ':' << '\n';
efd689d8 434 ++out.indent_;
b0385401 435 out << code_;
efd689d8 436 --out.indent_;
96a7e5c2 437 out << next_;
cac61857
JF
438}
439
c8a0500b
JF
440void CYDebugger::Output(CYOutput &out, CYFlags flags) const {
441 out << "debugger" << ';';
442}
443
09fc3efb 444void CYBinding::Output(CYOutput &out, CYFlags flags) const {
5999c315 445 out << *identifier_;
e013809d 446 //out.out_ << ':' << identifier_->usage_ << '#' << identifier_->offset_;
09fc3efb 447 if (initializer_ != NULL) {
96a7e5c2 448 out << ' ' << '=' << ' ';
09fc3efb 449 initializer_->Output(out, CYAssign::Precedence_, CYRight(flags));
96a7e5c2 450 }
5999c315
JF
451}
452
09fc3efb 453void CYBindings::Output(CYOutput &out) const {
96a7e5c2 454 Output(out, CYNoFlags);
cac61857 455}
d35a3b07 456
09fc3efb
JF
457void CYBindings::Output(CYOutput &out, CYFlags flags) const {
458 const CYBindings *binding(this);
fb98ac0c 459 bool first(true);
d35a3b07 460
c8a0500b 461 for (;;) {
09fc3efb 462 CYBindings *next(binding->next_);
c8a0500b
JF
463
464 CYFlags jacks(first ? CYLeft(flags) : next == NULL ? CYRight(flags) : CYCenter(flags));
465 first = false;
09fc3efb 466 binding->binding_->Output(out, jacks);
c8a0500b
JF
467
468 if (next == NULL)
469 break;
470
96a7e5c2 471 out << ',' << ' ';
09fc3efb 472 binding = next;
d35a3b07 473 }
5999c315
JF
474}
475
652ec1ba 476void CYDirectMember::Output(CYOutput &out, CYFlags flags) const {
b38adb44 477 object_->Output(out, Precedence(), CYLeft(flags) | CYNoInteger);
9b5527f0
JF
478 if (const char *word = property_->Word())
479 out << '.' << word;
96a7e5c2
JF
480 else
481 out << '[' << *property_ << ']';
9b5527f0
JF
482}
483
fb98ac0c 484void CYDoWhile::Output(CYOutput &out, CYFlags flags) const {
fb98ac0c 485 out << "do";
efd689d8
JF
486
487 unsigned line(out.position_.line);
488 unsigned indent(out.indent_);
489 code_->Single(out, CYCenter(flags), CYCompactLong);
490
491 if (out.position_.line != line && out.recent_ == indent)
492 out << ' ';
493 else
494 out << '\n' << '\t';
495
96a7e5c2 496 out << "while" << ' ' << '(' << *test_ << ')';
5999c315
JF
497}
498
fc8fc33d
JF
499void CYElementSpread::Output(CYOutput &out) const {
500 out << "..." << value_;
501}
502
503void CYElementValue::Output(CYOutput &out) const {
5999c315 504 if (value_ != NULL)
8351aa30 505 value_->Output(out, CYAssign::Precedence_, CYNoFlags);
11c1cc16 506 if (next_ != NULL || value_ == NULL) {
5999c315 507 out << ',';
fc8fc33d 508 if (next_ != NULL && !next_->Elision())
11c1cc16
JF
509 out << ' ';
510 }
5befe15e
JF
511 if (next_ != NULL)
512 next_->Output(out);
5999c315
JF
513}
514
fb98ac0c 515void CYEmpty::Output(CYOutput &out, CYFlags flags) const {
1fdca2fa 516 out.Terminate();
5999c315
JF
517}
518
7085e1ab
JF
519void CYEval::Output(CYOutput &out, CYFlags flags) const {
520 _assert(false);
521}
522
fb98ac0c 523void CYExpress::Output(CYOutput &out, CYFlags flags) const {
c5b15840 524 expression_->Output(out, flags | CYNoBFC);
96a7e5c2 525 out << ';';
5999c315
JF
526}
527
96a7e5c2
JF
528void CYExpression::Output(CYOutput &out) const {
529 Output(out, CYNoFlags);
530}
531
9a39f705 532void CYExpression::Output(CYOutput &out, int precedence, CYFlags flags) const {
96a7e5c2
JF
533 if (precedence < Precedence() || (flags & CYNoRightHand) != 0 && RightHand())
534 out << '(' << *this << ')';
535 else
b09da87b
JF
536 Output(out, flags);
537}
538
4f3e597c
JF
539void CYExtend::Output(CYOutput &out, CYFlags flags) const {
540 lhs_->Output(out, CYLeft(flags));
541 out << ' ' << object_;
542}
543
436a877b 544void CYExternalDefinition::Output(CYOutput &out, CYFlags flags) const {
5b4dabb2
JF
545 out << "extern" << ' ' << abi_ << ' ';
546 type_->Output(out, name_);
ffc2d225 547 out.Terminate();
c5587ed7
JF
548}
549
436a877b 550void CYExternalExpression::Output(CYOutput &out, CYFlags flags) const {
5b4dabb2
JF
551 out << '(' << "extern" << ' ' << abi_ << ' ';
552 type_->Output(out, name_);
553 out << ')';
436a877b
JF
554}
555
a0be43fc 556void CYFatArrow::Output(CYOutput &out, CYFlags flags) const {
b0385401 557 out << '(' << parameters_ << ')' << ' ' << "=>" << ' ' << '{' << code_ << '}';
a0be43fc
JF
558}
559
b10bd496 560void CYFinally::Output(CYOutput &out) const {
b0385401
JF
561 out << ' ' << "finally" << ' ';
562 out << '{' << '\n';
563 ++out.indent_;
564 out << code_;
565 --out.indent_;
566 out << '\t' << '}';
b10bd496
JF
567}
568
fb98ac0c 569void CYFor::Output(CYOutput &out, CYFlags flags) const {
96a7e5c2 570 out << "for" << ' ' << '(';
09fc3efb
JF
571 if (initializer_ != NULL)
572 initializer_->Output(out, CYNoIn);
1fdca2fa 573 out.Terminate();
e661185c
JF
574 if (test_ != NULL)
575 out << ' ';
96a7e5c2 576 out << test_;
1fdca2fa 577 out.Terminate();
e661185c
JF
578 if (increment_ != NULL)
579 out << ' ';
96a7e5c2 580 out << increment_;
5999c315 581 out << ')';
efd689d8 582 code_->Single(out, CYRight(flags), CYCompactShort);
5999c315 583}
75b0a457 584
7085e1ab
JF
585void CYForLexical::Output(CYOutput &out, CYFlags flags) const {
586 out << (constant_ ? "const" : "let") << ' ';
09fc3efb 587 binding_->Output(out, CYRight(flags));
75b0a457
JF
588}
589
fb98ac0c 590void CYForIn::Output(CYOutput &out, CYFlags flags) const {
96a7e5c2 591 out << "for" << ' ' << '(';
09fc3efb
JF
592 initializer_->Output(out, CYNoIn | CYNoRightHand);
593 out << ' ' << "in" << ' ' << *iterable_ << ')';
efd689d8 594 code_->Single(out, CYRight(flags), CYCompactShort);
5999c315
JF
595}
596
23111dca
JF
597void CYForInitialized::Output(CYOutput &out, CYFlags flags) const {
598 out << "for" << ' ' << '(' << "var" << ' ';
09fc3efb
JF
599 binding_->Output(out, CYNoIn | CYNoRightHand);
600 out << ' ' << "in" << ' ' << *iterable_ << ')';
23111dca
JF
601 code_->Single(out, CYRight(flags), CYCompactShort);
602}
603
4644480a 604void CYForInComprehension::Output(CYOutput &out) const {
4e3c9056 605 out << "for" << ' ' << '(';
09fc3efb
JF
606 binding_->Output(out, CYNoIn | CYNoRightHand);
607 out << ' ' << "in" << ' ' << *iterable_ << ')';
75b0a457
JF
608}
609
7085e1ab
JF
610void CYForOf::Output(CYOutput &out, CYFlags flags) const {
611 out << "for" << ' ' << '(';
09fc3efb
JF
612 initializer_->Output(out, CYNoRightHand);
613 out << ' ' << "of" << ' ' << *iterable_ << ')';
7085e1ab
JF
614 code_->Single(out, CYRight(flags), CYCompactShort);
615}
616
617void CYForOfComprehension::Output(CYOutput &out) const {
618 out << "for" << ' ' << '(';
09fc3efb
JF
619 binding_->Output(out, CYNoRightHand);
620 out << ' ' << "of" << ' ' << *iterable_ << ')' << next_;
7085e1ab
JF
621}
622
623void CYForVariable::Output(CYOutput &out, CYFlags flags) const {
624 out << "var" << ' ';
09fc3efb 625 binding_->Output(out, CYRight(flags));
7085e1ab
JF
626}
627
c5b15840 628void CYFunction::Output(CYOutput &out) const {
b0385401
JF
629 out << '(' << parameters_ << ')' << ' ';
630 out << '{' << '\n';
631 ++out.indent_;
632 out << code_;
633 --out.indent_;
634 out << '\t' << '}';
fb98ac0c
JF
635}
636
637void CYFunctionExpression::Output(CYOutput &out, CYFlags flags) const {
c5b15840
JF
638 // XXX: one could imagine using + here to save a byte
639 bool protect((flags & CYNoFunction) != 0);
640 if (protect)
641 out << '(';
642 out << "function";
643 if (name_ != NULL)
644 out << ' ' << *name_;
645 CYFunction::Output(out);
646 if (protect)
647 out << ')';
fb98ac0c
JF
648}
649
650void CYFunctionStatement::Output(CYOutput &out, CYFlags flags) const {
c5b15840
JF
651 out << "function" << ' ' << *name_;
652 CYFunction::Output(out);
b09da87b
JF
653}
654
652ec1ba 655void CYFunctionParameter::Output(CYOutput &out) const {
09fc3efb 656 binding_->Output(out, CYNoFlags);
96a7e5c2
JF
657 if (next_ != NULL)
658 out << ',' << ' ' << *next_;
5999c315
JF
659}
660
029bc65b 661const char *CYIdentifier::Word() const {
7085e1ab 662 return next_ == NULL || next_ == this ? CYWord::Word() : next_->Word();
029bc65b
JF
663}
664
fb98ac0c
JF
665void CYIf::Output(CYOutput &out, CYFlags flags) const {
666 bool protect(false);
667 if (false_ == NULL && (flags & CYNoDangle) != 0) {
668 protect = true;
669 out << '{';
96a7e5c2 670 }
1fdca2fa
JF
671
672 out << "if" << ' ' << '(' << *test_ << ')';
673
fb98ac0c 674 CYFlags right(protect ? CYNoFlags : CYRight(flags));
d29365ce 675
fb98ac0c 676 CYFlags jacks(CYNoDangle);
96a7e5c2
JF
677 if (false_ == NULL)
678 jacks |= right;
d29365ce
JF
679 else
680 jacks |= protect ? CYNoFlags : CYCenter(flags);
1fdca2fa 681
efd689d8
JF
682 unsigned line(out.position_.line);
683 unsigned indent(out.indent_);
684 true_->Single(out, jacks, CYCompactShort);
1fdca2fa 685
5999c315 686 if (false_ != NULL) {
efd689d8
JF
687 if (out.position_.line != line && out.recent_ == indent)
688 out << ' ';
689 else
690 out << '\n' << '\t';
691
692 out << "else";
693 false_->Single(out, right, CYCompactLong);
5999c315 694 }
1fdca2fa 695
fb98ac0c
JF
696 if (protect)
697 out << '}';
5999c315
JF
698}
699
4644480a
JF
700void CYIfComprehension::Output(CYOutput &out) const {
701 out << "if" << ' ' << '(' << *test_ << ')' << next_;
75b0a457
JF
702}
703
7b750785
JF
704void CYImport::Output(CYOutput &out, CYFlags flags) const {
705 out << "@import";
706}
707
90dd6ff1
JF
708void CYImportDeclaration::Output(CYOutput &out, CYFlags flags) const {
709 _assert(false);
710}
711
7085e1ab
JF
712void CYIndirect::Output(CYOutput &out, CYFlags flags) const {
713 out << "*";
714 rhs_->Output(out, Precedence(), CYRight(flags));
715}
716
652ec1ba 717void CYIndirectMember::Output(CYOutput &out, CYFlags flags) const {
9b5527f0 718 object_->Output(out, Precedence(), CYLeft(flags));
9b5527f0 719 if (const char *word = property_->Word())
3b52fd1a 720 out << "->" << word;
96a7e5c2 721 else
3b52fd1a 722 out << "->" << '[' << *property_ << ']';
5999c315
JF
723}
724
652ec1ba 725void CYInfix::Output(CYOutput &out, CYFlags flags) const {
b09da87b 726 const char *name(Operator());
d09e527c 727 bool protect((flags & CYNoIn) != 0 && strcmp(name, "in") == 0);
b09da87b
JF
728 if (protect)
729 out << '(';
b09da87b 730 CYFlags left(protect ? CYNoFlags : CYLeft(flags));
b09da87b 731 lhs_->Output(out, Precedence(), left);
96a7e5c2 732 out << ' ' << name << ' ';
b09da87b 733 CYFlags right(protect ? CYNoFlags : CYRight(flags));
b09da87b
JF
734 rhs_->Output(out, Precedence() - 1, right);
735 if (protect)
736 out << ')';
5999c315
JF
737}
738
3b52fd1a 739void CYLabel::Output(CYOutput &out, CYFlags flags) const {
efd689d8
JF
740 out << *name_ << ':';
741 statement_->Single(out, CYRight(flags), CYCompactShort);
3b52fd1a
JF
742}
743
b0385401
JF
744void CYParenthetical::Output(CYOutput &out, CYFlags flags) const {
745 out << '(';
746 expression_->Output(out, CYCompound::Precedence_, CYNoFlags);
747 out << ')';
748}
749
750void CYStatement::Output(CYOutput &out) const {
751 Multiple(out);
752}
753
b900e1a4
JF
754void CYTemplate::Output(CYOutput &out, CYFlags flags) const {
755 _assert(false);
756}
757
5b4dabb2
JF
758void CYTypeArrayOf::Output(CYOutput &out, CYPropertyName *name) const {
759 next_->Output(out, Precedence(), name, false);
9a39f705
JF
760 out << '[';
761 out << size_;
762 out << ']';
763}
764
5b4dabb2 765void CYTypeBlockWith::Output(CYOutput &out, CYPropertyName *name) const {
3fe16be7 766 out << '(' << '^';
5b4dabb2 767 next_->Output(out, Precedence(), name, false);
3fe16be7
JF
768 out << ')' << '(' << parameters_ << ')';
769}
770
5b4dabb2 771void CYTypeConstant::Output(CYOutput &out, CYPropertyName *name) const {
53cb77ff 772 out << "const";
5b4dabb2 773 next_->Output(out, Precedence(), name, false);
9a39f705
JF
774}
775
5b4dabb2
JF
776void CYTypeFunctionWith::Output(CYOutput &out, CYPropertyName *name) const {
777 next_->Output(out, Precedence(), name, false);
574d4720
JF
778 out << '(' << parameters_;
779 if (variadic_) {
780 if (parameters_ != NULL)
781 out << ',' << ' ';
782 out << "...";
783 }
784 out << ')';
9a39f705
JF
785}
786
5b4dabb2 787void CYTypePointerTo::Output(CYOutput &out, CYPropertyName *name) const {
9a39f705 788 out << '*';
5b4dabb2 789 next_->Output(out, Precedence(), name, false);
9a39f705
JF
790}
791
5b4dabb2 792void CYTypeVolatile::Output(CYOutput &out, CYPropertyName *name) const {
9a39f705 793 out << "volatile";
5b4dabb2 794 next_->Output(out, Precedence(), name, true);
9a39f705
JF
795}
796
5b4dabb2
JF
797void CYTypeModifier::Output(CYOutput &out, int precedence, CYPropertyName *name, bool space) const {
798 if (this == NULL && name == NULL)
53cb77ff
JF
799 return;
800 else if (space)
801 out << ' ';
802
9a39f705 803 if (this == NULL) {
5b4dabb2 804 name->PropertyName(out);
9a39f705
JF
805 return;
806 }
807
808 bool protect(precedence > Precedence());
809
810 if (protect)
811 out << '(';
5b4dabb2 812 Output(out, name);
9a39f705
JF
813 if (protect)
814 out << ')';
815}
816
5b4dabb2 817void CYType::Output(CYOutput &out, CYPropertyName *name) const {
aaa29c28 818 out << *specifier_;
5b4dabb2
JF
819 modifier_->Output(out, 0, name, true);
820}
821
822void CYType::Output(CYOutput &out) const {
823 Output(out, NULL);
9a39f705
JF
824}
825
826void CYEncodedType::Output(CYOutput &out, CYFlags flags) const {
827 out << "@encode(" << typed_ << ")";
828}
829
830void CYTypedParameter::Output(CYOutput &out) const {
5b4dabb2 831 type_->Output(out, name_);
9a39f705
JF
832 if (next_ != NULL)
833 out << ',' << ' ' << next_;
60097023
JF
834}
835
690cf1a8
JF
836void CYLambda::Output(CYOutput &out, CYFlags flags) const {
837 // XXX: this is seriously wrong
838 out << "[](";
839 out << ")->";
840 out << "{";
841 out << "}";
842}
843
60097023 844void CYTypeDefinition::Output(CYOutput &out, CYFlags flags) const {
5b4dabb2
JF
845 out << "typedef" << ' ';
846 type_->Output(out, name_);
ffc2d225 847 out.Terminate();
60097023
JF
848}
849
64a505ff
JF
850void CYTypeExpression::Output(CYOutput &out, CYFlags flags) const {
851 out << '(' << "typedef" << ' ' << *typed_ << ')';
852}
853
09fc3efb 854void CYLexical::Output(CYOutput &out, CYFlags flags) const {
ca6a1b2b 855 out << "let" << ' ';
09fc3efb 856 bindings_->Output(out, flags); // XXX: flags
ca6a1b2b 857 out << ';';
cac61857
JF
858}
859
7b750785
JF
860void CYModule::Output(CYOutput &out) const {
861 out << part_;
862 if (next_ != NULL)
863 out << '.' << next_;
864}
865
2eb8215d
JF
866namespace cy {
867namespace Syntax {
868
869void New::Output(CYOutput &out, CYFlags flags) const {
96a7e5c2 870 out << "new" << ' ';
11c1cc16 871 CYFlags jacks(CYNoCall | CYCenter(flags));
11c1cc16 872 constructor_->Output(out, Precedence(), jacks);
96a7e5c2
JF
873 if (arguments_ != NULL)
874 out << '(' << *arguments_ << ')';
5999c315
JF
875}
876
2eb8215d
JF
877} }
878
652ec1ba 879void CYNull::Output(CYOutput &out, CYFlags flags) const {
8f56307d 880 out << "null";
5999c315
JF
881}
882
652ec1ba 883void CYNumber::Output(CYOutput &out, CYFlags flags) const {
856b8cd0
JF
884 std::ostringstream str;
885 CYNumerify(str, Value());
9561f209
JF
886 std::string value(str.str());
887 out << value.c_str();
888 // XXX: this should probably also handle hex conversions and exponents
889 if ((flags & CYNoInteger) != 0 && value.find('.') == std::string::npos)
890 out << '.';
5999c315
JF
891}
892
652ec1ba 893void CYNumber::PropertyName(CYOutput &out) const {
fb98ac0c 894 Output(out, CYNoFlags);
e5bc40db
JF
895}
896
652ec1ba 897void CYObject::Output(CYOutput &out, CYFlags flags) const {
b09da87b
JF
898 bool protect((flags & CYNoBrace) != 0);
899 if (protect)
900 out << '(';
c0bc320e
JF
901 out << '{' << '\n';
902 ++out.indent_;
3b52fd1a 903 out << properties_;
c0bc320e
JF
904 --out.indent_;
905 out << '\t' << '}';
b09da87b
JF
906 if (protect)
907 out << ')';
693d501b
JF
908}
909
652ec1ba 910void CYPostfix::Output(CYOutput &out, CYFlags flags) const {
b09da87b 911 lhs_->Output(out, Precedence(), CYLeft(flags));
d35a3b07 912 out << Operator();
5999c315
JF
913}
914
652ec1ba 915void CYPrefix::Output(CYOutput &out, CYFlags flags) const {
1ef7d061 916 const char *name(Operator());
1ef7d061 917 out << name;
96a7e5c2 918 if (Alphabetic())
11c1cc16 919 out << ' ';
96a7e5c2 920 rhs_->Output(out, Precedence(), CYRight(flags));
5999c315
JF
921}
922
a7d8b413 923void CYScript::Output(CYOutput &out) const {
b0385401 924 out << code_;
3b52fd1a
JF
925}
926
652ec1ba 927void CYProperty::Output(CYOutput &out) const {
c5b15840
JF
928 if (next_ != NULL || out.pretty_)
929 out << ',';
930 out << '\n' << next_;
931}
932
933void CYPropertyGetter::Output(CYOutput &out) const {
934 out << "get" << ' ';
935 name_->PropertyName(out);
936 CYFunction::Output(out);
937 CYProperty::Output(out);
938}
939
940void CYPropertyMethod::Output(CYOutput &out) const {
941 name_->PropertyName(out);
942 CYFunction::Output(out);
943 CYProperty::Output(out);
944}
945
946void CYPropertySetter::Output(CYOutput &out) const {
947 out << "set" << ' ';
948 name_->PropertyName(out);
949 CYFunction::Output(out);
950 CYProperty::Output(out);
951}
952
953void CYPropertyValue::Output(CYOutput &out) const {
c0bc320e 954 out << '\t';
e5bc40db 955 name_->PropertyName(out);
96a7e5c2 956 out << ':' << ' ';
8351aa30 957 value_->Output(out, CYAssign::Precedence_, CYNoFlags);
c5b15840 958 CYProperty::Output(out);
5999c315
JF
959}
960
63cd45c9
JF
961void CYRegEx::Output(CYOutput &out, CYFlags flags) const {
962 out << Value();
63cd45c9
JF
963}
964
2fad14e5
JF
965void CYResolveMember::Output(CYOutput &out, CYFlags flags) const {
966 object_->Output(out, Precedence(), CYLeft(flags));
967 if (const char *word = property_->Word())
968 out << "::" << word;
969 else
970 out << "::" << '[' << *property_ << ']';
971}
972
fb98ac0c 973void CYReturn::Output(CYOutput &out, CYFlags flags) const {
c0bc320e
JF
974 out << "return";
975 if (value_ != NULL)
976 out << ' ' << *value_;
977 out << ';';
5999c315
JF
978}
979
6c093cce 980void CYRubyBlock::Output(CYOutput &out, CYFlags flags) const {
4f3e597c 981 lhs_->Output(out, CYLeft(flags));
6c093cce
JF
982 out << ' ';
983 proc_->Output(out, CYRight(flags));
984}
985
986void CYRubyProc::Output(CYOutput &out, CYFlags flags) const {
0da459fc 987 out << '{' << ' ' << '|' << parameters_ << '|' << '\n';
b0385401 988 ++out.indent_;
6c093cce 989 out << code_;
b0385401
JF
990 --out.indent_;
991 out << '\t' << '}';
6c093cce
JF
992}
993
e56c2499
JF
994void CYSubscriptMember::Output(CYOutput &out, CYFlags flags) const {
995 object_->Output(out, Precedence(), CYLeft(flags));
996 out << "." << '[' << *property_ << ']';
997}
998
fb98ac0c
JF
999void CYStatement::Multiple(CYOutput &out, CYFlags flags) const {
1000 bool first(true);
c2c9f509 1001 CYForEach (next, this) {
fb98ac0c 1002 bool last(next->next_ == NULL);
7bf4a0cd 1003 CYFlags jacks(first ? last ? flags : CYLeft(flags) : last ? CYRight(flags) : CYCenter(flags));
fb98ac0c 1004 first = false;
1fdca2fa 1005 out << '\t';
fb98ac0c 1006 next->Output(out, jacks);
1fdca2fa 1007 out << '\n';
fb98ac0c 1008 }
5999c315
JF
1009}
1010
efd689d8 1011void CYStatement::Single(CYOutput &out, CYFlags flags, CYCompactType request) const {
0f37eca9
JF
1012 if (this == NULL)
1013 return out.Terminate();
1014
3b52fd1a 1015 _assert(next_ == NULL);
efd689d8
JF
1016
1017 CYCompactType compact(Compact());
1018
1019 if (compact >= request)
1020 out << ' ';
1021 else {
1022 out << '\n';
1023 ++out.indent_;
1024 out << '\t';
1025 }
1026
3b52fd1a 1027 Output(out, flags);
efd689d8
JF
1028
1029 if (compact < request)
1030 --out.indent_;
5999c315
JF
1031}
1032
652ec1ba 1033void CYString::Output(CYOutput &out, CYFlags flags) const {
96a7e5c2 1034 std::ostringstream str;
37dadc21 1035 CYStringify(str, value_, size_, CYStringifyModeLegacy);
96a7e5c2 1036 out << str.str().c_str();
5999c315
JF
1037}
1038
652ec1ba 1039void CYString::PropertyName(CYOutput &out) const {
e5bc40db
JF
1040 if (const char *word = Word())
1041 out << word;
1042 else
96a7e5c2 1043 out << *this;
e5bc40db
JF
1044}
1045
c0bc320e
JF
1046static const char *Reserved_[] = {
1047 "false", "null", "true",
1048
1049 "break", "case", "catch", "continue", "default",
1050 "delete", "do", "else", "finally", "for", "function",
1051 "if", "in", "instanceof", "new", "return", "switch",
1052 "this", "throw", "try", "typeof", "var", "void",
1053 "while", "with",
1054
1055 "debugger", "const",
1056
1057 "class", "enum", "export", "extends", "import", "super",
1058
1059 "abstract", "boolean", "byte", "char", "double", "final",
1060 "float", "goto", "int", "long", "native", "short",
1061 "synchronized", "throws", "transient", "volatile",
1062
1063 "let", "yield",
1064
c0bc320e
JF
1065 NULL
1066};
1067
11c1cc16
JF
1068const char *CYString::Word() const {
1069 if (size_ == 0 || !WordStartRange_[value_[0]])
1070 return NULL;
1071 for (size_t i(1); i != size_; ++i)
1072 if (!WordEndRange_[value_[i]])
1073 return NULL;
1074 const char *value(Value());
c0bc320e 1075 for (const char **reserved(Reserved_); *reserved != NULL; ++reserved)
11c1cc16
JF
1076 if (strcmp(*reserved, value) == 0)
1077 return NULL;
1078 return value;
1079}
1080
d8380373
JF
1081void CYStructDefinition::Output(CYOutput &out, CYFlags flags) const {
1082 out << "struct" << ' ' << *name_ << *tail_;
1083}
1084
1085void CYStructTail::Output(CYOutput &out) const {
1086 out << ' ' << '{' << '\n';
1087 ++out.indent_;
1088 CYForEach (field, fields_) {
5b4dabb2
JF
1089 out << '\t';
1090 field->type_->Output(out, field->name_);
d8380373
JF
1091 out.Terminate();
1092 out << '\n';
1093 }
1094 --out.indent_;
53cb77ff 1095 out << '\t' << '}';
d8380373
JF
1096}
1097
c5b15840
JF
1098void CYSuperAccess::Output(CYOutput &out, CYFlags flags) const {
1099 out << "super";
1100 if (const char *word = property_->Word())
1101 out << '.' << word;
1102 else
1103 out << '[' << *property_ << ']';
1104}
1105
1106void CYSuperCall::Output(CYOutput &out, CYFlags flags) const {
1107 out << "super" << '(' << arguments_ << ')';
1108}
1109
fb98ac0c 1110void CYSwitch::Output(CYOutput &out, CYFlags flags) const {
efd689d8
JF
1111 out << "switch" << ' ' << '(' << *value_ << ')' << ' ' << '{' << '\n';
1112 ++out.indent_;
96a7e5c2 1113 out << clauses_;
efd689d8
JF
1114 --out.indent_;
1115 out << '\t' << '}';
5999c315
JF
1116}
1117
2fad14e5
JF
1118void CYSymbol::Output(CYOutput &out, CYFlags flags) const {
1119 bool protect((flags & CYNoColon) != 0);
1120 if (protect)
1121 out << '(';
1122 out << ':' << name_;
1123 if (protect)
1124 out << ')';
1125}
1126
652ec1ba 1127void CYThis::Output(CYOutput &out, CYFlags flags) const {
8f56307d 1128 out << "this";
5999c315
JF
1129}
1130
37954781
JF
1131namespace cy {
1132namespace Syntax {
1133
1134void Throw::Output(CYOutput &out, CYFlags flags) const {
c0bc320e
JF
1135 out << "throw";
1136 if (value_ != NULL)
1137 out << ' ' << *value_;
1138 out << ';';
5999c315
JF
1139}
1140
37954781 1141void Try::Output(CYOutput &out, CYFlags flags) const {
b0385401
JF
1142 out << "try" << ' ';
1143 out << '{' << '\n';
1144 ++out.indent_;
1145 out << code_;
1146 --out.indent_;
1147 out << '\t' << '}';
1148 out << catch_ << finally_;
5999c315
JF
1149}
1150
37954781
JF
1151} }
1152
0559abf8
JF
1153void CYTypeCharacter::Output(CYOutput &out) const {
1154 switch (signing_) {
1155 case CYTypeNeutral: break;
1156 case CYTypeSigned: out << "signed" << ' '; break;
1157 case CYTypeUnsigned: out << "unsigned" << ' '; break;
1158 }
03db6a67 1159
0559abf8 1160 out << "char";
3fe283c5
JF
1161}
1162
aaa29c28
JF
1163void CYTypeEnum::Output(CYOutput &out) const {
1164 out << "enum" << ' ';
1165 if (name_ != NULL)
1166 out << *name_;
1167 else {
1168 if (specifier_ != NULL)
1169 out << ':' << ' ' << *specifier_ << ' ';
1170
1171 out << '{' << '\n';
1172 ++out.indent_;
1173 bool comma(false);
1174
1175 CYForEach (constant, constants_) {
1176 if (comma)
1177 out << ',' << '\n';
1178 else
1179 comma = true;
1180 out << '\t' << constant->name_;
1181 out << ' ' << '=' << ' ' << constant->value_;
1182 }
1183
1184 if (out.pretty_)
1185 out << ',';
1186 out << '\n';
1187 --out.indent_;
1188 out << '\t' << '}';
1189 }
1190}
1191
0559abf8
JF
1192void CYTypeError::Output(CYOutput &out) const {
1193 out << "@error";
3fe283c5
JF
1194}
1195
1e8d8047
JF
1196void CYTypeFloating::Output(CYOutput &out) const {
1197 switch (length_) {
1198 case 0: out << "float"; break;
1199 case 1: out << "double"; break;
1200 case 2: out << "long" << ' ' << "double"; break;
1201 default: _assert(false);
1202 }
1203}
1204
24ffc58c
JF
1205void CYTypeInt128::Output(CYOutput &out) const {
1206 switch (signing_) {
1207 case CYTypeNeutral: break;
1208 case CYTypeSigned: out << "signed" << ' '; break;
1209 case CYTypeUnsigned: out << "unsigned" << ' '; break;
1210 }
1211
1212 out << "__int128";
1213}
1214
0559abf8
JF
1215void CYTypeIntegral::Output(CYOutput &out) const {
1216 if (signing_ == CYTypeUnsigned)
1217 out << "unsigned" << ' ';
1218 switch (length_) {
1219 case 0: out << "short"; break;
1220 case 1: out << "int"; break;
1221 case 2: out << "long"; break;
1222 case 3: out << "long" << ' ' << "long"; break;
1223 default: _assert(false);
1224 }
3fe283c5
JF
1225}
1226
b3c38c5f 1227void CYTypeStruct::Output(CYOutput &out) const {
d8380373 1228 out << "struct";
b3c38c5f 1229 if (name_ != NULL)
d8380373
JF
1230 out << ' ' << *name_;
1231 else
1232 out << *tail_;
b3c38c5f
JF
1233}
1234
d8380373 1235void CYTypeReference::Output(CYOutput &out) const {
aaa29c28
JF
1236 switch (kind_) {
1237 case CYTypeReferenceStruct: out << "struct"; break;
1238 case CYTypeReferenceEnum: out << "enum"; break;
1239 default: _assert(false);
1240 }
1241
1242 out << ' ' << *name_;
d8380373
JF
1243}
1244
3fe283c5
JF
1245void CYTypeVariable::Output(CYOutput &out) const {
1246 out << *name_;
1247}
1248
1249void CYTypeVoid::Output(CYOutput &out) const {
1250 out << "void";
1251}
1252
fb98ac0c 1253void CYVar::Output(CYOutput &out, CYFlags flags) const {
efd689d8 1254 out << "var" << ' ';
09fc3efb 1255 bindings_->Output(out, flags); // XXX: flags
96a7e5c2 1256 out << ';';
cac61857
JF
1257}
1258
652ec1ba 1259void CYVariable::Output(CYOutput &out, CYFlags flags) const {
5999c315
JF
1260 out << *name_;
1261}
1262
fb98ac0c 1263void CYWhile::Output(CYOutput &out, CYFlags flags) const {
efd689d8
JF
1264 out << "while" << ' ' << '(' << *test_ << ')';
1265 code_->Single(out, CYRight(flags), CYCompactShort);
5999c315
JF
1266}
1267
fb98ac0c 1268void CYWith::Output(CYOutput &out, CYFlags flags) const {
efd689d8
JF
1269 out << "with" << ' ' << '(' << *scope_ << ')';
1270 code_->Single(out, CYRight(flags), CYCompactShort);
5999c315
JF
1271}
1272
652ec1ba 1273void CYWord::Output(CYOutput &out) const {
029bc65b 1274 out << Word();
efd689d8
JF
1275 if (out.options_.verbose_) {
1276 out('@');
1277 char number[32];
1278 sprintf(number, "%p", this);
1279 out(number);
1280 }
5999c315 1281}
e5bc40db 1282
652ec1ba 1283void CYWord::PropertyName(CYOutput &out) const {
e5bc40db
JF
1284 Output(out);
1285}
029bc65b
JF
1286
1287const char *CYWord::Word() const {
1288 return word_;
1289}