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