# kjs Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# nodes2string.cpp

    00001 // -*- c-basic-offset: 2 -*-
    00002 /*
    00003  *  This file is part of the KDE libraries
    00004  *  Copyright (C) 2002 Harri Porten (porten@kde.org)
    00005  *  Copyright (C) 2003 Apple Computer, Inc.
    00006  *
    00007  *  This library is free software; you can redistribute it and/or
    00008  *  modify it under the terms of the GNU Library General Public
    00009  *  License as published by the Free Software Foundation; either
    00010  *  version 2 of the License, or (at your option) any later version.
    00011  *
    00012  *  This library is distributed in the hope that it will be useful,
    00013  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    00014  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00015  *  Library General Public License for more details.
    00016  *
    00017  *  You should have received a copy of the GNU Library General Public License
    00018  *  along with this library; see the file COPYING.LIB.  If not, write to
    00019  *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    00020  *  Boston, MA 02111-1307, USA.
    00021  *
    00022  */
    00023
    00024 #include "nodes.h"
    00025
    00026 namespace KJS {
    00030   class SourceStream {
    00031   public:
    00032     enum Format {
    00033       Endl, Indent, Unindent
    00034     };
    00035
    00036     UString toString() const { return str; }
    00037     SourceStream& operator<<(const Identifier &);
    00038     SourceStream& operator<<(const KJS::UString &);
    00039     SourceStream& operator<<(const char *);
    00040     SourceStream& operator<<(char);
    00041     SourceStream& operator<<(Format f);
    00042     SourceStream& operator<<(const Node *);
    00043   private:
    00044     UString str; /* TODO: buffer */
    00045     UString ind;
    00046   };
    00047 }
    00048
    00049 using namespace KJS;
    00050
    00051 SourceStream& SourceStream::operator<<(char c)
    00052 {
    00053   str += UString(c);
    00054   return *this;
    00055 }
    00056
    00057 SourceStream& SourceStream::operator<<(const char *s)
    00058 {
    00059   str += UString(s);
    00060   return *this;
    00061 }
    00062
    00063 SourceStream& SourceStream::operator<<(const UString &s)
    00064 {
    00065   str += s;
    00066   return *this;
    00067 }
    00068
    00069 SourceStream& SourceStream::operator<<(const Identifier &s)
    00070 {
    00071   str += s.ustring();
    00072   return *this;
    00073 }
    00074
    00075 SourceStream& SourceStream::operator<<(const Node *n)
    00076 {
    00077   if (n)
    00078     n->streamTo(*this);
    00079   return *this;
    00080 }
    00081
    00082 SourceStream& SourceStream::operator<<(Format f)
    00083 {
    00084   switch (f) {
    00085     case Endl:
    00086       str += "\n" + ind;
    00087       break;
    00088     case Indent:
    00089       ind += "  ";
    00090       break;
    00091     case Unindent:
    00092       ind = ind.substr(0, ind.size() - 2);
    00093       break;
    00094   }
    00095
    00096   return *this;
    00097 }
    00098
    00099 UString unescapeStr(UString str)
    00100 {
    00101   UString unescaped = "";
    00102   int i = 0;
    00103   int copied = 0;
    00104   for (i = 0; i <= str.size(); i++) {
    00105     if (str[i] == '"') {
    00106       if (copied < i)
    00107     unescaped += str.substr(copied,i-copied);
    00108       copied = i+1;
    00109       unescaped += "\\\"";
    00110     }
    00111   }
    00112   if (copied < i)
    00113     unescaped += str.substr(copied,i-copied);
    00114   return unescaped;
    00115 }
    00116
    00117 UString Node::toCode() const
    00118 {
    00119   SourceStream str;
    00120   streamTo(str);
    00121
    00122   return str.toString();
    00123 }
    00124
    00125 void NullNode::streamTo(SourceStream &s) const { s << "null"; }
    00126
    00127 void BooleanNode::streamTo(SourceStream &s) const
    00128 {
    00129   s << (val ? "true" : "false");
    00130 }
    00131
    00132 void NumberNode::streamTo(SourceStream &s) const { s << UString::from(val); }
    00133
    00134 void StringNode::streamTo(SourceStream &s) const
    00135 {
    00136   s << '"' << unescapeStr(val) << '"';
    00137 }
    00138
    00139 void RegExpNode::streamTo(SourceStream &s) const { s << "/" << pattern << "/" << flags; }
    00140
    00141 void ThisNode::streamTo(SourceStream &s) const { s << "this"; }
    00142
    00143 void ResolveNode::streamTo(SourceStream &s) const { s << ident; }
    00144
    00145 void GroupNode::streamTo(SourceStream &s) const
    00146 {
    00147   s << "(" << group << ")";
    00148 }
    00149
    00150 void ElementNode::streamTo(SourceStream &s) const
    00151 {
    00152   for (const ElementNode *n = this; n; n = n->list) {
    00153     for (int i = 0; i < n->elision; i++)
    00154       s << ",";
    00155     s << n->node;
    00156     if ( n->list )
    00157         s << ",";
    00158   }
    00159 }
    00160
    00161 void ArrayNode::streamTo(SourceStream &s) const
    00162 {
    00163   s << "[" << element;
    00164   for (int i = 0; i < elision; i++)
    00165     s << ",";
    00166   s << "]";
    00167 }
    00168
    00169 void ObjectLiteralNode::streamTo(SourceStream &s) const
    00170 {
    00171   if (list)
    00172     s << "{ " << list << " }";
    00173   else
    00174     s << "{ }";
    00175 }
    00176
    00177 void PropertyValueNode::streamTo(SourceStream &s) const
    00178 {
    00179   for (const PropertyValueNode *n = this; n; n = n->list)
    00180     s << n->name << ": " << n->assign;
    00181 }
    00182
    00183 void PropertyNode::streamTo(SourceStream &s) const
    00184 {
    00185   if (str.isNull())
    00186     s << UString::from(numeric);
    00187   else
    00188     s << str;
    00189 }
    00190
    00191 void AccessorNode1::streamTo(SourceStream &s) const
    00192 {
    00193   s << expr1 << "[" << expr2 << "]";
    00194 }
    00195
    00196 void AccessorNode2::streamTo(SourceStream &s) const
    00197 {
    00198   s << expr << "." << ident;
    00199 }
    00200
    00201 void ArgumentListNode::streamTo(SourceStream &s) const
    00202 {
    00203   s << expr;
    00204   for (ArgumentListNode *n = list; n; n = n->list)
    00205     s << ", " << n->expr;
    00206 }
    00207
    00208 void ArgumentsNode::streamTo(SourceStream &s) const
    00209 {
    00210   s << "(" << list << ")";
    00211 }
    00212
    00213 void NewExprNode::streamTo(SourceStream &s) const
    00214 {
    00215   s << "new " << expr << args;
    00216 }
    00217
    00218 void FunctionCallNode::streamTo(SourceStream &s) const
    00219 {
    00220   s << expr << args;
    00221 }
    00222
    00223 void PostfixNode::streamTo(SourceStream &s) const
    00224 {
    00225   s << expr;
    00226   if (oper == OpPlusPlus)
    00227     s << "++";
    00228   else
    00229     s << "--";
    00230 }
    00231
    00232 void DeleteNode::streamTo(SourceStream &s) const
    00233 {
    00234   s << "delete " << expr;
    00235 }
    00236
    00237 void VoidNode::streamTo(SourceStream &s) const
    00238 {
    00239   s << "void " << expr;
    00240 }
    00241
    00242 void TypeOfNode::streamTo(SourceStream &s) const
    00243 {
    00244   s << "typeof " << expr;
    00245 }
    00246
    00247 void PrefixNode::streamTo(SourceStream &s) const
    00248 {
    00249   s << (oper == OpPlusPlus ? "++" : "--") << expr;
    00250 }
    00251
    00252 void UnaryPlusNode::streamTo(SourceStream &s) const
    00253 {
    00254   s << "+" << expr;
    00255 }
    00256
    00257 void NegateNode::streamTo(SourceStream &s) const
    00258 {
    00259   s << "-" << expr;
    00260 }
    00261
    00262 void BitwiseNotNode::streamTo(SourceStream &s) const
    00263 {
    00264   s << "~" << expr;
    00265 }
    00266
    00267 void LogicalNotNode::streamTo(SourceStream &s) const
    00268 {
    00269   s << "!" << expr;
    00270 }
    00271
    00272 void MultNode::streamTo(SourceStream &s) const
    00273 {
    00274   s << term1 << oper << term2;
    00275 }
    00276
    00277 void AddNode::streamTo(SourceStream &s) const
    00278 {
    00279   s << term1 << oper << term2;
    00280 }
    00281
    00282 void AppendStringNode::streamTo(SourceStream &s) const
    00283 {
    00284   s << term << "+" << '"' << unescapeStr(str) << '"';
    00285 }
    00286
    00287 void ShiftNode::streamTo(SourceStream &s) const
    00288 {
    00289   s << term1;
    00290   if (oper == OpLShift)
    00291     s << "<<";
    00292   else if (oper == OpRShift)
    00293     s << ">>";
    00294   else
    00295     s << ">>>";
    00296   s << term2;
    00297 }
    00298
    00299 void RelationalNode::streamTo(SourceStream &s) const
    00300 {
    00301   s << expr1;
    00302   switch (oper) {
    00303   case OpLess:
    00304     s << " < ";
    00305     break;
    00306   case OpGreater:
    00307     s << " > ";
    00308     break;
    00309   case OpLessEq:
    00310     s << " <= ";
    00311     break;
    00312   case OpGreaterEq:
    00313     s << " >= ";
    00314     break;
    00315   case OpInstanceOf:
    00316     s << " instanceof ";
    00317     break;
    00318   case OpIn:
    00319     s << " in ";
    00320     break;
    00321   default:
    00322     ;
    00323   }
    00324   s << expr2;
    00325 }
    00326
    00327 void EqualNode::streamTo(SourceStream &s) const
    00328 {
    00329   s << expr1;
    00330  switch (oper) {
    00331  case OpEqEq:
    00332    s << " == ";
    00333    break;
    00334  case OpNotEq:
    00335    s << " != ";
    00336    break;
    00337  case OpStrEq:
    00338    s << " === ";
    00339    break;
    00340  case OpStrNEq:
    00341    s << " !== ";
    00342    break;
    00343  default:
    00344    ;
    00345  }
    00346   s << expr2;
    00347 }
    00348
    00349 void BitOperNode::streamTo(SourceStream &s) const
    00350 {
    00351   s << expr1;
    00352   if (oper == OpBitAnd)
    00353     s << " & ";
    00354   else if (oper == OpBitXOr)
    00355     s << " ^ ";
    00356   else
    00357     s << " | ";
    00358   s << expr2;
    00359 }
    00360
    00361 void BinaryLogicalNode::streamTo(SourceStream &s) const
    00362 {
    00363   s << expr1 << (oper == OpAnd ? " && " : " || ") << expr2;
    00364 }
    00365
    00366 void ConditionalNode::streamTo(SourceStream &s) const
    00367 {
    00368   s << logical << " ? " << expr1 << " : " << expr2;
    00369 }
    00370
    00371 void AssignNode::streamTo(SourceStream &s) const
    00372 {
    00373   s << left;
    00374   const char *opStr;
    00375   switch (oper) {
    00376   case OpEqual:
    00377     opStr = " = ";
    00378     break;
    00379   case OpMultEq:
    00380     opStr = " *= ";
    00381     break;
    00382   case OpDivEq:
    00383     opStr = " /= ";
    00384     break;
    00385   case OpPlusEq:
    00386     opStr = " += ";
    00387     break;
    00388   case OpMinusEq:
    00389     opStr = " -= ";
    00390     break;
    00391   case OpLShift:
    00392     opStr = " <<= ";
    00393     break;
    00394   case OpRShift:
    00395     opStr = " >>= ";
    00396     break;
    00397   case OpURShift:
    00398     opStr = " >>= ";
    00399     break;
    00400   case OpAndEq:
    00401     opStr = " &= ";
    00402     break;
    00403   case OpXOrEq:
    00404     opStr = " ^= ";
    00405     break;
    00406   case OpOrEq:
    00407     opStr = " |= ";
    00408     break;
    00409   case OpModEq:
    00410     opStr = " %= ";
    00411     break;
    00412   default:
    00413     opStr = " ?= ";
    00414   }
    00415   s << opStr << expr;
    00416 }
    00417
    00418 void CommaNode::streamTo(SourceStream &s) const
    00419 {
    00420   s << expr1 << ", " << expr2;
    00421 }
    00422
    00423 void StatListNode::streamTo(SourceStream &s) const
    00424 {
    00425   for (const StatListNode *n = this; n; n = n->list)
    00426     s << n->statement;
    00427 }
    00428
    00429 void AssignExprNode::streamTo(SourceStream &s) const
    00430 {
    00431   s << " = " << expr;
    00432 }
    00433
    00434 void VarDeclNode::streamTo(SourceStream &s) const
    00435 {
    00436   s << ident << init;
    00437 }
    00438
    00439 void VarDeclListNode::streamTo(SourceStream &s) const
    00440 {
    00441   s << var;
    00442   for (VarDeclListNode *n = list; n; n = n->list)
    00443     s << ", " << n->var;
    00444 }
    00445
    00446 void VarStatementNode::streamTo(SourceStream &s) const
    00447 {
    00448   s << SourceStream::Endl << "var " << list << ";";
    00449 }
    00450
    00451 void BlockNode::streamTo(SourceStream &s) const
    00452 {
    00453   s << SourceStream::Endl << "{" << SourceStream::Indent
    00454     << source << SourceStream::Unindent << SourceStream::Endl << "}";
    00455 }
    00456
    00457 void EmptyStatementNode::streamTo(SourceStream &s) const
    00458 {
    00459   s << SourceStream::Endl << ";";
    00460 }
    00461
    00462 void ExprStatementNode::streamTo(SourceStream &s) const
    00463 {
    00464   s << SourceStream::Endl << expr << ";";
    00465 }
    00466
    00467 void IfNode::streamTo(SourceStream &s) const
    00468 {
    00469   s << SourceStream::Endl << "if (" << expr << ")" << SourceStream::Indent
    00470     << statement1 << SourceStream::Unindent;
    00471   if (statement2)
    00472     s << SourceStream::Endl << "else" << SourceStream::Indent
    00473       << statement2 << SourceStream::Unindent;
    00474 }
    00475
    00476 void DoWhileNode::streamTo(SourceStream &s) const
    00477 {
    00478   s << SourceStream::Endl << "do " << SourceStream::Indent
    00479     << statement << SourceStream::Unindent << SourceStream::Endl
    00480     << "while (" << expr << ");";
    00481 }
    00482
    00483 void WhileNode::streamTo(SourceStream &s) const
    00484 {
    00485   s << SourceStream::Endl << "while (" << expr << ")" << SourceStream::Indent
    00486     << statement << SourceStream::Unindent;
    00487 }
    00488
    00489 void ForNode::streamTo(SourceStream &s) const
    00490 {
    00491   s << SourceStream::Endl << "for ("
    00492     << expr1  // TODO: doesn't properly do "var i = 0"
    00493     << "; " << expr2
    00494     << "; " << expr3
    00495     << ")" << SourceStream::Indent << statement << SourceStream::Unindent;
    00496 }
    00497
    00498 void ForInNode::streamTo(SourceStream &s) const
    00499 {
    00500   s << SourceStream::Endl << "for (";
    00501   if (varDecl)
    00502     s << "var " << varDecl;
    00503   if (init)
    00504     s << " = " << init;
    00505   s << " in " << expr << ")" << SourceStream::Indent
    00506     << statement << SourceStream::Unindent;
    00507 }
    00508
    00509 void ContinueNode::streamTo(SourceStream &s) const
    00510 {
    00511   s << SourceStream::Endl << "continue";
    00512   if (!ident.isNull())
    00513     s << " " << ident;
    00514   s << ";";
    00515 }
    00516
    00517 void BreakNode::streamTo(SourceStream &s) const
    00518 {
    00519   s << SourceStream::Endl << "break";
    00520   if (!ident.isNull())
    00521     s << " " << ident;
    00522   s << ";";
    00523 }
    00524
    00525 void ReturnNode::streamTo(SourceStream &s) const
    00526 {
    00527   s << SourceStream::Endl << "return";
    00528   if (value)
    00529     s << " " << value;
    00530   s << ";";
    00531 }
    00532
    00533 void WithNode::streamTo(SourceStream &s) const
    00534 {
    00535   s << SourceStream::Endl << "with (" << expr << ") "
    00536     << statement;
    00537 }
    00538
    00539 void CaseClauseNode::streamTo(SourceStream &s) const
    00540 {
    00541   s << SourceStream::Endl;
    00542   if (expr)
    00543     s << "case " << expr;
    00544   else
    00545     s << "default";
    00546   s << ":" << SourceStream::Indent;
    00547   if (list)
    00548     s << list;
    00549   s << SourceStream::Unindent;
    00550 }
    00551
    00552 void ClauseListNode::streamTo(SourceStream &s) const
    00553 {
    00554   for (const ClauseListNode *n = this; n; n = n->next())
    00555     s << n->clause();
    00556 }
    00557
    00558 void CaseBlockNode::streamTo(SourceStream &s) const
    00559 {
    00560   for (const ClauseListNode *n = list1; n; n = n->next())
    00561     s << n->clause();
    00562   if (def)
    00563     s << def;
    00564   for (const ClauseListNode *n = list2; n; n = n->next())
    00565     s << n->clause();
    00566 }
    00567
    00568 void SwitchNode::streamTo(SourceStream &s) const
    00569 {
    00570   s << SourceStream::Endl << "switch (" << expr << ") {"
    00571     << SourceStream::Indent << block << SourceStream::Unindent
    00572     << SourceStream::Endl << "}";
    00573 }
    00574
    00575 void LabelNode::streamTo(SourceStream &s) const
    00576 {
    00577   s << SourceStream::Endl << label << ":" << SourceStream::Indent
    00578     << statement << SourceStream::Unindent;
    00579 }
    00580
    00581 void ThrowNode::streamTo(SourceStream &s) const
    00582 {
    00583   s << SourceStream::Endl << "throw " << expr << ";";
    00584 }
    00585
    00586 void CatchNode::streamTo(SourceStream &s) const
    00587 {
    00588   s << SourceStream::Endl << "catch (" << ident << ")" << block;
    00589 }
    00590
    00591 void FinallyNode::streamTo(SourceStream &s) const
    00592 {
    00593   s << SourceStream::Endl << "finally " << block;
    00594 }
    00595
    00596 void TryNode::streamTo(SourceStream &s) const
    00597 {
    00598   s << SourceStream::Endl << "try " << block
    00599     << _catch
    00600     << _final;
    00601 }
    00602
    00603 void ParameterNode::streamTo(SourceStream &s) const
    00604 {
    00605   s << id;
    00606   for (ParameterNode *n = next; n; n = n->next)
    00607     s << ", " << n->id;
    00608 }
    00609
    00610 void FuncDeclNode::streamTo(SourceStream &s) const {
    00611   s << SourceStream::Endl << "function " << ident << "(";
    00612   if (param)
    00613     s << param;
    00614   s << ")" << body;
    00615 }
    00616
    00617 void FuncExprNode::streamTo(SourceStream &s) const
    00618 {
    00619   s << "function " << "("
    00620     << param
    00621     << ")" << body;
    00622 }
    00623
    00624 void SourceElementsNode::streamTo(SourceStream &s) const
    00625 {
    00626   for (const SourceElementsNode *n = this; n; n = n->elements)
    00627     s << n->element;
    00628 }
    00629

This file is part of the documentation for kjs Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:23:07 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003