nodes2string.cpp00001
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 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
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
|