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 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
KDE Logo
This file is part of the documentation for kjs Library Version 3.4.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Apr 12 23:07:00 2005 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003