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

Last change on this file since 29809 was 29809, checked in by [email protected], 17 years ago

Reviewed by Mark Rowe.

Cleanup node2string a little.

  • Remove some unnecessary branching.
  • Factor out bracket and dot streaming into static inline functions.
  • kjs/nodes.h:
  • kjs/nodes2string.cpp: (KJS::bracketNodeStreamTo): (KJS::dotNodeStreamTo): (KJS::FunctionCallBracketNode::streamTo): (KJS::FunctionCallDotNode::streamTo): (KJS::PostIncBracketNode::streamTo): (KJS::PostDecBracketNode::streamTo): (KJS::PostIncDotNode::streamTo): (KJS::PostDecDotNode::streamTo): (KJS::DeleteBracketNode::streamTo): (KJS::DeleteDotNode::streamTo): (KJS::PreIncBracketNode::streamTo): (KJS::PreDecBracketNode::streamTo): (KJS::PreIncDotNode::streamTo): (KJS::PreDecDotNode::streamTo): (KJS::ReadModifyBracketNode::streamTo): (KJS::AssignBracketNode::streamTo): (KJS::ReadModifyDotNode::streamTo): (KJS::AssignDotNode::streamTo): (KJS::WhileNode::streamTo):
  • Property svn:eol-style set to native
File size: 22.8 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_atStartOfStatement(true), 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 bool m_atStartOfStatement;
64 Precedence m_precedence;
65};
66
67// --------
68
69static UString escapeStringForPrettyPrinting(const UString& s)
70{
71 UString escapedString;
72
73 for (int i = 0; i < s.size(); i++) {
74 unsigned short c = s.data()[i].unicode();
75 switch (c) {
76 case '\"':
77 escapedString += "\\\"";
78 break;
79 case '\n':
80 escapedString += "\\n";
81 break;
82 case '\r':
83 escapedString += "\\r";
84 break;
85 case '\t':
86 escapedString += "\\t";
87 break;
88 case '\\':
89 escapedString += "\\\\";
90 break;
91 default:
92 if (c < 128 && isPrintableChar(c))
93 escapedString.append(c);
94 else {
95 char hexValue[7];
96 snprintf(hexValue, 7, "\\u%04x", c);
97 escapedString += hexValue;
98 }
99 }
100 }
101
102 return escapedString;
103}
104
105static const char* operatorString(Operator oper)
106{
107 switch (oper) {
108 case OpEqual:
109 return "=";
110 case OpMultEq:
111 return "*=";
112 case OpDivEq:
113 return "/=";
114 case OpPlusEq:
115 return "+=";
116 case OpMinusEq:
117 return "-=";
118 case OpLShift:
119 return "<<=";
120 case OpRShift:
121 return ">>=";
122 case OpURShift:
123 return ">>>=";
124 case OpAndEq:
125 return "&=";
126 case OpXOrEq:
127 return "^=";
128 case OpOrEq:
129 return "|=";
130 case OpModEq:
131 return "%=";
132 case OpPlusPlus:
133 return "++";
134 case OpMinusMinus:
135 return "--";
136 }
137 ASSERT_NOT_REACHED();
138 return "???";
139}
140
141static bool isParserRoundTripNumber(const UString& string)
142{
143 double number = string.toDouble(false, false);
144 if (isnan(number) || isinf(number))
145 return false;
146 return string == UString::from(number);
147}
148
149// --------
150
151SourceStream& SourceStream::operator<<(char c)
152{
153 m_numberNeedsParens = false;
154 m_atStartOfStatement = false;
155 UChar ch(c);
156 m_string.append(ch);
157 return *this;
158}
159
160SourceStream& SourceStream::operator<<(const char* s)
161{
162 m_numberNeedsParens = false;
163 m_atStartOfStatement = false;
164 m_string += s;
165 return *this;
166}
167
168SourceStream& SourceStream::operator<<(double value)
169{
170 bool needParens = m_numberNeedsParens;
171 m_numberNeedsParens = false;
172 m_atStartOfStatement = false;
173
174 if (needParens)
175 m_string.append('(');
176 m_string += UString::from(value);
177 if (needParens)
178 m_string.append(')');
179
180 return *this;
181}
182
183SourceStream& SourceStream::operator<<(const UString& s)
184{
185 m_numberNeedsParens = false;
186 m_atStartOfStatement = false;
187 m_string += s;
188 return *this;
189}
190
191SourceStream& SourceStream::operator<<(const Identifier& s)
192{
193 m_numberNeedsParens = false;
194 m_atStartOfStatement = false;
195 m_string += s.ustring();
196 return *this;
197}
198
199SourceStream& SourceStream::operator<<(const Node* n)
200{
201 bool needParens = (m_precedence != PrecExpression && n->precedence() > m_precedence) || (m_atStartOfStatement && n->needsParensIfLeftmost());
202 m_precedence = PrecExpression;
203 if (n) {
204 if (needParens)
205 m_string.append('(');
206 n->streamTo(*this);
207 if (needParens)
208 m_string.append(')');
209 }
210 return *this;
211}
212
213SourceStream& SourceStream::operator<<(EndlType)
214{
215 m_numberNeedsParens = false;
216 m_atStartOfStatement = true;
217 m_string.append('\n');
218 m_string.append(m_spacesForIndentation);
219 return *this;
220}
221
222SourceStream& SourceStream::operator<<(IndentType)
223{
224 m_numberNeedsParens = false;
225 m_atStartOfStatement = false;
226 m_spacesForIndentation += " ";
227 return *this;
228}
229
230SourceStream& SourceStream::operator<<(UnindentType)
231{
232 m_numberNeedsParens = false;
233 m_atStartOfStatement = false;
234 m_spacesForIndentation = m_spacesForIndentation.substr(0, m_spacesForIndentation.size() - 2);
235 return *this;
236}
237
238inline SourceStream& SourceStream::operator<<(DotExprType)
239{
240 m_numberNeedsParens = true;
241 return *this;
242}
243
244inline SourceStream& SourceStream::operator<<(Precedence precedence)
245{
246 m_precedence = precedence;
247 return *this;
248}
249
250static void streamLeftAssociativeBinaryOperator(SourceStream& s, Precedence precedence,
251 const char* operatorString, const Node* left, const Node* right)
252{
253 s << precedence << left
254 << ' ' << operatorString << ' '
255 << static_cast<Precedence>(precedence - 1) << right;
256}
257
258template <typename T> static inline void streamLeftAssociativeBinaryOperator(SourceStream& s,
259 Precedence p, const char* o, const RefPtr<T>& l, const RefPtr<T>& r)
260{
261 streamLeftAssociativeBinaryOperator(s, p, o, l.get(), r.get());
262}
263
264static inline void bracketNodeStreamTo(SourceStream& s, const RefPtr<ExpressionNode>& base, const RefPtr<ExpressionNode>& subscript)
265{
266 s << PrecCall << base.get() << "[" << subscript.get() << "]";
267}
268
269static inline void dotNodeStreamTo(SourceStream& s, const RefPtr<ExpressionNode>& base, const Identifier& ident)
270{
271 s << DotExpr << PrecCall << base.get() << "." << ident;
272}
273
274// --------
275
276UString Node::toString() const
277{
278 SourceStream stream;
279 streamTo(stream);
280 return stream.toString();
281}
282
283// --------
284
285void NullNode::streamTo(SourceStream& s) const
286{
287 s << "null";
288}
289
290void FalseNode::streamTo(SourceStream& s) const
291{
292 s << "false";
293}
294
295void TrueNode::streamTo(SourceStream& s) const
296{
297 s << "true";
298}
299
300void PlaceholderTrueNode::streamTo(SourceStream&) const
301{
302}
303
304void NumberNode::streamTo(SourceStream& s) const
305{
306 s << value();
307}
308
309void StringNode::streamTo(SourceStream& s) const
310{
311 s << '"' << escapeStringForPrettyPrinting(m_value) << '"';
312}
313
314void RegExpNode::streamTo(SourceStream& s) const
315{
316 s << '/' << m_regExp->pattern() << '/' << m_regExp->flags();
317}
318
319void ThisNode::streamTo(SourceStream& s) const
320{
321 s << "this";
322}
323
324void ResolveNode::streamTo(SourceStream& s) const
325{
326 s << ident;
327}
328
329void ElementNode::streamTo(SourceStream& s) const
330{
331 for (const ElementNode* n = this; n; n = n->next.get()) {
332 for (int i = 0; i < n->elision; i++)
333 s << ',';
334 s << PrecAssignment << n->node;
335 if (n->next)
336 s << ',';
337 }
338}
339
340void ArrayNode::streamTo(SourceStream& s) const
341{
342 s << '[' << element;
343 for (int i = 0; i < elision; i++)
344 s << ',';
345 // Parser consumes one elision comma if there's array elements
346 // present in the expression.
347 if (opt && element)
348 s << ',';
349 s << ']';
350}
351
352void ObjectLiteralNode::streamTo(SourceStream& s) const
353{
354 if (list)
355 s << "{ " << list << " }";
356 else
357 s << "{ }";
358}
359
360void PropertyListNode::streamTo(SourceStream& s) const
361{
362 s << node;
363 for (const PropertyListNode* n = next.get(); n; n = n->next.get())
364 s << ", " << n->node;
365}
366
367void PropertyNode::streamTo(SourceStream& s) const
368{
369 switch (type) {
370 case Constant: {
371 UString propertyName = name().ustring();
372 if (isParserRoundTripNumber(propertyName))
373 s << propertyName;
374 else
375 s << '"' << escapeStringForPrettyPrinting(propertyName) << '"';
376 s << ": " << PrecAssignment << assign;
377 break;
378 }
379 case Getter:
380 case Setter: {
381 const FuncExprNode* func = static_cast<const FuncExprNode*>(assign.get());
382 if (type == Getter)
383 s << "get \"";
384 else
385 s << "set \"";
386 s << escapeStringForPrettyPrinting(name().ustring())
387 << "\"(" << func->param << ')' << func->body;
388 break;
389 }
390 }
391}
392
393void BracketAccessorNode::streamTo(SourceStream& s) const
394{
395 s << PrecCall << expr1 << "[" << expr2 << "]";
396}
397
398void DotAccessorNode::streamTo(SourceStream& s) const
399{
400 s << DotExpr << PrecCall << expr << "." << ident;
401}
402
403void ArgumentListNode::streamTo(SourceStream& s) const
404{
405 s << PrecAssignment << expr;
406 for (ArgumentListNode* n = next.get(); n; n = n->next.get())
407 s << ", " << PrecAssignment << n->expr;
408}
409
410void ArgumentsNode::streamTo(SourceStream& s) const
411{
412 s << '(' << listNode << ')';
413}
414
415void NewExprNode::streamTo(SourceStream& s) const
416{
417 s << "new " << PrecMember << expr << args;
418}
419
420void FunctionCallValueNode::streamTo(SourceStream& s) const
421{
422 s << PrecCall << expr << args;
423}
424
425void FunctionCallResolveNode::streamTo(SourceStream& s) const
426{
427 s << ident << args;
428}
429
430void FunctionCallBracketNode::streamTo(SourceStream& s) const
431{
432 bracketNodeStreamTo(s, base, subscript);
433 s << args;
434}
435
436void FunctionCallDotNode::streamTo(SourceStream& s) const
437{
438 dotNodeStreamTo(s, base, ident);
439 s << args;
440}
441
442void PostIncResolveNode::streamTo(SourceStream& s) const
443{
444 s << m_ident << "++";
445}
446
447void PostDecResolveNode::streamTo(SourceStream& s) const
448{
449 s << m_ident << "--";
450}
451
452void PostIncBracketNode::streamTo(SourceStream& s) const
453{
454 bracketNodeStreamTo(s, m_base, m_subscript);
455 s << "++";
456}
457
458void PostDecBracketNode::streamTo(SourceStream& s) const
459{
460 bracketNodeStreamTo(s, m_base, m_subscript);
461 s << "--";
462}
463
464void PostIncDotNode::streamTo(SourceStream& s) const
465{
466 dotNodeStreamTo(s, m_base, m_ident);
467 s << "++";
468}
469
470void PostDecDotNode::streamTo(SourceStream& s) const
471{
472 dotNodeStreamTo(s, m_base, m_ident);
473 s << "--";
474}
475
476void PostfixErrorNode::streamTo(SourceStream& s) const
477{
478 s << PrecLeftHandSide << m_expr;
479 if (m_oper == OpPlusPlus)
480 s << "++";
481 else
482 s << "--";
483}
484
485void DeleteResolveNode::streamTo(SourceStream& s) const
486{
487 s << "delete " << m_ident;
488}
489
490void DeleteBracketNode::streamTo(SourceStream& s) const
491{
492 s << "delete ";
493 bracketNodeStreamTo(s, m_base, m_subscript);
494}
495
496void DeleteDotNode::streamTo(SourceStream& s) const
497{
498 s << "delete ";
499 dotNodeStreamTo(s, m_base, m_ident);
500}
501
502void DeleteValueNode::streamTo(SourceStream& s) const
503{
504 s << "delete " << PrecUnary << m_expr;
505}
506
507void VoidNode::streamTo(SourceStream& s) const
508{
509 s << "void " << PrecUnary << expr;
510}
511
512void TypeOfValueNode::streamTo(SourceStream& s) const
513{
514 s << "typeof " << PrecUnary << m_expr;
515}
516
517void TypeOfResolveNode::streamTo(SourceStream& s) const
518{
519 s << "typeof " << m_ident;
520}
521
522void PreIncResolveNode::streamTo(SourceStream& s) const
523{
524 s << "++" << m_ident;
525}
526
527void PreDecResolveNode::streamTo(SourceStream& s) const
528{
529 s << "--" << m_ident;
530}
531
532void PreIncBracketNode::streamTo(SourceStream& s) const
533{
534 s << "++";
535 bracketNodeStreamTo(s, m_base, m_subscript);
536}
537
538void PreDecBracketNode::streamTo(SourceStream& s) const
539{
540 s << "--";
541 bracketNodeStreamTo(s, m_base, m_subscript);
542}
543
544void PreIncDotNode::streamTo(SourceStream& s) const
545{
546 s << "++";
547 dotNodeStreamTo(s, m_base, m_ident);
548}
549
550void PreDecDotNode::streamTo(SourceStream& s) const
551{
552 s << "--";
553 dotNodeStreamTo(s, m_base, m_ident);
554}
555
556void PrefixErrorNode::streamTo(SourceStream& s) const
557{
558 if (m_oper == OpPlusPlus)
559 s << "++" << PrecUnary << m_expr;
560 else
561 s << "--" << PrecUnary << m_expr;
562}
563
564void UnaryPlusNode::streamTo(SourceStream& s) const
565{
566 s << "+ " << PrecUnary << m_expr;
567}
568
569void NegateNode::streamTo(SourceStream& s) const
570{
571 s << "- " << PrecUnary << expr;
572}
573
574void BitwiseNotNode::streamTo(SourceStream& s) const
575{
576 s << "~" << PrecUnary << expr;
577}
578
579void LogicalNotNode::streamTo(SourceStream& s) const
580{
581 s << "!" << PrecUnary << expr;
582}
583
584void MultNode::streamTo(SourceStream& s) const
585{
586 streamLeftAssociativeBinaryOperator(s, precedence(), "*", term1, term2);
587}
588
589void DivNode::streamTo(SourceStream& s) const
590{
591 streamLeftAssociativeBinaryOperator(s, precedence(), "/", term1, term2);
592}
593
594void ModNode::streamTo(SourceStream& s) const
595{
596 streamLeftAssociativeBinaryOperator(s, precedence(), "%", term1, term2);
597}
598
599void AddNode::streamTo(SourceStream& s) const
600{
601 streamLeftAssociativeBinaryOperator(s, precedence(), "+", term1, term2);
602}
603
604void SubNode::streamTo(SourceStream& s) const
605{
606 streamLeftAssociativeBinaryOperator(s, precedence(), "-", term1, term2);
607}
608
609void LeftShiftNode::streamTo(SourceStream& s) const
610{
611 streamLeftAssociativeBinaryOperator(s, precedence(), "<<", term1, term2);
612}
613
614void RightShiftNode::streamTo(SourceStream& s) const
615{
616 streamLeftAssociativeBinaryOperator(s, precedence(), ">>", term1, term2);
617}
618
619void UnsignedRightShiftNode::streamTo(SourceStream& s) const
620{
621 streamLeftAssociativeBinaryOperator(s, precedence(), ">>>", term1, term2);
622}
623
624void LessNode::streamTo(SourceStream& s) const
625{
626 streamLeftAssociativeBinaryOperator(s, precedence(), "<", expr1, expr2);
627}
628
629void GreaterNode::streamTo(SourceStream& s) const
630{
631 streamLeftAssociativeBinaryOperator(s, precedence(), ">", expr1, expr2);
632}
633
634void LessEqNode::streamTo(SourceStream& s) const
635{
636 streamLeftAssociativeBinaryOperator(s, precedence(), "<=", expr1, expr2);
637}
638
639void GreaterEqNode::streamTo(SourceStream& s) const
640{
641 streamLeftAssociativeBinaryOperator(s, precedence(), ">=", expr1, expr2);
642}
643
644void InstanceOfNode::streamTo(SourceStream& s) const
645{
646 streamLeftAssociativeBinaryOperator(s, precedence(), "instanceof", expr1, expr2);
647}
648
649void InNode::streamTo(SourceStream& s) const
650{
651 streamLeftAssociativeBinaryOperator(s, precedence(), "in", expr1, expr2);
652}
653
654void EqualNode::streamTo(SourceStream& s) const
655{
656 streamLeftAssociativeBinaryOperator(s, precedence(), "==", expr1, expr2);
657}
658
659void NotEqualNode::streamTo(SourceStream& s) const
660{
661 streamLeftAssociativeBinaryOperator(s, precedence(), "!=", expr1, expr2);
662}
663
664void StrictEqualNode::streamTo(SourceStream& s) const
665{
666 streamLeftAssociativeBinaryOperator(s, precedence(), "===", expr1, expr2);
667}
668
669void NotStrictEqualNode::streamTo(SourceStream& s) const
670{
671 streamLeftAssociativeBinaryOperator(s, precedence(), "!==", expr1, expr2);
672}
673
674void BitAndNode::streamTo(SourceStream& s) const
675{
676 streamLeftAssociativeBinaryOperator(s, precedence(), "&", expr1, expr2);
677}
678
679void BitXOrNode::streamTo(SourceStream& s) const
680{
681 streamLeftAssociativeBinaryOperator(s, precedence(), "^", expr1, expr2);
682}
683
684void BitOrNode::streamTo(SourceStream& s) const
685{
686 streamLeftAssociativeBinaryOperator(s, precedence(), "|", expr1, expr2);
687}
688
689void LogicalAndNode::streamTo(SourceStream& s) const
690{
691 streamLeftAssociativeBinaryOperator(s, precedence(), "&&", expr1, expr2);
692}
693
694void LogicalOrNode::streamTo(SourceStream& s) const
695{
696 streamLeftAssociativeBinaryOperator(s, precedence(), "||", expr1, expr2);
697}
698
699void ConditionalNode::streamTo(SourceStream& s) const
700{
701 s << PrecLogicalOr << logical
702 << " ? " << PrecAssignment << expr1
703 << " : " << PrecAssignment << expr2;
704}
705
706void ReadModifyResolveNode::streamTo(SourceStream& s) const
707{
708 s << m_ident << ' ' << operatorString(m_oper) << ' ' << PrecAssignment << m_right;
709}
710
711void AssignResolveNode::streamTo(SourceStream& s) const
712{
713 s << m_ident << " = " << PrecAssignment << m_right;
714}
715
716void ReadModifyBracketNode::streamTo(SourceStream& s) const
717{
718 bracketNodeStreamTo(s, m_base, m_subscript);
719 s << ' ' << operatorString(m_oper) << ' ' << PrecAssignment << m_right;
720}
721
722void AssignBracketNode::streamTo(SourceStream& s) const
723{
724 bracketNodeStreamTo(s, m_base, m_subscript);
725 s << " = " << PrecAssignment << m_right;
726}
727
728void ReadModifyDotNode::streamTo(SourceStream& s) const
729{
730 dotNodeStreamTo(s, m_base, m_ident);
731 s << ' ' << operatorString(m_oper) << ' ' << PrecAssignment << m_right;
732}
733
734void AssignDotNode::streamTo(SourceStream& s) const
735{
736 dotNodeStreamTo(s, m_base, m_ident);
737 s << " = " << PrecAssignment << m_right;
738}
739
740void AssignErrorNode::streamTo(SourceStream& s) const
741{
742 s << PrecLeftHandSide << m_left << ' '
743 << operatorString(m_oper) << ' ' << PrecAssignment << m_right;
744}
745
746void CommaNode::streamTo(SourceStream& s) const
747{
748 s << PrecAssignment << expr1 << ", " << PrecAssignment << expr2;
749}
750
751void ConstDeclNode::streamTo(SourceStream& s) const
752{
753 s << ident;
754 if (init)
755 s << " = " << init;
756 for (ConstDeclNode* n = next.get(); n; n = n->next.get()) {
757 s << ", " << ident;
758 if (init)
759 s << " = " << init;
760 }
761}
762
763void ConstStatementNode::streamTo(SourceStream& s) const
764{
765 s << Endl << "const " << next << ';';
766}
767
768static inline void statementListStreamTo(const Vector<RefPtr<StatementNode> >& nodes, SourceStream& s)
769{
770 for (Vector<RefPtr<StatementNode> >::const_iterator ptr = nodes.begin(); ptr != nodes.end(); ptr++)
771 s << *ptr;
772}
773
774void BlockNode::streamTo(SourceStream& s) const
775{
776 s << Endl << "{" << Indent;
777 statementListStreamTo(m_children, s);
778 s << Unindent << Endl << "}";
779}
780
781void ScopeNode::streamTo(SourceStream& s) const
782{
783 s << Endl << "{" << Indent;
784
785 bool printedVar = false;
786 for (size_t i = 0; i < m_varStack.size(); ++i) {
787 if (m_varStack[i].second == 0) {
788 if (!printedVar) {
789 s << Endl << "var ";
790 printedVar = true;
791 } else
792 s << ", ";
793 s << m_varStack[i].first;
794 }
795 }
796 if (printedVar)
797 s << ';';
798
799 statementListStreamTo(m_children, s);
800 s << Unindent << Endl << "}";
801}
802
803void EmptyStatementNode::streamTo(SourceStream& s) const
804{
805 s << Endl << ';';
806}
807
808void ExprStatementNode::streamTo(SourceStream& s) const
809{
810 s << Endl << expr << ';';
811}
812
813void VarStatementNode::streamTo(SourceStream& s) const
814{
815 s << Endl << "var " << expr << ';';
816}
817
818void IfNode::streamTo(SourceStream& s) const
819{
820 s << Endl << "if (" << m_condition << ')' << Indent << m_ifBlock << Unindent;
821}
822
823void IfElseNode::streamTo(SourceStream& s) const
824{
825 IfNode::streamTo(s);
826 s << Endl << "else" << Indent << m_elseBlock << Unindent;
827}
828
829void DoWhileNode::streamTo(SourceStream& s) const
830{
831 s << Endl << "do " << Indent << statement << Unindent << Endl
832 << "while (" << expr << ");";
833}
834
835void WhileNode::streamTo(SourceStream& s) const
836{
837 s << Endl << "while (" << expr << ')' << Indent << statement << Unindent;
838}
839
840void ForNode::streamTo(SourceStream& s) const
841{
842 s << Endl << "for ("
843 << (expr1WasVarDecl ? "var " : "")
844 << expr1
845 << "; " << expr2
846 << "; " << expr3
847 << ')' << Indent << statement << Unindent;
848}
849
850void ForInNode::streamTo(SourceStream& s) const
851{
852 s << Endl << "for (";
853 if (identIsVarDecl) {
854 s << "var ";
855 if (init)
856 s << init;
857 else
858 s << PrecLeftHandSide << lexpr;
859 } else
860 s << PrecLeftHandSide << lexpr;
861
862 s << " in " << expr << ')' << Indent << statement << Unindent;
863}
864
865void ContinueNode::streamTo(SourceStream& s) const
866{
867 s << Endl << "continue";
868 if (!ident.isNull())
869 s << ' ' << ident;
870 s << ';';
871}
872
873void BreakNode::streamTo(SourceStream& s) const
874{
875 s << Endl << "break";
876 if (!ident.isNull())
877 s << ' ' << ident;
878 s << ';';
879}
880
881void ReturnNode::streamTo(SourceStream& s) const
882{
883 s << Endl << "return";
884 if (value)
885 s << ' ' << value;
886 s << ';';
887}
888
889void WithNode::streamTo(SourceStream& s) const
890{
891 s << Endl << "with (" << expr << ") " << statement;
892}
893
894void CaseClauseNode::streamTo(SourceStream& s) const
895{
896 s << Endl;
897 if (expr)
898 s << "case " << expr;
899 else
900 s << "default";
901 s << ":" << Indent;
902 statementListStreamTo(m_children, s);
903 s << Unindent;
904}
905
906void ClauseListNode::streamTo(SourceStream& s) const
907{
908 for (const ClauseListNode* n = this; n; n = n->getNext())
909 s << n->getClause();
910}
911
912void CaseBlockNode::streamTo(SourceStream& s) const
913{
914 for (const ClauseListNode* n = list1.get(); n; n = n->getNext())
915 s << n->getClause();
916 s << def;
917 for (const ClauseListNode* n = list2.get(); n; n = n->getNext())
918 s << n->getClause();
919}
920
921void SwitchNode::streamTo(SourceStream& s) const
922{
923 s << Endl << "switch (" << expr << ") {"
924 << Indent << block << Unindent
925 << Endl << "}";
926}
927
928void LabelNode::streamTo(SourceStream& s) const
929{
930 s << Endl << label << ":" << Indent << statement << Unindent;
931}
932
933void ThrowNode::streamTo(SourceStream& s) const
934{
935 s << Endl << "throw " << expr << ';';
936}
937
938void TryNode::streamTo(SourceStream& s) const
939{
940 s << Endl << "try " << tryBlock;
941 if (catchBlock)
942 s << Endl << "catch (" << exceptionIdent << ')' << catchBlock;
943 if (finallyBlock)
944 s << Endl << "finally " << finallyBlock;
945}
946
947void ParameterNode::streamTo(SourceStream& s) const
948{
949 s << id;
950 for (ParameterNode* n = next.get(); n; n = n->next.get())
951 s << ", " << n->id;
952}
953
954void FuncDeclNode::streamTo(SourceStream& s) const
955{
956 s << Endl << "function " << ident << '(' << param << ')' << body;
957}
958
959void FuncExprNode::streamTo(SourceStream& s) const
960{
961 s << "function " << ident << '(' << param << ')' << body;
962}
963
964} // namespace KJS
Note: See TracBrowser for help on using the repository browser.