source: webkit/trunk/JavaScriptCore/kjs/nodes2string.cpp@ 27664

Last change on this file since 27664 was 27664, checked in by Darin Adler, 18 years ago

Reviewed by Sam.

Gives 1.1% on SunSpider.

  • kjs/grammar.y: Create TrueNode and FalseNode instead of BooleanNode.
  • kjs/nodes.h: Changed to use Noncopyable. Moved optimizeForUnnecessaryResult down from Node to ExpressionNode. Changed some classes to not inherit from ExpressionNode where not necessary, and removed unnneeded evaluate functions as well as evaluate functions that need not be virtual. Call the optimizeForUnnecessaryResult function on the start of a for loop too.
  • kjs/nodes.cpp: (KJS::ExpressionNode::evaluateToBoolean): Added. (KJS::FalseNode::evaluate): Added. (KJS::TrueNode::evaluate): Added. (KJS::NumberNode::evaluateToBoolean): Added. (KJS::StringNode::evaluateToBoolean): Added. (KJS::LocalVarAccessNode::evaluateToBoolean): Added. (KJS::BracketAccessorNode::evaluateToBoolean): Added. (KJS::LogicalNotNode::evaluate): Changed to call evaluateToBoolean. (KJS::LogicalNotNode::evaluateToBoolean): Added. (KJS::lessThan): Changed to return bool. (KJS::lessThanEq): Ditto. (KJS::LessNode::evaluate): Changed since lessThan returns bool. (KJS::LessNode::evaluateToBoolean): Added. (KJS::GreaterNode::evaluate): Changed since lessThanEq returns bool. (KJS::GreaterNode::evaluateToBoolean): Added. (KJS::LessEqNode::evaluate): Changed since lessThanEq returns bool. (KJS::LessEqNode::evaluateToBoolean): Added. (KJS::GreaterEqNode::evaluate): Changed since lessThan returns bool. (KJS::GreaterEqNode::evaluateToBoolean): Added. (KJS::InstanceOfNode::evaluateToBoolean): Added. (KJS::InNode::evaluateToBoolean): Added. (KJS::EqualNode::evaluateToBoolean): Added. (KJS::NotEqualNode::evaluateToBoolean): Added. (KJS::StrictEqualNode::evaluateToBoolean): Added. (KJS::NotStrictEqualNode::evaluateToBoolean): Added. (KJS::ConditionalNode::evaluate): Changed to call evaluateToBoolean. (KJS::IfNode::execute): Ditto. (KJS::DoWhileNode::execute): Ditto. (KJS::WhileNode::execute): Ditto. (KJS::ForNode::execute): Ditto.
  • kjs/nodes2string.cpp: (KJS::FalseNode::streamTo): Added. (KJS::TrueNode::streamTo): Added.
  • Property svn:eol-style set to native
File size: 21.0 KB
Line 
1/*
2 * Copyright (C) 2002 Harri Porten ([email protected])
3 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
4 * Copyright (C) 2007 Eric Seidel <[email protected]>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23#include "config.h"
24#include "nodes.h"
25
26#include <wtf/MathExtras.h>
27#include <wtf/StringExtras.h>
28#include <wtf/unicode/Unicode.h>
29
30using namespace WTF;
31using namespace Unicode;
32
33namespace KJS {
34
35// A simple text streaming class that helps with code indentation.
36
37enum EndlType { Endl };
38enum IndentType { Indent };
39enum UnindentType { Unindent };
40enum DotExprType { DotExpr };
41
42class SourceStream {
43public:
44 SourceStream() : m_numberNeedsParens(false), m_precedence(PrecExpression) { }
45 UString toString() const { return m_string; }
46 SourceStream& operator<<(const Identifier&);
47 SourceStream& operator<<(const UString&);
48 SourceStream& operator<<(const char*);
49 SourceStream& operator<<(double);
50 SourceStream& operator<<(char);
51 SourceStream& operator<<(EndlType);
52 SourceStream& operator<<(IndentType);
53 SourceStream& operator<<(UnindentType);
54 SourceStream& operator<<(DotExprType);
55 SourceStream& operator<<(Precedence);
56 SourceStream& operator<<(const Node*);
57 template <typename T> SourceStream& operator<<(const RefPtr<T>& n) { return *this << n.get(); }
58
59private:
60 UString m_string;
61 UString m_spacesForIndentation;
62 bool m_numberNeedsParens;
63 Precedence m_precedence;
64};
65
66// --------
67
68static UString escapeStringForPrettyPrinting(const UString& s)
69{
70 UString escapedString;
71
72 for (int i = 0; i < s.size(); i++) {
73 unsigned short c = s.data()[i].unicode();
74 switch (c) {
75 case '\"':
76 escapedString += "\\\"";
77 break;
78 case '\n':
79 escapedString += "\\n";
80 break;
81 case '\r':
82 escapedString += "\\r";
83 break;
84 case '\t':
85 escapedString += "\\t";
86 break;
87 case '\\':
88 escapedString += "\\\\";
89 break;
90 default:
91 if (c < 128 && isPrintableChar(c))
92 escapedString.append(c);
93 else {
94 char hexValue[7];
95 snprintf(hexValue, 7, "\\u%04x", c);
96 escapedString += hexValue;
97 }
98 }
99 }
100
101 return escapedString;
102}
103
104static const char* operatorString(Operator oper)
105{
106 switch (oper) {
107 case OpEqual:
108 return "=";
109 case OpMultEq:
110 return "*=";
111 case OpDivEq:
112 return "/=";
113 case OpPlusEq:
114 return "+=";
115 case OpMinusEq:
116 return "-=";
117 case OpLShift:
118 return "<<=";
119 case OpRShift:
120 return ">>=";
121 case OpURShift:
122 return ">>>=";
123 case OpAndEq:
124 return "&=";
125 case OpXOrEq:
126 return "^=";
127 case OpOrEq:
128 return "|=";
129 case OpModEq:
130 return "%=";
131 case OpPlusPlus:
132 return "++";
133 case OpMinusMinus:
134 return "--";
135 }
136 ASSERT_NOT_REACHED();
137 return "???";
138}
139
140static bool isParserRoundTripNumber(const UString& string)
141{
142 double number = string.toDouble(false, false);
143 if (isnan(number) || isinf(number))
144 return false;
145 return string == UString::from(number);
146}
147
148// --------
149
150SourceStream& SourceStream::operator<<(char c)
151{
152 m_numberNeedsParens = false;
153 UChar ch(c);
154 m_string.append(ch);
155 return *this;
156}
157
158SourceStream& SourceStream::operator<<(const char* s)
159{
160 m_numberNeedsParens = false;
161 m_string += s;
162 return *this;
163}
164
165SourceStream& SourceStream::operator<<(double value)
166{
167 bool needParens = m_numberNeedsParens;
168 m_numberNeedsParens = false;
169
170 if (needParens)
171 m_string.append('(');
172 m_string += UString::from(value);
173 if (needParens)
174 m_string.append(')');
175
176 return *this;
177}
178
179SourceStream& SourceStream::operator<<(const UString& s)
180{
181 m_numberNeedsParens = false;
182 m_string += s;
183 return *this;
184}
185
186SourceStream& SourceStream::operator<<(const Identifier& s)
187{
188 m_numberNeedsParens = false;
189 m_string += s.ustring();
190 return *this;
191}
192
193SourceStream& SourceStream::operator<<(const Node* n)
194{
195 bool needParens = m_precedence != PrecExpression && n->precedence() > m_precedence;
196 m_precedence = PrecExpression;
197 if (n) {
198 if (needParens)
199 m_string.append('(');
200 n->streamTo(*this);
201 if (needParens)
202 m_string.append(')');
203 }
204 return *this;
205}
206
207SourceStream& SourceStream::operator<<(EndlType)
208{
209 m_numberNeedsParens = false;
210 m_string.append('\n');
211 m_string.append(m_spacesForIndentation);
212 return *this;
213}
214
215SourceStream& SourceStream::operator<<(IndentType)
216{
217 m_numberNeedsParens = false;
218 m_spacesForIndentation += " ";
219 return *this;
220}
221
222SourceStream& SourceStream::operator<<(UnindentType)
223{
224 m_numberNeedsParens = false;
225 m_spacesForIndentation = m_spacesForIndentation.substr(0, m_spacesForIndentation.size() - 2);
226 return *this;
227}
228
229inline SourceStream& SourceStream::operator<<(DotExprType)
230{
231 m_numberNeedsParens = true;
232 return *this;
233}
234
235inline SourceStream& SourceStream::operator<<(Precedence precedence)
236{
237 m_precedence = precedence;
238 return *this;
239}
240
241static void streamLeftAssociativeBinaryOperator(SourceStream& s, Precedence precedence,
242 const char* operatorString, const Node* left, const Node* right)
243{
244 s << precedence << left
245 << ' ' << operatorString << ' '
246 << static_cast<Precedence>(precedence - 1) << right;
247}
248
249template <typename T> static inline void streamLeftAssociativeBinaryOperator(SourceStream& s,
250 Precedence p, const char* o, const RefPtr<T>& l, const RefPtr<T>& r)
251{
252 streamLeftAssociativeBinaryOperator(s, p, o, l.get(), r.get());
253}
254
255// --------
256
257UString Node::toString() const
258{
259 SourceStream stream;
260 streamTo(stream);
261 return stream.toString();
262}
263
264// --------
265
266void NullNode::streamTo(SourceStream& s) const
267{
268 s << "null";
269}
270
271void FalseNode::streamTo(SourceStream& s) const
272{
273 s << "false";
274}
275
276void TrueNode::streamTo(SourceStream& s) const
277{
278 s << "true";
279}
280
281void NumberNode::streamTo(SourceStream& s) const
282{
283 s << value();
284}
285
286void StringNode::streamTo(SourceStream& s) const
287{
288 s << '"' << escapeStringForPrettyPrinting(value) << '"';
289}
290
291void RegExpNode::streamTo(SourceStream& s) const
292{
293 s << '/' << pattern << '/' << flags;
294}
295
296void ThisNode::streamTo(SourceStream& s) const
297{
298 s << "this";
299}
300
301void ResolveNode::streamTo(SourceStream& s) const
302{
303 s << ident;
304}
305
306void ElementNode::streamTo(SourceStream& s) const
307{
308 for (const ElementNode* n = this; n; n = n->next.get()) {
309 for (int i = 0; i < n->elision; i++)
310 s << ',';
311 s << PrecAssignment << n->node;
312 if (n->next)
313 s << ',';
314 }
315}
316
317void ArrayNode::streamTo(SourceStream& s) const
318{
319 s << '[' << element;
320 for (int i = 0; i < elision; i++)
321 s << ',';
322 // Parser consumes one elision comma if there's array elements
323 // present in the expression.
324 if (opt && element)
325 s << ',';
326 s << ']';
327}
328
329void ObjectLiteralNode::streamTo(SourceStream& s) const
330{
331 if (list)
332 s << "{ " << list << " }";
333 else
334 s << "{ }";
335}
336
337void PropertyListNode::streamTo(SourceStream& s) const
338{
339 s << node;
340 for (const PropertyListNode* n = next.get(); n; n = n->next.get())
341 s << ", " << n->node;
342}
343
344void PropertyNode::streamTo(SourceStream& s) const
345{
346 switch (type) {
347 case Constant: {
348 UString propertyName = name().ustring();
349 if (isParserRoundTripNumber(propertyName))
350 s << propertyName;
351 else
352 s << '"' << escapeStringForPrettyPrinting(propertyName) << '"';
353 s << ": " << PrecAssignment << assign;
354 break;
355 }
356 case Getter:
357 case Setter: {
358 const FuncExprNode* func = static_cast<const FuncExprNode*>(assign.get());
359 if (type == Getter)
360 s << "get \"";
361 else
362 s << "set \"";
363 s << escapeStringForPrettyPrinting(name().ustring())
364 << "\"(" << func->param << ')' << func->body;
365 break;
366 }
367 }
368}
369
370void BracketAccessorNode::streamTo(SourceStream& s) const
371{
372 s << PrecCall << expr1 << "[" << expr2 << "]";
373}
374
375void DotAccessorNode::streamTo(SourceStream& s) const
376{
377 s << DotExpr << PrecCall << expr << "." << ident;
378}
379
380void ArgumentListNode::streamTo(SourceStream& s) const
381{
382 s << PrecAssignment << expr;
383 for (ArgumentListNode* n = next.get(); n; n = n->next.get())
384 s << ", " << PrecAssignment << n->expr;
385}
386
387void ArgumentsNode::streamTo(SourceStream& s) const
388{
389 s << '(' << listNode << ')';
390}
391
392void NewExprNode::streamTo(SourceStream& s) const
393{
394 s << "new " << PrecMember << expr << args;
395}
396
397void FunctionCallValueNode::streamTo(SourceStream& s) const
398{
399 s << PrecCall << expr << args;
400}
401
402void FunctionCallResolveNode::streamTo(SourceStream& s) const
403{
404 s << ident << args;
405}
406
407void FunctionCallBracketNode::streamTo(SourceStream& s) const
408{
409 s << PrecCall << base << "[" << subscript << "]" << args;
410}
411
412void FunctionCallDotNode::streamTo(SourceStream& s) const
413{
414 s << DotExpr << PrecCall << base << "." << ident << args;
415}
416
417void PostIncResolveNode::streamTo(SourceStream& s) const
418{
419 s << m_ident << "++";
420}
421
422void PostDecResolveNode::streamTo(SourceStream& s) const
423{
424 s << m_ident << "--";
425}
426
427void PostfixBracketNode::streamTo(SourceStream& s) const
428{
429 s << PrecCall << m_base << "[" << m_subscript << "]";
430 if (isIncrement())
431 s << "++";
432 else
433 s << "--";
434}
435
436void PostfixDotNode::streamTo(SourceStream& s) const
437{
438 s << DotExpr << PrecCall << m_base << "." << m_ident;
439 if (isIncrement())
440 s << "++";
441 else
442 s << "--";
443}
444
445void PostfixErrorNode::streamTo(SourceStream& s) const
446{
447 s << PrecLeftHandSide << m_expr;
448 if (m_oper == OpPlusPlus)
449 s << "++";
450 else
451 s << "--";
452}
453
454void DeleteResolveNode::streamTo(SourceStream& s) const
455{
456 s << "delete " << m_ident;
457}
458
459void DeleteBracketNode::streamTo(SourceStream& s) const
460{
461 s << "delete " << PrecCall << m_base << "[" << m_subscript << "]";
462}
463
464void DeleteDotNode::streamTo(SourceStream& s) const
465{
466 s << "delete " << DotExpr << PrecCall << m_base << "." << m_ident;
467}
468
469void DeleteValueNode::streamTo(SourceStream& s) const
470{
471 s << "delete " << PrecUnary << m_expr;
472}
473
474void VoidNode::streamTo(SourceStream& s) const
475{
476 s << "void " << PrecUnary << expr;
477}
478
479void TypeOfValueNode::streamTo(SourceStream& s) const
480{
481 s << "typeof " << PrecUnary << m_expr;
482}
483
484void TypeOfResolveNode::streamTo(SourceStream& s) const
485{
486 s << "typeof " << m_ident;
487}
488
489void PreIncResolveNode::streamTo(SourceStream& s) const
490{
491 s << "++" << m_ident;
492}
493
494void PreDecResolveNode::streamTo(SourceStream& s) const
495{
496 s << "--" << m_ident;
497}
498
499void PrefixBracketNode::streamTo(SourceStream& s) const
500{
501 if (isIncrement())
502 s << "++";
503 else
504 s << "--";
505 s << PrecCall << m_base << "[" << m_subscript << "]";
506}
507
508void PrefixDotNode::streamTo(SourceStream& s) const
509{
510 if (isIncrement())
511 s << "++";
512 else
513 s << "--";
514 s << DotExpr << PrecCall << m_base << "." << m_ident;
515}
516
517void PrefixErrorNode::streamTo(SourceStream& s) const
518{
519 if (m_oper == OpPlusPlus)
520 s << "++" << PrecUnary << m_expr;
521 else
522 s << "--" << PrecUnary << m_expr;
523}
524
525void UnaryPlusNode::streamTo(SourceStream& s) const
526{
527 s << "+ " << PrecUnary << expr;
528}
529
530void NegateNode::streamTo(SourceStream& s) const
531{
532 s << "- " << PrecUnary << expr;
533}
534
535void BitwiseNotNode::streamTo(SourceStream& s) const
536{
537 s << "~" << PrecUnary << expr;
538}
539
540void LogicalNotNode::streamTo(SourceStream& s) const
541{
542 s << "!" << PrecUnary << expr;
543}
544
545void MultNode::streamTo(SourceStream& s) const
546{
547 streamLeftAssociativeBinaryOperator(s, precedence(), "*", term1, term2);
548}
549
550void DivNode::streamTo(SourceStream& s) const
551{
552 streamLeftAssociativeBinaryOperator(s, precedence(), "/", term1, term2);
553}
554
555void ModNode::streamTo(SourceStream& s) const
556{
557 streamLeftAssociativeBinaryOperator(s, precedence(), "%", term1, term2);
558}
559
560void AddNode::streamTo(SourceStream& s) const
561{
562 streamLeftAssociativeBinaryOperator(s, precedence(), "+", term1, term2);
563}
564
565void SubNode::streamTo(SourceStream& s) const
566{
567 streamLeftAssociativeBinaryOperator(s, precedence(), "-", term1, term2);
568}
569
570void LeftShiftNode::streamTo(SourceStream& s) const
571{
572 streamLeftAssociativeBinaryOperator(s, precedence(), "<<", term1, term2);
573}
574
575void RightShiftNode::streamTo(SourceStream& s) const
576{
577 streamLeftAssociativeBinaryOperator(s, precedence(), ">>", term1, term2);
578}
579
580void UnsignedRightShiftNode::streamTo(SourceStream& s) const
581{
582 streamLeftAssociativeBinaryOperator(s, precedence(), ">>>", term1, term2);
583}
584
585void LessNode::streamTo(SourceStream& s) const
586{
587 streamLeftAssociativeBinaryOperator(s, precedence(), "<", expr1, expr2);
588}
589
590void GreaterNode::streamTo(SourceStream& s) const
591{
592 streamLeftAssociativeBinaryOperator(s, precedence(), ">", expr1, expr2);
593}
594
595void LessEqNode::streamTo(SourceStream& s) const
596{
597 streamLeftAssociativeBinaryOperator(s, precedence(), "<=", expr1, expr2);
598}
599
600void GreaterEqNode::streamTo(SourceStream& s) const
601{
602 streamLeftAssociativeBinaryOperator(s, precedence(), ">=", expr1, expr2);
603}
604
605void InstanceOfNode::streamTo(SourceStream& s) const
606{
607 streamLeftAssociativeBinaryOperator(s, precedence(), "instanceof", expr1, expr2);
608}
609
610void InNode::streamTo(SourceStream& s) const
611{
612 streamLeftAssociativeBinaryOperator(s, precedence(), "in", expr1, expr2);
613}
614
615void EqualNode::streamTo(SourceStream& s) const
616{
617 streamLeftAssociativeBinaryOperator(s, precedence(), "==", expr1, expr2);
618}
619
620void NotEqualNode::streamTo(SourceStream& s) const
621{
622 streamLeftAssociativeBinaryOperator(s, precedence(), "!=", expr1, expr2);
623}
624
625void StrictEqualNode::streamTo(SourceStream& s) const
626{
627 streamLeftAssociativeBinaryOperator(s, precedence(), "===", expr1, expr2);
628}
629
630void NotStrictEqualNode::streamTo(SourceStream& s) const
631{
632 streamLeftAssociativeBinaryOperator(s, precedence(), "!==", expr1, expr2);
633}
634
635void BitAndNode::streamTo(SourceStream& s) const
636{
637 streamLeftAssociativeBinaryOperator(s, precedence(), "&", expr1, expr2);
638}
639
640void BitXOrNode::streamTo(SourceStream& s) const
641{
642 streamLeftAssociativeBinaryOperator(s, precedence(), "^", expr1, expr2);
643}
644
645void BitOrNode::streamTo(SourceStream& s) const
646{
647 streamLeftAssociativeBinaryOperator(s, precedence(), "|", expr1, expr2);
648}
649
650void LogicalAndNode::streamTo(SourceStream& s) const
651{
652 streamLeftAssociativeBinaryOperator(s, precedence(), "&&", expr1, expr2);
653}
654
655void LogicalOrNode::streamTo(SourceStream& s) const
656{
657 streamLeftAssociativeBinaryOperator(s, precedence(), "||", expr1, expr2);
658}
659
660void ConditionalNode::streamTo(SourceStream& s) const
661{
662 s << PrecLogicalOr << logical
663 << " ? " << PrecAssignment << expr1
664 << " : " << PrecAssignment << expr2;
665}
666
667void ReadModifyResolveNode::streamTo(SourceStream& s) const
668{
669 s << m_ident << ' ' << operatorString(m_oper) << ' ' << PrecAssignment << m_right;
670}
671
672void AssignResolveNode::streamTo(SourceStream& s) const
673{
674 s << m_ident << " = " << PrecAssignment << m_right;
675}
676
677void ReadModifyBracketNode::streamTo(SourceStream& s) const
678{
679 s << PrecCall << m_base << '[' << m_subscript << "] "
680 << operatorString(m_oper) << ' ' << PrecAssignment << m_right;
681}
682
683void AssignBracketNode::streamTo(SourceStream& s) const
684{
685 s << PrecCall << m_base << '[' << m_subscript << "] = " << PrecAssignment << m_right;
686}
687
688void ReadModifyDotNode::streamTo(SourceStream& s) const
689{
690 s << DotExpr << PrecCall << m_base << "." << m_ident << ' '
691 << operatorString(m_oper) << ' ' << PrecAssignment << m_right;
692}
693
694void AssignDotNode::streamTo(SourceStream& s) const
695{
696 s << DotExpr << PrecCall << m_base << "." << m_ident << " = " << PrecAssignment << m_right;
697}
698
699void AssignErrorNode::streamTo(SourceStream& s) const
700{
701 s << PrecLeftHandSide << m_left << ' '
702 << operatorString(m_oper) << ' ' << PrecAssignment << m_right;
703}
704
705void CommaNode::streamTo(SourceStream& s) const
706{
707 s << PrecAssignment << expr1 << ", " << PrecAssignment << expr2;
708}
709
710void AssignExprNode::streamTo(SourceStream& s) const
711{
712 s << " = " << PrecAssignment << expr;
713}
714
715void VarDeclNode::streamTo(SourceStream& s) const
716{
717 s << "var " << ident << init;
718 for (VarDeclNode* n = next.get(); n; n = n->next.get())
719 s << ", " << ident << init;
720}
721
722void VarStatementNode::streamTo(SourceStream& s) const
723{
724 s << Endl << next << ';';
725}
726
727static inline void statementListStreamTo(Vector<RefPtr<StatementNode> >* nodes, SourceStream& s)
728{
729 if (!nodes)
730 return;
731
732 for (Vector<RefPtr<StatementNode> >::iterator ptr = nodes->begin(); ptr != nodes->end(); ptr++)
733 s << *ptr;
734}
735
736void BlockNode::streamTo(SourceStream& s) const
737{
738 s << Endl << "{" << Indent;
739 statementListStreamTo(m_children.get(), s);
740 s << Unindent << Endl << "}";
741}
742
743void EmptyStatementNode::streamTo(SourceStream& s) const
744{
745 s << Endl << ';';
746}
747
748void ExprStatementNode::streamTo(SourceStream& s) const
749{
750 s << Endl << expr << ';';
751}
752
753void IfNode::streamTo(SourceStream& s) const
754{
755 s << Endl << "if (" << expr << ')' << Indent << statement1 << Unindent;
756 if (statement2)
757 s << Endl << "else" << Indent << statement2 << Unindent;
758}
759
760void DoWhileNode::streamTo(SourceStream& s) const
761{
762 s << Endl << "do " << Indent << statement << Unindent << Endl
763 << "while (" << expr << ");";
764}
765
766void WhileNode::streamTo(SourceStream& s) const
767{
768 s << Endl << "while (" << expr << ')' << Indent << statement << Unindent;
769}
770
771void ForNode::streamTo(SourceStream& s) const
772{
773 s << Endl << "for ("
774 << expr1
775 << "; " << expr2
776 << "; " << expr3
777 << ')' << Indent << statement << Unindent;
778}
779
780void ForInNode::streamTo(SourceStream& s) const
781{
782 s << Endl << "for (";
783 if (varDecl)
784 s << varDecl;
785 else
786 s << PrecLeftHandSide << lexpr;
787
788 s << " in " << expr << ')' << Indent << statement << Unindent;
789}
790
791void ContinueNode::streamTo(SourceStream& s) const
792{
793 s << Endl << "continue";
794 if (!ident.isNull())
795 s << ' ' << ident;
796 s << ';';
797}
798
799void BreakNode::streamTo(SourceStream& s) const
800{
801 s << Endl << "break";
802 if (!ident.isNull())
803 s << ' ' << ident;
804 s << ';';
805}
806
807void ReturnNode::streamTo(SourceStream& s) const
808{
809 s << Endl << "return";
810 if (value)
811 s << ' ' << value;
812 s << ';';
813}
814
815void WithNode::streamTo(SourceStream& s) const
816{
817 s << Endl << "with (" << expr << ") " << statement;
818}
819
820void CaseClauseNode::streamTo(SourceStream& s) const
821{
822 s << Endl;
823 if (expr)
824 s << "case " << expr;
825 else
826 s << "default";
827 s << ":" << Indent;
828 statementListStreamTo(m_children.get(), s);
829 s << Unindent;
830}
831
832void ClauseListNode::streamTo(SourceStream& s) const
833{
834 for (const ClauseListNode* n = this; n; n = n->getNext())
835 s << n->getClause();
836}
837
838void CaseBlockNode::streamTo(SourceStream& s) const
839{
840 for (const ClauseListNode* n = list1.get(); n; n = n->getNext())
841 s << n->getClause();
842 s << def;
843 for (const ClauseListNode* n = list2.get(); n; n = n->getNext())
844 s << n->getClause();
845}
846
847void SwitchNode::streamTo(SourceStream& s) const
848{
849 s << Endl << "switch (" << expr << ") {"
850 << Indent << block << Unindent
851 << Endl << "}";
852}
853
854void LabelNode::streamTo(SourceStream& s) const
855{
856 s << Endl << label << ":" << Indent << statement << Unindent;
857}
858
859void ThrowNode::streamTo(SourceStream& s) const
860{
861 s << Endl << "throw " << expr << ';';
862}
863
864void TryNode::streamTo(SourceStream& s) const
865{
866 s << Endl << "try " << tryBlock;
867 if (catchBlock)
868 s << Endl << "catch (" << exceptionIdent << ')' << catchBlock;
869 if (finallyBlock)
870 s << Endl << "finally " << finallyBlock;
871}
872
873void ParameterNode::streamTo(SourceStream& s) const
874{
875 s << id;
876 for (ParameterNode* n = next.get(); n; n = n->next.get())
877 s << ", " << n->id;
878}
879
880void FuncDeclNode::streamTo(SourceStream& s) const
881{
882 s << Endl << "function " << ident << '(' << param << ')' << body;
883}
884
885void FuncExprNode::streamTo(SourceStream& s) const
886{
887 s << "function " << ident << '(' << param << ')' << body;
888}
889
890}
Note: See TracBrowser for help on using the repository browser.