1 /* Cycript - Optimizing JavaScript Compiler/Runtime 
   2  * Copyright (C) 2009-2015  Jay Freeman (saurik) 
   5 /* GNU Affero General Public License, Version 3 {{{ */ 
   7  * This program is free software: you can redistribute it and/or modify 
   8  * it under the terms of the GNU Affero General Public License as published by 
   9  * the Free Software Foundation, either version 3 of the License, or 
  10  * (at your option) any later version. 
  12  * This program is distributed in the hope that it will be useful, 
  13  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
  14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  15  * GNU Affero General Public License for more details. 
  17  * You should have received a copy of the GNU Affero General Public License 
  18  * along with this program.  If not, see <http://www.gnu.org/licenses/>. 
  25 #include "Replace.hpp" 
  28 CYFunctionExpression 
*CYNonLocalize(CYContext 
&context
, CYFunctionExpression 
*function
) { 
  29     function
->nonlocal_ 
= context
.nextlocal_
; 
  33 CYFunctionExpression 
*CYSuperize(CYContext 
&context
, CYFunctionExpression 
*function
) { 
  34     function
->super_ 
= context
.super_
; 
  38 CYStatement 
*CYDefineProperty(CYExpression 
*object
, CYExpression 
*name
, bool configurable
, bool enumerable
, CYProperty 
*descriptor
) { 
  39     return $
E($
C3($
M($
V("Object"), $
S("defineProperty")), object
, name
, $ 
CYObject(CYList
<CYProperty
>() 
  40         ->* (configurable 
? $ 
CYPropertyValue($
S("configurable"), $ 
CYTrue()) : NULL
) 
  41         ->* (enumerable 
? $ 
CYPropertyValue($
S("enumerable"), $ 
CYTrue()) : NULL
) 
  45 static void CYImplicitReturn(CYStatement 
*&code
) { 
  46     if (CYStatement 
*&last 
= CYGetLast(code
)) 
  47         last 
= last
->Return(); 
  50 CYExpression 
*CYAdd::Replace(CYContext 
&context
) { 
  51     CYInfix::Replace(context
); 
  53     CYString 
*lhs(dynamic_cast<CYString 
*>(lhs_
)); 
  54     CYString 
*rhs(dynamic_cast<CYString 
*>(rhs_
)); 
  56     if (lhs 
!= NULL 
|| rhs 
!= NULL
) { 
  58             lhs 
= lhs_
->String(context
); 
  61         } else if (rhs 
== NULL
) { 
  62             rhs 
= rhs_
->String(context
); 
  67         return lhs
->Concat(context
, rhs
); 
  70     if (CYNumber 
*lhn 
= lhs_
->Number(context
)) 
  71         if (CYNumber 
*rhn 
= rhs_
->Number(context
)) 
  72             return $
D(lhn
->Value() + rhn
->Value()); 
  77 CYExpression 
*CYAddressOf::Replace(CYContext 
&context
) { 
  78     return $
C0($
M(rhs_
, $
S("$cya"))); 
  81 CYTarget 
*CYApply::AddArgument(CYContext 
&context
, CYExpression 
*value
) { 
  82     CYArgument 
**argument(&arguments_
); 
  83     while (*argument 
!= NULL
) 
  84         argument 
= &(*argument
)->next_
; 
  85     *argument 
= $ 
CYArgument(value
); 
  89 CYArgument 
*CYArgument::Replace(CYContext 
&context
) { $
T(NULL
) 
  90     context
.Replace(value_
); 
  91     next_ 
= next_
->Replace(context
); 
 103 CYTarget 
*CYArray::Replace(CYContext 
&context
) { 
 104     if (elements_ 
!= NULL
) 
 105         elements_
->Replace(context
); 
 109 CYTarget 
*CYArrayComprehension::Replace(CYContext 
&context
) { 
 110     CYVariable 
*cyv($
V("$cyv")); 
 112     return $
C0($
F(NULL
, $
P1($
L($
I("$cyv")), comprehensions_
->Parameters(context
)), $$
->* 
 113         $
E($ 
CYAssign(cyv
, $ 
CYArray()))->* 
 114         comprehensions_
->Replace(context
, $
E($
C1($
M(cyv
, $
S("push")), expression_
)))->* 
 119 CYExpression 
*CYAssignment::Replace(CYContext 
&context
) { 
 120     context
.Replace(lhs_
); 
 121     context
.Replace(rhs_
); 
 125 CYStatement 
*CYBlock::Return() { 
 126     CYImplicitReturn(code_
); 
 130 CYStatement 
*CYBlock::Replace(CYContext 
&context
) { 
 131     CYScope 
scope(true, context
); 
 132     context
.ReplaceAll(code_
); 
 133     scope
.Close(context
); 
 140 CYStatement 
*CYBreak::Replace(CYContext 
&context
) { 
 144 CYTarget 
*CYCall::Replace(CYContext 
&context
) { 
 145     context
.Replace(function_
); 
 146     arguments_
->Replace(context
); 
 153 void Catch::Replace(CYContext 
&context
) { $
T() 
 154     CYScope 
scope(true, context
); 
 156     name_ 
= name_
->Replace(context
, CYIdentifierCatch
); 
 158     context
.ReplaceAll(code_
); 
 159     scope
.Close(context
); 
 164 CYTarget 
*CYClassExpression::Replace(CYContext 
&context
) { 
 167     CYIdentifier 
*super(context
.Unique()); 
 169     CYIdentifier 
*old(context
.super_
); 
 170     context
.super_ 
= super
; 
 172     CYIdentifier 
*constructor(context
.Unique()); 
 173     CYForEach (member
, tail_
->static_
) 
 174         member
->Replace(context
, builder
, $
V(constructor
), true); 
 176     CYIdentifier 
*prototype(context
.Unique()); 
 177     CYForEach (member
, tail_
->instance_
) 
 178         member
->Replace(context
, builder
, $
V(prototype
), true); 
 180     if (tail_
->constructor_ 
== NULL
) 
 181         tail_
->constructor_ 
= $ 
CYFunctionExpression(NULL
, NULL
, NULL
); 
 182     tail_
->constructor_ 
= CYSuperize(context
, tail_
->constructor_
); 
 184     context
.super_ 
= old
; 
 186     return $
C1($ 
CYFunctionExpression(NULL
, $
P($
L(super
)), $$
 
 187         ->* $ 
CYVar($
L1($
L(constructor
, tail_
->constructor_
))) 
 188         ->* $ 
CYVar($
L1($
L(prototype
, $ 
CYFunctionExpression(NULL
, NULL
, NULL
)))) 
 189         ->* $
E($ 
CYAssign($
M($
V(prototype
), $
S("prototype")), $
M($
V(super
), $
S("prototype")))) 
 190         ->* $
E($ 
CYAssign($
V(prototype
), $
N($
V(prototype
)))) 
 191         ->* CYDefineProperty($
V(prototype
), $
S("constructor"), false, false, $ 
CYPropertyValue($
S("value"), $
V(constructor
))) 
 192         ->* $ 
CYVar(builder
.declarations_
) 
 193         ->* builder
.statements_
 
 194         ->* CYDefineProperty($
V(constructor
), $
S("prototype"), false, false, $ 
CYPropertyValue($
S("value"), $
V(prototype
))) 
 195         ->* $ 
CYReturn($
V(constructor
)) 
 196     ), tail_
->extends_ 
?: $
V($
I("Object"))); 
 199 CYStatement 
*CYClassStatement::Replace(CYContext 
&context
) { 
 200     return $ 
CYVar($
L1($
L(name_
, $ 
CYClassExpression(name_
, tail_
)))); 
 203 void CYClause::Replace(CYContext 
&context
) { $
T() 
 204     context
.Replace(case_
); 
 205     context
.ReplaceAll(code_
); 
 206     next_
->Replace(context
); 
 209 CYExpression 
*CYCompound::Replace(CYContext 
&context
) { 
 210     context
.Replace(expression_
); 
 211     context
.Replace(next_
); 
 213     if (CYCompound 
*compound 
= dynamic_cast<CYCompound 
*>(expression_
)) { 
 214         expression_ 
= compound
->expression_
; 
 215         compound
->expression_ 
= compound
->next_
; 
 216         compound
->next_ 
= next_
; 
 223 CYFunctionParameter 
*CYCompound::Parameter() const { 
 224     CYFunctionParameter 
*next(next_
->Parameter()); 
 228     CYFunctionParameter 
*parameter(expression_
->Parameter()); 
 229     if (parameter 
== NULL
) 
 232     parameter
->SetNext(next
); 
 236 CYFunctionParameter 
*CYComprehension::Parameters(CYContext 
&context
) const { $
T(NULL
) 
 237     CYFunctionParameter 
*next(next_
->Parameters(context
)); 
 238     if (CYFunctionParameter 
*parameter 
= Parameter(context
)) { 
 239         parameter
->SetNext(next
); 
 245 CYStatement 
*CYComprehension::Replace(CYContext 
&context
, CYStatement 
*statement
) const { 
 246     return next_ 
== NULL 
? statement 
: next_
->Replace(context
, statement
); 
 249 CYExpression 
*CYComputed::PropertyName(CYContext 
&context
) { 
 253 CYExpression 
*CYCondition::Replace(CYContext 
&context
) { 
 254     context
.Replace(test_
); 
 255     context
.Replace(true_
); 
 256     context
.Replace(false_
); 
 260 void CYContext::NonLocal(CYStatement 
*&statements
) { 
 261     CYContext 
&context(*this); 
 263     if (nextlocal_ 
!= NULL 
&& nextlocal_
->identifier_ 
!= NULL
) { 
 264         CYIdentifier 
*cye($
I("$cye")->Replace(context
, CYIdentifierGlobal
)); 
 265         CYIdentifier 
*unique(nextlocal_
->identifier_
->Replace(context
, CYIdentifierGlobal
)); 
 267         CYStatement 
*declare( 
 268             $ 
CYVar($
L1($
L(unique
, $ 
CYObject())))); 
 270         cy::Syntax::Catch 
*rescue( 
 271             $ 
cy::Syntax::Catch(cye
, $$
->* 
 272                 $ 
CYIf($ 
CYIdentical($
M($
V(cye
), $
S("$cyk")), $
V(unique
)), $$
->* 
 273                     $ 
CYReturn($
M($
V(cye
), $
S("$cyv"))))->* 
 274                 $ 
cy::Syntax::Throw($
V(cye
)))); 
 276         context
.Replace(declare
); 
 277         rescue
->Replace(context
); 
 281             $ 
cy::Syntax::Try(statements
, rescue
, NULL
); 
 285 CYIdentifier 
*CYContext::Unique() { 
 286     return $ 
CYIdentifier($pool
.strcat("$cy", $pool
.itoa(unique_
++), NULL
)); 
 289 CYStatement 
*CYContinue::Replace(CYContext 
&context
) { 
 293 CYStatement 
*CYDebugger::Replace(CYContext 
&context
) { 
 297 CYTarget 
*CYDeclaration::Target(CYContext 
&context
) { 
 298     return $
V(identifier_
); 
 301 CYAssignment 
*CYDeclaration::Replace(CYContext 
&context
, CYIdentifierKind kind
) { 
 302     identifier_ 
= identifier_
->Replace(context
, kind
); 
 304     if (initialiser_ 
== NULL
) 
 307     CYAssignment 
*value($ 
CYAssign(Target(context
), initialiser_
)); 
 312 CYExpression 
*CYDeclarations::Replace(CYContext 
&context
, CYIdentifierKind kind
) { $
T(NULL
) 
 313     CYAssignment 
*assignment(declaration_
->Replace(context
, kind
)); 
 314     CYExpression 
*compound(next_
->Replace(context
, kind
)); 
 316     if (assignment 
!= NULL
) 
 317         if (compound 
== NULL
) 
 318             compound 
= assignment
; 
 320             compound 
= $ 
CYCompound(assignment
, compound
); 
 324 CYFunctionParameter 
*CYDeclarations::Parameter(CYContext 
&context
) { $
T(NULL
) 
 325     return $ 
CYFunctionParameter($ 
CYDeclaration(declaration_
->identifier_
), next_
->Parameter(context
)); 
 328 CYArgument 
*CYDeclarations::Argument(CYContext 
&context
) { $
T(NULL
) 
 329     return $ 
CYArgument(declaration_
->initialiser_
, next_
->Argument(context
)); 
 332 CYTarget 
*CYDirectMember::Replace(CYContext 
&context
) { 
 333     context
.Replace(object_
); 
 334     context
.Replace(property_
); 
 338 CYStatement 
*CYDoWhile::Replace(CYContext 
&context
) { 
 339     context
.Replace(test_
); 
 340     context
.ReplaceAll(code_
); 
 344 void CYElementSpread::Replace(CYContext 
&context
) { 
 345     context
.Replace(value_
); 
 348 void CYElementValue::Replace(CYContext 
&context
) { 
 349     context
.Replace(value_
); 
 351         next_
->Replace(context
); 
 354 CYForInitializer 
*CYEmpty::Replace(CYContext 
&context
) { 
 358 CYTarget 
*CYEncodedType::Replace(CYContext 
&context
) { 
 359     return typed_
->Replace(context
); 
 362 CYTarget 
*CYEval::Replace(CYContext 
&context
) { 
 363     context
.scope_
->Damage(); 
 364     if (arguments_ 
!= NULL
) 
 365         arguments_
->value_ 
= $
C1($
M($
V("Cycript"), $
S("compile")), arguments_
->value_
); 
 366     return $
C($
V("eval"), arguments_
); 
 369 CYStatement 
*CYExpress::Return() { 
 370     return $ 
CYReturn(expression_
); 
 373 CYForInitializer 
*CYExpress::Replace(CYContext 
&context
) { 
 374     context
.Replace(expression_
); 
 378 CYTarget 
*CYExpression::AddArgument(CYContext 
&context
, CYExpression 
*value
) { 
 379     return $
C1(this, value
); 
 382 CYFunctionParameter 
*CYExpression::Parameter() const { 
 386 CYStatement 
*CYExternal::Replace(CYContext 
&context
) { 
 387     return $
E($ 
CYAssign($
V(typed_
->identifier_
), $
C1(typed_
->Replace(context
), $
C2($
V("dlsym"), $
V("RTLD_DEFAULT"), $
S(typed_
->identifier_
->Word()))))); 
 390 CYNumber 
*CYFalse::Number(CYContext 
&context
) { 
 394 CYString 
*CYFalse::String(CYContext 
&context
) { 
 398 CYExpression 
*CYFatArrow::Replace(CYContext 
&context
) { 
 399     CYFunctionExpression 
*function($ 
CYFunctionExpression(NULL
, parameters_
, code_
)); 
 400     function
->this_
.SetNext(context
.this_
); 
 404 void CYFinally::Replace(CYContext 
&context
) { $
T() 
 405     CYScope 
scope(true, context
); 
 406     context
.ReplaceAll(code_
); 
 407     scope
.Close(context
); 
 410 CYStatement 
*CYFor::Replace(CYContext 
&context
) { 
 411     CYScope 
outer(true, context
); 
 412     context
.Replace(initialiser_
); 
 414     context
.Replace(test_
); 
 417         CYScope 
inner(true, context
); 
 418         context
.ReplaceAll(code_
); 
 419         inner
.Close(context
); 
 422     context
.Replace(increment_
); 
 424     outer
.Close(context
); 
 428 CYStatement 
*CYForLexical::Initialize(CYContext 
&context
, CYExpression 
*value
) { 
 430         if (declaration_
->initialiser_ 
== NULL
) 
 432         value 
= declaration_
->initialiser_
; 
 435     return $ 
CYLet(constant_
, $
L1($ 
CYDeclaration(declaration_
->identifier_
, value
))); 
 438 CYTarget 
*CYForLexical::Replace(CYContext 
&context
) { 
 439     _assert(declaration_
->Replace(context
, CYIdentifierLexical
) == NULL
); 
 440     return declaration_
->Target(context
); 
 443 CYStatement 
*CYForIn::Replace(CYContext 
&context
) { 
 444     CYScope 
scope(true, context
); 
 445     context
.Replace(initialiser_
); 
 446     context
.Replace(set_
); 
 447     context
.ReplaceAll(code_
); 
 448     scope
.Close(context
); 
 452 CYFunctionParameter 
*CYForInComprehension::Parameter(CYContext 
&context
) const { 
 453     return $ 
CYFunctionParameter(declaration_
); 
 456 CYStatement 
*CYForInComprehension::Replace(CYContext 
&context
, CYStatement 
*statement
) const { 
 457     return $ 
CYForIn(declaration_
->Target(context
), set_
, CYComprehension::Replace(context
, statement
)); 
 460 CYStatement 
*CYForOf::Replace(CYContext 
&context
) { 
 461     CYIdentifier 
*item(context
.Unique()), *list(context
.Unique()); 
 464         ->* initialiser_
->Initialize(context
, NULL
) 
 465         ->* $ 
CYLet(false, $
L2($
L(list
, set_
), $
L(item
))) 
 466         ->* $ 
CYForIn($
V(item
), $
V(list
), $ 
CYBlock($$
 
 467             ->* initialiser_
->Initialize(context
, $
M($
V(list
), $
V(item
))) 
 472 CYFunctionParameter 
*CYForOfComprehension::Parameter(CYContext 
&context
) const { 
 473     return $ 
CYFunctionParameter(declaration_
); 
 476 CYStatement 
*CYForOfComprehension::Replace(CYContext 
&context
, CYStatement 
*statement
) const { 
 477     CYIdentifier 
*cys($
I("$cys")); 
 479     return $
E($
C0($
F(NULL
, $
P1($
L($
I("$cys"))), $$
->* 
 480         $
E($ 
CYAssign($
V(cys
), set_
))->* 
 481         $ 
CYForIn(declaration_
->Target(context
), $
V(cys
), $ 
CYBlock($$
->* 
 482             $
E($ 
CYAssign(declaration_
->Target(context
), $
M($
V(cys
), declaration_
->Target(context
))))->* 
 483             CYComprehension::Replace(context
, statement
) 
 488 CYStatement 
*CYForVariable::Initialize(CYContext 
&context
, CYExpression 
*value
) { 
 490         if (declaration_
->initialiser_ 
== NULL
) 
 492         value 
= declaration_
->initialiser_
; 
 495     return $ 
CYVar($
L1($ 
CYDeclaration(declaration_
->identifier_
, value
))); 
 498 CYTarget 
*CYForVariable::Replace(CYContext 
&context
) { 
 499     _assert(declaration_
->Replace(context
, CYIdentifierVariable
) == NULL
); 
 500     return declaration_
->Target(context
); 
 503 // XXX: this is evil evil black magic. don't ask, don't tell... don't believe! 
 504 #define MappingSet "0etnirsoalfucdphmgyvbxTwSNECAFjDLkMOIBPqzRH$_WXUVGYKQJZ" 
 505 //#define MappingSet "0abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_" 
 507 void CYFunction::Replace(CYContext 
&context
) { 
 508     CYThisScope 
*_this(context
.this_
); 
 509     context
.this_ 
= &this_
; 
 510     context
.this_ 
= CYGetLast(context
.this_
); 
 512     CYIdentifier 
*super(context
.super_
); 
 513     context
.super_ 
= super_
; 
 515     CYNonLocal 
*nonlocal(context
.nonlocal_
); 
 516     CYNonLocal 
*nextlocal(context
.nextlocal_
); 
 519     if (nonlocal_ 
!= NULL
) { 
 521         context
.nonlocal_ 
= nonlocal_
; 
 524         nonlocal_ 
= $ 
CYNonLocal(); 
 525         context
.nextlocal_ 
= nonlocal_
; 
 528     CYScope 
scope(!localize
, context
); 
 530     parameters_
->Replace(context
, code_
); 
 532     context
.ReplaceAll(code_
); 
 535         CYImplicitReturn(code_
); 
 537     if (CYIdentifier 
*identifier 
= this_
.identifier_
) { 
 538         context
.scope_
->Declare(context
, identifier
, CYIdentifierVariable
); 
 540             ->*$
E($ 
CYAssign($
V(identifier
), $ 
CYThis())) 
 546         context
.NonLocal(code_
); 
 548     context
.nextlocal_ 
= nextlocal
; 
 549     context
.nonlocal_ 
= nonlocal
; 
 551     context
.super_ 
= super
; 
 552     context
.this_ 
= _this
; 
 554     scope
.Close(context
, code_
); 
 557 CYTarget 
*CYFunctionExpression::Replace(CYContext 
&context
) { 
 558     CYScope 
scope(false, context
); 
 560         name_ 
= name_
->Replace(context
, CYIdentifierOther
); 
 562     CYFunction::Replace(context
); 
 563     scope
.Close(context
); 
 567 void CYFunctionParameter::Replace(CYContext 
&context
, CYStatement 
*&statements
) { $
T() 
 568     CYAssignment 
*assignment(initialiser_
->Replace(context
, CYIdentifierArgument
)); 
 570     next_
->Replace(context
, statements
); 
 572     if (assignment 
!= NULL
) 
 574             $ 
CYIf($ 
CYIdentical($ 
CYTypeOf(initialiser_
->Target(context
)), $
S("undefined")), $$
->* 
 580 CYStatement 
*CYFunctionStatement::Replace(CYContext 
&context
) { 
 581     name_ 
= name_
->Replace(context
, CYIdentifierOther
); 
 582     CYFunction::Replace(context
); 
 586 CYIdentifier 
*CYIdentifier::Replace(CYContext 
&context
, CYIdentifierKind kind
) { 
 590         return next_
->Replace(context
, kind
); 
 591     next_ 
= context
.scope_
->Declare(context
, this, kind
)->identifier_
; 
 595 CYStatement 
*CYIf::Return() { 
 596     CYImplicitReturn(true_
); 
 597     CYImplicitReturn(false_
); 
 601 CYStatement 
*CYIf::Replace(CYContext 
&context
) { 
 602     context
.Replace(test_
); 
 603     context
.ReplaceAll(true_
); 
 604     context
.ReplaceAll(false_
); 
 608 CYFunctionParameter 
*CYIfComprehension::Parameter(CYContext 
&context
) const { 
 612 CYStatement 
*CYIfComprehension::Replace(CYContext 
&context
, CYStatement 
*statement
) const { 
 613     return $ 
CYIf(test_
, CYComprehension::Replace(context
, statement
)); 
 616 CYStatement 
*CYImport::Replace(CYContext 
&context
) { 
 617     return $ 
CYVar($
L1($
L($
I(module_
->part_
->Word()), $
C1($
V("require"), module_
->Replace(context
, "/"))))); 
 620 CYTarget 
*CYIndirect::Replace(CYContext 
&context
) { 
 621     return $
M(rhs_
, $
S("$cyi")); 
 624 CYTarget 
*CYIndirectMember::Replace(CYContext 
&context
) { 
 625     return $
M($ 
CYIndirect(object_
), property_
); 
 628 CYExpression 
*CYInfix::Replace(CYContext 
&context
) { 
 629     context
.Replace(lhs_
); 
 630     context
.Replace(rhs_
); 
 634 CYStatement 
*CYLabel::Replace(CYContext 
&context
) { 
 635     context
.Replace(statement_
); 
 639 CYTarget 
*CYLambda::Replace(CYContext 
&context
) { 
 640     return $
N2($
V("Functor"), $ 
CYFunctionExpression(NULL
, parameters_
->Parameters(context
), code_
), parameters_
->TypeSignature(context
, typed_
->Replace(context
))); 
 643 CYForInitializer 
*CYLet::Replace(CYContext 
&context
) { 
 644     if (CYExpression 
*expression 
= declarations_
->Replace(context
, CYIdentifierLexical
)) 
 645         return $
E(expression
); 
 649 CYFunctionExpression 
*CYMethod::Constructor() { 
 653 void CYMethod::Replace(CYContext 
&context
) { 
 654     CYFunction::Replace(context
); 
 657 CYString 
*CYModule::Replace(CYContext 
&context
, const char *separator
) const { 
 659         return $ 
CYString(part_
); 
 660     return $ 
CYString($pool
.strcat(next_
->Replace(context
, separator
)->Value(), separator
, part_
->Word(), NULL
)); 
 663 CYExpression 
*CYMultiply::Replace(CYContext 
&context
) { 
 664     CYInfix::Replace(context
); 
 666     if (CYNumber 
*lhn 
= lhs_
->Number(context
)) 
 667         if (CYNumber 
*rhn 
= rhs_
->Number(context
)) 
 668             return $
D(lhn
->Value() * rhn
->Value()); 
 676 CYTarget 
*New::AddArgument(CYContext 
&context
, CYExpression 
*value
) { 
 677     CYSetLast(arguments_
) = $ 
CYArgument(value
); 
 681 CYTarget 
*New::Replace(CYContext 
&context
) { 
 682     context
.Replace(constructor_
); 
 683     arguments_
->Replace(context
); 
 689 CYNumber 
*CYNull::Number(CYContext 
&context
) { 
 693 CYString 
*CYNull::String(CYContext 
&context
) { 
 697 CYNumber 
*CYNumber::Number(CYContext 
&context
) { 
 701 CYString 
*CYNumber::String(CYContext 
&context
) { 
 702     // XXX: there is a precise algorithm for this 
 703     return $
S($pool
.sprintf(24, "%.17g", Value())); 
 706 CYExpression 
*CYNumber::PropertyName(CYContext 
&context
) { 
 707     return String(context
); 
 710 CYTarget 
*CYObject::Replace(CYContext 
&context
) { 
 712     if (properties_ 
!= NULL
) 
 713         properties_ 
= properties_
->ReplaceAll(context
, builder
, $ 
CYThis(), false); 
 716         return $
C1($
M($ 
CYFunctionExpression(NULL
, builder
.declarations_
->Parameter(context
), 
 717             builder
.statements_
->* 
 718                 $ 
CYReturn($ 
CYThis()) 
 719         ), $
S("call")), this, builder
.declarations_
->Argument(context
)); 
 722     CYForEach (property
, properties_
) 
 723         property
->Replace(context
); 
 727 CYTarget 
*CYParenthetical::Replace(CYContext 
&context
) { 
 728     // XXX: return expression_; 
 729     context
.Replace(expression_
); 
 733 CYExpression 
*CYPostfix::Replace(CYContext 
&context
) { 
 734     context
.Replace(lhs_
); 
 738 CYExpression 
*CYPrefix::Replace(CYContext 
&context
) { 
 739     context
.Replace(rhs_
); 
 743 CYProperty 
*CYProperty::ReplaceAll(CYContext 
&context
, CYBuilder 
&builder
, CYExpression 
*self
, bool update
) { 
 744     update 
|= name_
->Computed(); 
 746         Replace(context
, builder
, self
, false); 
 748         next_ 
= next_
->ReplaceAll(context
, builder
, self
, update
); 
 749     return update 
? next_ 
: this; 
 752 void CYProperty::Replace(CYContext 
&context
, CYBuilder 
&builder
, CYExpression 
*self
, bool protect
) { 
 753     CYExpression 
*name(name_
->PropertyName(context
)); 
 754     if (name_
->Computed()) { 
 755         CYIdentifier 
*unique(context
.Unique()); 
 756         builder
.declarations_
->*$
L1($
L(unique
, name
)); 
 760     Replace(context
, builder
, self
, name
, protect
); 
 763 void CYPropertyGetter::Replace(CYContext 
&context
, CYBuilder 
&builder
, CYExpression 
*self
, CYExpression 
*name
, bool protect
) { 
 764     CYIdentifier 
*unique(context
.Unique()); 
 765     builder
.declarations_
 
 766         ->* $
L1($
L(unique
, CYSuperize(context
, $ 
CYFunctionExpression(NULL
, parameters_
, code_
)))); 
 768         ->* CYDefineProperty(self
, name
, true, !protect
, $ 
CYPropertyValue($
S("get"), $
V(unique
))); 
 771 CYFunctionExpression 
*CYPropertyMethod::Constructor() { 
 772     return name_
->Constructor() ? $ 
CYFunctionExpression(NULL
, parameters_
, code_
) : NULL
; 
 775 void CYPropertyMethod::Replace(CYContext 
&context
, CYBuilder 
&builder
, CYExpression 
*self
, CYExpression 
*name
, bool protect
) { 
 776     CYIdentifier 
*unique(context
.Unique()); 
 777     builder
.declarations_
 
 778         ->* $
L1($
L(unique
, CYSuperize(context
, $ 
CYFunctionExpression(NULL
, parameters_
, code_
)))); 
 780         ->* (!protect 
? $
E($ 
CYAssign($
M(self
, name
), $
V(unique
))) : 
 781             CYDefineProperty(self
, name
, true, !protect
, $ 
CYPropertyValue($
S("value"), $
V(unique
), $ 
CYPropertyValue($
S("writable"), $ 
CYTrue())))); 
 784 void CYPropertySetter::Replace(CYContext 
&context
, CYBuilder 
&builder
, CYExpression 
*self
, CYExpression 
*name
, bool protect
) { 
 785     CYIdentifier 
*unique(context
.Unique()); 
 786     builder
.declarations_
 
 787         ->* $
L1($
L(unique
, CYSuperize(context
, $ 
CYFunctionExpression(NULL
, parameters_
, code_
)))); 
 789         ->* CYDefineProperty(self
, name
, true, !protect
, $ 
CYPropertyValue($
S("set"), $
V(unique
))); 
 792 void CYPropertyValue::Replace(CYContext 
&context
, CYBuilder 
&builder
, CYExpression 
*self
, CYExpression 
*name
, bool protect
) { 
 794     CYIdentifier 
*unique(context
.Unique()); 
 795     builder
.declarations_
 
 796         ->* $
L1($
L(unique
, value_
)); 
 798         ->* $
E($ 
CYAssign($
M(self
, name
), $
V(unique
))); 
 801 void CYPropertyValue::Replace(CYContext 
&context
) { 
 802     context
.Replace(value_
); 
 805 void CYScript::Replace(CYContext 
&context
) { 
 806     CYScope 
scope(false, context
); 
 807     context
.scope_
->Damage(); 
 809     context
.nextlocal_ 
= $ 
CYNonLocal(); 
 810     context
.ReplaceAll(code_
); 
 811     context
.NonLocal(code_
); 
 813     scope
.Close(context
, code_
); 
 817     for (std::vector
<CYIdentifier 
*>::const_iterator 
i(context
.replace_
.begin()); i 
!= context
.replace_
.end(); ++i
) { 
 819         if (context
.options_
.verbose_
) 
 820             name 
= $pool
.strcat("$", $pool
.itoa(offset
++), NULL
); 
 826             unsigned position(7), local(offset
++ + 1); 
 829                 unsigned index(local 
% (sizeof(MappingSet
) - 1)); 
 830                 local 
/= sizeof(MappingSet
) - 1; 
 831                 id
[--position
] = MappingSet
[index
]; 
 832             } while (local 
!= 0); 
 834             if (scope
.Lookup(context
, id 
+ position
) != NULL
) 
 836             // XXX: at some point, this could become a keyword 
 838             name 
= $pool
.strmemdup(id 
+ position
, 7 - position
); 
 841         CYIdentifier 
*identifier(*i
); 
 842         _assert(identifier
->next_ 
== identifier
); 
 843         identifier
->next_ 
= $
I(name
); 
 847 CYStatement 
*CYReturn::Replace(CYContext 
&context
) { 
 848     if (context
.nonlocal_ 
!= NULL
) { 
 849         CYProperty 
*value(value_ 
== NULL 
? NULL 
: $ 
CYPropertyValue($
S("$cyv"), value_
)); 
 850         return $ 
cy::Syntax::Throw($ 
CYObject( 
 851             $ 
CYPropertyValue($
S("$cyk"), $
V(context
.nonlocal_
->Target(context
)), value
) 
 855     context
.Replace(value_
); 
 859 CYTarget 
*CYRubyBlock::Replace(CYContext 
&context
) { 
 860     return call_
->AddArgument(context
, proc_
->Replace(context
)); 
 863 CYTarget 
*CYRubyBlock::AddArgument(CYContext 
&context
, CYExpression 
*value
) { 
 864     return Replace(context
)->AddArgument(context
, value
); 
 867 CYTarget 
*CYRubyProc::Replace(CYContext 
&context
) { 
 868     CYFunctionExpression 
*function($ 
CYFunctionExpression(NULL
, parameters_
, code_
)); 
 869     function 
= CYNonLocalize(context
, function
); 
 870     function
->implicit_ 
= true; 
 874 CYScope::CYScope(bool transparent
, CYContext 
&context
) : 
 875     transparent_(transparent
), 
 876     parent_(context
.scope_
), 
 881     _assert(!transparent_ 
|| parent_ 
!= NULL
); 
 882     context
.scope_ 
= this; 
 885 void CYScope::Damage() { 
 891 CYIdentifierFlags 
*CYScope::Lookup(CYContext 
&context
, const char *word
) { 
 892     CYForEach (i
, internal_
) 
 893         if (strcmp(i
->identifier_
->Word(), word
) == 0) 
 898 CYIdentifierFlags 
*CYScope::Lookup(CYContext 
&context
, CYIdentifier 
*identifier
) { 
 899     return Lookup(context
, identifier
->Word()); 
 902 CYIdentifierFlags 
*CYScope::Declare(CYContext 
&context
, CYIdentifier 
*identifier
, CYIdentifierKind kind
) { 
 903     _assert(identifier
->next_ 
== NULL 
|| identifier
->next_ 
== identifier
); 
 905     CYIdentifierFlags 
*existing(Lookup(context
, identifier
)); 
 906     if (existing 
== NULL
) 
 907         internal_ 
= $ 
CYIdentifierFlags(identifier
, kind
, internal_
); 
 909     if (existing 
== NULL
) 
 913         case CYIdentifierArgument
: 
 914         case CYIdentifierCatch
: 
 915         case CYIdentifierMagic
: 
 921     if (existing
->kind_ 
== CYIdentifierGlobal
) 
 922         existing
->kind_ 
= kind
; 
 923     else if (kind 
== CYIdentifierGlobal
) 
 925     else if (existing
->kind_ 
== CYIdentifierLexical 
|| kind 
== CYIdentifierLexical
) 
 926         _assert(false); // XXX: throw new SyntaxError() 
 931 void CYScope::Merge(CYContext 
&context
, const CYIdentifierFlags 
*flags
) { 
 932     _assert(flags
->identifier_
->next_ 
== flags
->identifier_
); 
 933     CYIdentifierFlags 
*existing(Declare(context
, flags
->identifier_
, flags
->kind_
)); 
 934     flags
->identifier_
->next_ 
= existing
->identifier_
; 
 936     existing
->count_ 
+= flags
->count_
; 
 937     if (existing
->offset_ 
< flags
->offset_
) 
 938         existing
->offset_ 
= flags
->offset_
; 
 941 void CYScope::Close(CYContext 
&context
, CYStatement 
*&statements
) { 
 944     CYList
<CYDeclarations
> declarations
; 
 946     CYForEach (i
, internal_
) 
 947         if (i
->kind_ 
== CYIdentifierVariable
) 
 948             declarations 
->* $ 
CYDeclarations($ 
CYDeclaration(i
->identifier_
)); 
 951         CYVar 
*var($ 
CYVar(declarations
)); 
 952         var
->SetNext(statements
); 
 957 void CYScope::Close(CYContext 
&context
) { 
 958     context
.scope_ 
= parent_
; 
 960     CYForEach (i
, internal_
) { 
 961         _assert(i
->identifier_
->next_ 
== i
->identifier_
); 
 963         case CYIdentifierArgument
: { 
 964             _assert(!transparent_
); 
 967         case CYIdentifierLexical
: { 
 969                 CYIdentifier 
*replace(context
.Unique()); 
 970                 replace
->next_ 
= replace
; 
 971                 i
->identifier_
->next_ 
= replace
; 
 972                 i
->identifier_ 
= replace
; 
 976                 i
->kind_ 
= CYIdentifierVariable
; 
 978                 parent_
->Declare(context
, i
->identifier_
, CYIdentifierVariable
); 
 981         case CYIdentifierVariable
: { 
 983                 parent_
->Declare(context
, i
->identifier_
, i
->kind_
); 
 984                 i
->kind_ 
= CYIdentifierGlobal
; 
 992     typedef std::multimap
<unsigned, CYIdentifier 
*> CYIdentifierOffsetMap
; 
 993     CYIdentifierOffsetMap offsets
; 
 995     CYForEach (i
, internal_
) { 
 996         _assert(i
->identifier_
->next_ 
== i
->identifier_
); 
 998         case CYIdentifierArgument
: 
 999         case CYIdentifierVariable
: 
1000             offsets
.insert(CYIdentifierOffsetMap::value_type(i
->offset_
, i
->identifier_
)); 
1006     for (CYIdentifierOffsetMap::const_iterator 
i(offsets
.begin()); i 
!= offsets
.end(); ++i
) { 
1007         if (offset 
< i
->first
) 
1009         CYIdentifier 
*identifier(i
->second
); 
1011         if (offset 
>= context
.replace_
.size()) 
1012             context
.replace_
.resize(offset 
+ 1, NULL
); 
1013         CYIdentifier 
*&replace(context
.replace_
[offset
++]); 
1015         if (replace 
== NULL
) 
1016             replace 
= identifier
; 
1018             _assert(replace
->next_ 
== replace
); 
1019             identifier
->next_ 
= replace
; 
1023     if (parent_ 
== NULL
) 
1026     CYForEach (i
, internal_
) { 
1028         case CYIdentifierGlobal
: { 
1029             if (i
->offset_ 
< offset
) 
1030                 i
->offset_ 
= offset
; 
1031             parent_
->Merge(context
, i
); 
1036 CYElementValue 
*CYSpan::Replace(CYContext 
&context
) { $
T(NULL
) 
1037     return $ 
CYElementValue(expression_
, $ 
CYElementValue(string_
, next_
->Replace(context
))); 
1040 CYStatement 
*CYStatement::Return() { 
1044 CYString 
*CYString::Concat(CYContext 
&context
, CYString 
*rhs
) const { 
1045     size_t size(size_ 
+ rhs
->size_
); 
1046     char *value($ 
char[size 
+ 1]); 
1047     memcpy(value
, value_
, size_
); 
1048     memcpy(value 
+ size_
, rhs
->value_
, rhs
->size_
); 
1050     return $
S(value
, size
); 
1053 CYNumber 
*CYString::Number(CYContext 
&context
) { 
1054     // XXX: there is a precise algorithm for this 
1058 CYExpression 
*CYString::PropertyName(CYContext 
&context
) { 
1062 CYString 
*CYString::String(CYContext 
&context
) { 
1066 CYTarget 
*CYSuperAccess::Replace(CYContext 
&context
) { 
1067     return $
C1($
M($
M($
M($
V(context
.super_
), $
S("prototype")), property_
), $
S("bind")), $ 
CYThis()); 
1070 CYTarget 
*CYSuperCall::Replace(CYContext 
&context
) { 
1071     return $
C($
C1($
M($
V(context
.super_
), $
S("bind")), $ 
CYThis()), arguments_
); 
1074 CYStatement 
*CYSwitch::Replace(CYContext 
&context
) { 
1075     context
.Replace(value_
); 
1076     clauses_
->Replace(context
); 
1080 CYStatement 
*CYTarget::Initialize(CYContext 
&context
, CYExpression 
*value
) { 
1083     return $
E($ 
CYAssign(this, value
)); 
1086 CYTarget 
*CYTemplate::Replace(CYContext 
&context
) { 
1087     return $
C2($
M($
M($
M($
V("String"), $
S("prototype")), $
S("concat")), $
S("apply")), $
S(""), $ 
CYArray($ 
CYElementValue(string_
, spans_
->Replace(context
)))); 
1090 CYTarget 
*CYThis::Replace(CYContext 
&context
) { 
1091     if (context
.this_ 
!= NULL
) 
1092         return $
V(context
.this_
->Identifier(context
)); 
1099 CYStatement 
*Throw::Replace(CYContext 
&context
) { 
1100     context
.Replace(value_
); 
1106 CYTarget 
*CYTrivial::Replace(CYContext 
&context
) { 
1110 CYNumber 
*CYTrue::Number(CYContext 
&context
) { 
1114 CYString 
*CYTrue::String(CYContext 
&context
) { 
1121 CYStatement 
*Try::Replace(CYContext 
&context
) { 
1122     CYScope 
scope(true, context
); 
1123     context
.ReplaceAll(code_
); 
1124     scope
.Close(context
); 
1126     catch_
->Replace(context
); 
1127     finally_
->Replace(context
); 
1133 CYTarget 
*CYTypeArrayOf::Replace_(CYContext 
&context
, CYTarget 
*type
) { 
1134     return next_
->Replace(context
, $ 
CYCall($ 
CYDirectMember(type
, $ 
CYString("arrayOf")), $ 
CYArgument(size_
))); 
1137 CYTarget 
*CYTypeBlockWith::Replace_(CYContext 
&context
, CYTarget 
*type
) { 
1138     return next_
->Replace(context
, $ 
CYCall($ 
CYDirectMember(type
, $ 
CYString("blockWith")), parameters_
->Argument(context
))); 
1141 CYTarget 
*CYTypeConstant::Replace_(CYContext 
&context
, CYTarget 
*type
) { 
1142     return next_
->Replace(context
, $ 
CYCall($ 
CYDirectMember(type
, $ 
CYString("constant")))); 
1145 CYStatement 
*CYTypeDefinition::Replace(CYContext 
&context
) { 
1146     return $
E($ 
CYAssign($
V(typed_
->identifier_
), typed_
->Replace(context
))); 
1149 CYTarget 
*CYTypeError::Replace(CYContext 
&context
) { 
1154 CYTarget 
*CYTypeModifier::Replace(CYContext 
&context
, CYTarget 
*type
) { $
T(type
) 
1155     return Replace_(context
, type
); 
1158 CYTarget 
*CYTypeFunctionWith::Replace_(CYContext 
&context
, CYTarget 
*type
) { 
1159     return next_
->Replace(context
, $ 
CYCall($ 
CYDirectMember(type
, $ 
CYString("functionWith")), parameters_
->Argument(context
))); 
1162 CYTarget 
*CYTypeLong::Replace(CYContext 
&context
) { 
1163     return $ 
CYCall($ 
CYDirectMember(specifier_
->Replace(context
), $ 
CYString("long"))); 
1166 CYTarget 
*CYTypePointerTo::Replace_(CYContext 
&context
, CYTarget 
*type
) { 
1167     return next_
->Replace(context
, $ 
CYCall($ 
CYDirectMember(type
, $ 
CYString("pointerTo")))); 
1170 CYTarget 
*CYTypeShort::Replace(CYContext 
&context
) { 
1171     return $ 
CYCall($ 
CYDirectMember(specifier_
->Replace(context
), $ 
CYString("short"))); 
1174 CYTarget 
*CYTypeSigned::Replace(CYContext 
&context
) { 
1175     return $ 
CYCall($ 
CYDirectMember(specifier_
->Replace(context
), $ 
CYString("signed"))); 
1178 CYTarget 
*CYTypeUnsigned::Replace(CYContext 
&context
) { 
1179     return $ 
CYCall($ 
CYDirectMember(specifier_
->Replace(context
), $ 
CYString("unsigned"))); 
1182 CYTarget 
*CYTypeVariable::Replace(CYContext 
&context
) { 
1186 CYTarget 
*CYTypeVoid::Replace(CYContext 
&context
) { 
1187     return $
N1($
V("Type"), $ 
CYString("v")); 
1190 CYTarget 
*CYTypeVolatile::Replace_(CYContext 
&context
, CYTarget 
*type
) { 
1191     return next_
->Replace(context
, $ 
CYCall($ 
CYDirectMember(type
, $ 
CYString("volatile")))); 
1194 CYTarget 
*CYTypedIdentifier::Replace(CYContext 
&context
) { 
1195     return modifier_
->Replace(context
, specifier_
->Replace(context
)); 
1198 CYTypeFunctionWith 
*CYTypedIdentifier::Function() { 
1199     CYTypeModifier 
**modifier(&modifier_
); 
1200     if (*modifier 
== NULL
) 
1202     while ((*modifier
)->next_ 
!= NULL
) 
1203         modifier 
= &(*modifier
)->next_
; 
1204     CYTypeFunctionWith 
*function((*modifier
)->Function()); 
1205     if (function 
== NULL
) 
1211 CYArgument 
*CYTypedParameter::Argument(CYContext 
&context
) { $
T(NULL
) 
1212     return $ 
CYArgument(typed_
->Replace(context
), next_
->Argument(context
)); 
1215 CYFunctionParameter 
*CYTypedParameter::Parameters(CYContext 
&context
) { $
T(NULL
) 
1216     return $ 
CYFunctionParameter($ 
CYDeclaration(typed_
->identifier_ 
?: context
.Unique()), next_
->Parameters(context
)); 
1219 CYExpression 
*CYTypedParameter::TypeSignature(CYContext 
&context
, CYExpression 
*prefix
) { $
T(prefix
) 
1220     return next_
->TypeSignature(context
, $ 
CYAdd(prefix
, typed_
->Replace(context
))); 
1223 CYForInitializer 
*CYVar::Replace(CYContext 
&context
) { 
1224     if (CYExpression 
*expression 
= declarations_
->Replace(context
, CYIdentifierVariable
)) 
1225         return $
E(expression
); 
1229 CYTarget 
*CYVariable::Replace(CYContext 
&context
) { 
1230     name_ 
= name_
->Replace(context
, CYIdentifierGlobal
); 
1234 CYFunctionParameter 
*CYVariable::Parameter() const { 
1235     return $ 
CYFunctionParameter($ 
CYDeclaration(name_
)); 
1238 CYStatement 
*CYWhile::Replace(CYContext 
&context
) { 
1239     context
.Replace(test_
); 
1240     context
.ReplaceAll(code_
); 
1244 CYStatement 
*CYWith::Replace(CYContext 
&context
) { 
1245     context
.Replace(scope_
); 
1246     context
.ReplaceAll(code_
); 
1250 CYExpression 
*CYWord::PropertyName(CYContext 
&context
) {