kjs Library API Documentation

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   }
00157 }
00158 
00159 void ArrayNode::streamTo(SourceStream &s) const
00160 {
00161   s << "[" << element;
00162   for (int i = 0; i < elision; i++)
00163     s << ",";
00164   s << "]";
00165 }
00166 
00167 void ObjectLiteralNode::streamTo(SourceStream &s) const
00168 {
00169   if (list)
00170     s << "{ " << list << " }";
00171   else
00172     s << "{ }";
00173 }
00174 
00175 void PropertyValueNode::streamTo(SourceStream &s) const
00176 {
00177   for (const PropertyValueNode *n = this; n; n = n->list)
00178     s << n->name << ": " << n->assign;
00179 }
00180 
00181 void PropertyNode::streamTo(SourceStream &s) const
00182 {
00183   if (str.isNull())
00184     s << UString::from(numeric);
00185   else
00186     s << str;
00187 }
00188 
00189 void AccessorNode1::streamTo(SourceStream &s) const
00190 {
00191   s << expr1 << "[" << expr2 << "]";
00192 }
00193 
00194 void AccessorNode2::streamTo(SourceStream &s) const
00195 {
00196   s << expr << "." << ident;
00197 }
00198 
00199 void ArgumentListNode::streamTo(SourceStream &s) const
00200 {
00201   s << expr;
00202   for (ArgumentListNode *n = list; n; n = n->list)
00203     s << ", " << n->expr;
00204 }
00205 
00206 void ArgumentsNode::streamTo(SourceStream &s) const
00207 {
00208   s << "(" << list << ")";
00209 }
00210 
00211 void NewExprNode::streamTo(SourceStream &s) const
00212 {
00213   s << "new " << expr << args;
00214 }
00215 
00216 void FunctionCallNode::streamTo(SourceStream &s) const
00217 {
00218   s << expr << args;
00219 }
00220 
00221 void PostfixNode::streamTo(SourceStream &s) const
00222 {
00223   s << expr;
00224   if (oper == OpPlusPlus)
00225     s << "++";
00226   else
00227     s << "--";
00228 }
00229 
00230 void DeleteNode::streamTo(SourceStream &s) const
00231 {
00232   s << "delete " << expr;
00233 }
00234 
00235 void VoidNode::streamTo(SourceStream &s) const
00236 {
00237   s << "void " << expr;
00238 }
00239 
00240 void TypeOfNode::streamTo(SourceStream &s) const
00241 {
00242   s << "typeof " << expr;
00243 }
00244 
00245 void PrefixNode::streamTo(SourceStream &s) const
00246 {
00247   s << (oper == OpPlusPlus ? "++" : "--") << expr;
00248 }
00249 
00250 void UnaryPlusNode::streamTo(SourceStream &s) const
00251 {
00252   s << "+" << expr;
00253 }
00254 
00255 void NegateNode::streamTo(SourceStream &s) const
00256 {
00257   s << "-" << expr;
00258 }
00259 
00260 void BitwiseNotNode::streamTo(SourceStream &s) const
00261 {
00262   s << "~" << expr;
00263 }
00264 
00265 void LogicalNotNode::streamTo(SourceStream &s) const
00266 {
00267   s << "!" << expr;
00268 }
00269 
00270 void MultNode::streamTo(SourceStream &s) const
00271 {
00272   s << term1 << oper << term2;
00273 }
00274 
00275 void AddNode::streamTo(SourceStream &s) const
00276 {
00277   s << term1 << oper << term2;
00278 }
00279 
00280 void AppendStringNode::streamTo(SourceStream &s) const
00281 {
00282   s << term << "+" << '"' << unescapeStr(str) << '"';
00283 }
00284 
00285 void ShiftNode::streamTo(SourceStream &s) const
00286 {
00287   s << term1;
00288   if (oper == OpLShift)
00289     s << "<<";
00290   else if (oper == OpRShift)
00291     s << ">>";
00292   else
00293     s << ">>>";
00294   s << term2;
00295 }
00296 
00297 void RelationalNode::streamTo(SourceStream &s) const
00298 {
00299   s << expr1;
00300   switch (oper) {
00301   case OpLess:
00302     s << " < ";
00303     break;
00304   case OpGreater:
00305     s << " > ";
00306     break;
00307   case OpLessEq:
00308     s << " <= ";
00309     break;
00310   case OpGreaterEq:
00311     s << " >= ";
00312     break;
00313   case OpInstanceOf:
00314     s << " instanceof ";
00315     break;
00316   case OpIn:
00317     s << " in ";
00318     break;
00319   default:
00320     ;
00321   }
00322   s << expr2;
00323 }
00324 
00325 void EqualNode::streamTo(SourceStream &s) const
00326 {
00327   s << expr1;
00328  switch (oper) {
00329  case OpEqEq:
00330    s << " == ";
00331    break;
00332  case OpNotEq:
00333    s << " != ";
00334    break;
00335  case OpStrEq:
00336    s << " === ";
00337    break;
00338  case OpStrNEq:
00339    s << " !== ";
00340    break;
00341  default:
00342    ;
00343  }
00344   s << expr2;
00345 }
00346 
00347 void BitOperNode::streamTo(SourceStream &s) const
00348 {
00349   s << expr1;
00350   if (oper == OpBitAnd)
00351     s << " & ";
00352   else if (oper == OpBitXOr)
00353     s << " ^ ";
00354   else
00355     s << " | ";
00356   s << expr2;
00357 }
00358 
00359 void BinaryLogicalNode::streamTo(SourceStream &s) const
00360 {
00361   s << expr1 << (oper == OpAnd ? " && " : " || ") << expr2;
00362 }
00363 
00364 void ConditionalNode::streamTo(SourceStream &s) const
00365 {
00366   s << logical << " ? " << expr1 << " : " << expr2;
00367 }
00368 
00369 void AssignNode::streamTo(SourceStream &s) const
00370 {
00371   s << left;
00372   const char *opStr;
00373   switch (oper) {
00374   case OpEqual:
00375     opStr = " = ";
00376     break;
00377   case OpMultEq:
00378     opStr = " *= ";
00379     break;
00380   case OpDivEq:
00381     opStr = " /= ";
00382     break;
00383   case OpPlusEq:
00384     opStr = " += ";
00385     break;
00386   case OpMinusEq:
00387     opStr = " -= ";
00388     break;
00389   case OpLShift:
00390     opStr = " <<= ";
00391     break;
00392   case OpRShift:
00393     opStr = " >>= ";
00394     break;
00395   case OpURShift:
00396     opStr = " >>= ";
00397     break;
00398   case OpAndEq:
00399     opStr = " &= ";
00400     break;
00401   case OpXOrEq:
00402     opStr = " ^= ";
00403     break;
00404   case OpOrEq:
00405     opStr = " |= ";
00406     break;
00407   case OpModEq:
00408     opStr = " %= ";
00409     break;
00410   default:
00411     opStr = " ?= ";
00412   }
00413   s << opStr << expr;
00414 }
00415 
00416 void CommaNode::streamTo(SourceStream &s) const
00417 {
00418   s << expr1 << ", " << expr2;
00419 }
00420 
00421 void StatListNode::streamTo(SourceStream &s) const
00422 {
00423   for (const StatListNode *n = this; n; n = n->list)
00424     s << n->statement;
00425 }
00426 
00427 void AssignExprNode::streamTo(SourceStream &s) const
00428 {
00429   s << " = " << expr;
00430 }
00431 
00432 void VarDeclNode::streamTo(SourceStream &s) const
00433 {
00434   s << ident << init;
00435 }
00436 
00437 void VarDeclListNode::streamTo(SourceStream &s) const
00438 {
00439   s << var;
00440   for (VarDeclListNode *n = list; n; n = n->list)
00441     s << ", " << n->var;
00442 }
00443 
00444 void VarStatementNode::streamTo(SourceStream &s) const
00445 {
00446   s << SourceStream::Endl << "var " << list << ";";
00447 }
00448 
00449 void BlockNode::streamTo(SourceStream &s) const
00450 {
00451   s << SourceStream::Endl << "{" << SourceStream::Indent
00452     << source << SourceStream::Unindent << SourceStream::Endl << "}";
00453 }
00454 
00455 void EmptyStatementNode::streamTo(SourceStream &s) const
00456 {
00457   s << SourceStream::Endl << ";";
00458 }
00459 
00460 void ExprStatementNode::streamTo(SourceStream &s) const
00461 {
00462   s << SourceStream::Endl << expr << ";";
00463 }
00464 
00465 void IfNode::streamTo(SourceStream &s) const
00466 {
00467   s << SourceStream::Endl << "if (" << expr << ")" << SourceStream::Indent
00468     << statement1 << SourceStream::Unindent;
00469   if (statement2)
00470     s << SourceStream::Endl << "else" << SourceStream::Indent
00471       << statement2 << SourceStream::Unindent;
00472 }
00473 
00474 void DoWhileNode::streamTo(SourceStream &s) const
00475 {
00476   s << SourceStream::Endl << "do " << SourceStream::Indent
00477     << statement << SourceStream::Unindent << SourceStream::Endl
00478     << "while (" << expr << ");";
00479 }
00480 
00481 void WhileNode::streamTo(SourceStream &s) const
00482 {
00483   s << SourceStream::Endl << "while (" << expr << ")" << SourceStream::Indent
00484     << statement << SourceStream::Unindent;
00485 }
00486 
00487 void ForNode::streamTo(SourceStream &s) const
00488 {
00489   s << SourceStream::Endl << "for ("
00490     << expr1  // TODO: doesn't properly do "var i = 0"
00491     << "; " << expr2
00492     << "; " << expr3
00493     << ")" << SourceStream::Indent << statement << SourceStream::Unindent;
00494 }
00495 
00496 void ForInNode::streamTo(SourceStream &s) const
00497 {
00498   s << SourceStream::Endl << "for (";
00499   if (varDecl)
00500     s << "var " << varDecl;
00501   if (init)
00502     s << " = " << init;
00503   s << " in " << expr << ")" << SourceStream::Indent
00504     << statement << SourceStream::Unindent;
00505 }
00506 
00507 void ContinueNode::streamTo(SourceStream &s) const
00508 {
00509   s << SourceStream::Endl << "continue";
00510   if (!ident.isNull())
00511     s << " " << ident;
00512   s << ";";
00513 }
00514 
00515 void BreakNode::streamTo(SourceStream &s) const
00516 {
00517   s << SourceStream::Endl << "break";
00518   if (!ident.isNull())
00519     s << " " << ident;
00520   s << ";";
00521 }
00522 
00523 void ReturnNode::streamTo(SourceStream &s) const
00524 {
00525   s << SourceStream::Endl << "return";
00526   if (value)
00527     s << " " << value;
00528   s << ";";
00529 }
00530 
00531 void WithNode::streamTo(SourceStream &s) const
00532 {
00533   s << SourceStream::Endl << "with (" << expr << ") "
00534     << statement;
00535 }
00536 
00537 void CaseClauseNode::streamTo(SourceStream &s) const
00538 {
00539   s << SourceStream::Endl;
00540   if (expr)
00541     s << "case " << expr;
00542   else
00543     s << "default";
00544   s << ":" << SourceStream::Indent;
00545   if (list)
00546     s << list;
00547   s << SourceStream::Unindent;
00548 }
00549 
00550 void ClauseListNode::streamTo(SourceStream &s) const
00551 {
00552   for (const ClauseListNode *n = this; n; n = n->next())
00553     s << n->clause();
00554 }
00555 
00556 void CaseBlockNode::streamTo(SourceStream &s) const
00557 {
00558   for (const ClauseListNode *n = list1; n; n = n->next())
00559     s << n->clause();
00560   if (def)
00561     s << def;
00562   for (const ClauseListNode *n = list2; n; n = n->next())
00563     s << n->clause();
00564 }
00565 
00566 void SwitchNode::streamTo(SourceStream &s) const
00567 {
00568   s << SourceStream::Endl << "switch (" << expr << ") {"
00569     << SourceStream::Indent << block << SourceStream::Unindent
00570     << SourceStream::Endl << "}";
00571 }
00572 
00573 void LabelNode::streamTo(SourceStream &s) const
00574 {
00575   s << SourceStream::Endl << label << ":" << SourceStream::Indent
00576     << statement << SourceStream::Unindent;
00577 }
00578 
00579 void ThrowNode::streamTo(SourceStream &s) const
00580 {
00581   s << SourceStream::Endl << "throw " << expr << ";";
00582 }
00583 
00584 void CatchNode::streamTo(SourceStream &s) const
00585 {
00586   s << SourceStream::Endl << "catch (" << ident << ")" << block;
00587 }
00588 
00589 void FinallyNode::streamTo(SourceStream &s) const
00590 {
00591   s << SourceStream::Endl << "finally " << block;
00592 }
00593 
00594 void TryNode::streamTo(SourceStream &s) const
00595 {
00596   s << "try " << block
00597     << _catch
00598     << _final;
00599 }
00600 
00601 void ParameterNode::streamTo(SourceStream &s) const
00602 {
00603   s << id;
00604   for (ParameterNode *n = next; n; n = n->next)
00605     s << ", " << n->id;
00606 }
00607 
00608 void FuncDeclNode::streamTo(SourceStream &s) const {
00609   s << SourceStream::Endl << "function " << ident << "(";
00610   if (param)
00611     s << param;
00612   s << ")" << body;
00613 }
00614 
00615 void FuncExprNode::streamTo(SourceStream &s) const
00616 {
00617   s << "function " << "("
00618     << param
00619     << ")" << body;
00620 }
00621 
00622 void SourceElementsNode::streamTo(SourceStream &s) const
00623 {
00624   for (const SourceElementsNode *n = this; n; n = n->elements)
00625     s << n->element;
00626 }
00627 
KDE Logo
This file is part of the documentation for kjs Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Mar 3 19:23:28 2005 by doxygen 1.3.6 written by Dimitri van Heesch, © 1997-2003