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
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