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.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 12 15:08:29 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003