nodes2string.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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;
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
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
This file is part of the documentation for kjs Library Version 3.2.3.