1 /* Cycript - Optimizing JavaScript Compiler/Runtime
2 * Copyright (C) 2009-2010 Jay Freeman (saurik)
5 /* GNU Lesser General Public License, Version 3 {{{ */
7 * Cycript is free software: you can redistribute it and/or modify it under
8 * the terms of the GNU Lesser General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
12 * Cycript is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 * License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with Cycript. If not, see <http://www.gnu.org/licenses/>.
23 #include "Replace.hpp"
27 CYFunctionExpression
*CYNonLocalize(CYContext
&context
, CYFunctionExpression
*function
) {
28 function
->nonlocal_
= context
.nextlocal_
;
32 CYExpression
*CYAdd::Replace(CYContext
&context
) {
33 CYInfix::Replace(context
);
35 CYExpression
*lhp(lhs_
->Primitive(context
));
36 CYExpression
*rhp(rhs_
->Primitive(context
));
38 CYString
*lhs(dynamic_cast<CYString
*>(lhp
));
39 CYString
*rhs(dynamic_cast<CYString
*>(rhp
));
41 if (lhs
!= NULL
|| rhs
!= NULL
) {
43 lhs
= lhp
->String(context
);
46 } else if (rhs
== NULL
) {
47 rhs
= rhp
->String(context
);
52 return lhs
->Concat(context
, rhs
);
55 if (CYNumber
*lhn
= lhp
->Number(context
))
56 if (CYNumber
*rhn
= rhp
->Number(context
))
57 return $
D(lhn
->Value() + rhn
->Value());
62 CYExpression
*CYAddressOf::Replace(CYContext
&context
) {
63 return $
C0($
M(rhs_
, $
S("$cya")));
66 void CYArgument::Replace(CYContext
&context
) { $
T()
67 context
.Replace(value_
);
68 next_
->Replace(context
);
71 CYExpression
*CYArray::Replace(CYContext
&context
) {
72 elements_
->Replace(context
);
76 CYExpression
*CYArrayComprehension::Replace(CYContext
&context
) {
77 CYVariable
*cyv($
V("$cyv"));
79 return $
C0($
F(NULL
, $
P1("$cyv", comprehensions_
->Parameters(context
)), $$
->*
80 $
E($
CYAssign(cyv
, $
CYArray()))->*
81 comprehensions_
->Replace(context
, $
E($
C1($
M(cyv
, $
S("push")), expression_
)))->*
86 CYExpression
*CYAssignment::Replace(CYContext
&context
) {
87 context
.Replace(lhs_
);
88 context
.Replace(rhs_
);
92 CYStatement
*CYBlock::Replace(CYContext
&context
) {
93 context
.ReplaceAll(statements_
);
94 if (statements_
== NULL
)
99 CYStatement
*CYBreak::Replace(CYContext
&context
) {
103 CYExpression
*CYCall::AddArgument(CYContext
&context
, CYExpression
*value
) {
104 CYArgument
**argument(&arguments_
);
105 while (*argument
!= NULL
)
106 argument
= &(*argument
)->next_
;
107 *argument
= $
CYArgument(value
);
111 CYExpression
*CYCall::Replace(CYContext
&context
) {
112 context
.Replace(function_
);
113 arguments_
->Replace(context
);
120 void Catch::Replace(CYContext
&context
) { $
T()
121 CYScope
scope(true, context
, code_
.statements_
);
123 context
.Replace(name_
);
124 context
.scope_
->Declare(context
, name_
, CYIdentifierCatch
);
126 code_
.Replace(context
);
132 void CYClause::Replace(CYContext
&context
) { $
T()
133 context
.Replace(case_
);
134 context
.ReplaceAll(statements_
);
135 next_
->Replace(context
);
138 CYStatement
*CYComment::Replace(CYContext
&context
) {
142 CYExpression
*CYCompound::Replace(CYContext
&context
) {
143 context
.ReplaceAll(expressions_
);
144 if (expressions_
== NULL
)
149 CYFunctionParameter
*CYComprehension::Parameters(CYContext
&context
) const { $
T(NULL
)
150 CYFunctionParameter
*next(next_
->Parameters(context
));
151 if (CYFunctionParameter
*parameter
= Parameter(context
)) {
152 parameter
->SetNext(next
);
158 CYStatement
*CYComprehension::Replace(CYContext
&context
, CYStatement
*statement
) const {
159 return next_
== NULL
? statement
: next_
->Replace(context
, statement
);
162 CYExpression
*CYCondition::Replace(CYContext
&context
) {
163 context
.Replace(test_
);
164 context
.Replace(true_
);
165 context
.Replace(false_
);
169 void CYContext::NonLocal(CYStatement
*&statements
) {
170 CYContext
&context(*this);
172 if (nextlocal_
!= NULL
&& nextlocal_
->identifier_
!= NULL
) {
173 CYIdentifier
*cye($
I("$cye")->Replace(context
));
174 CYIdentifier
*unique(nextlocal_
->identifier_
->Replace(context
));
176 CYStatement
*declare(
177 $
CYVar($
L1($
L(unique
, $
CYObject()))));
179 cy::Syntax::Catch
*rescue(
180 $
cy::Syntax::Catch(cye
, $$
->*
181 $
CYIf($
CYIdentical($
M($
V(cye
), $
S("$cyk")), $
V(unique
)), $$
->*
182 $
CYReturn($
M($
V(cye
), $
S("$cyv"))))->*
183 $
cy::Syntax::Throw($
V(cye
))));
185 context
.Replace(declare
);
186 rescue
->Replace(context
);
190 $
cy::Syntax::Try(statements
, rescue
, NULL
);
194 CYIdentifier
*CYContext::Unique() {
195 return $
CYIdentifier(apr_psprintf($pool
, "$cy%u", unique_
++));
198 CYStatement
*CYContinue::Replace(CYContext
&context
) {
202 CYAssignment
*CYDeclaration::Assignment(CYContext
&context
) {
203 if (initialiser_
== NULL
)
206 CYAssignment
*value($
CYAssign(Variable(context
), initialiser_
));
211 CYVariable
*CYDeclaration::Variable(CYContext
&context
) {
212 return $
V(identifier_
);
215 CYStatement
*CYDeclaration::ForEachIn(CYContext
&context
, CYExpression
*value
) {
216 return $
CYVar($
L1($
L(identifier_
, value
)));
219 CYExpression
*CYDeclaration::Replace(CYContext
&context
) {
220 context
.Replace(identifier_
);
221 context
.scope_
->Declare(context
, identifier_
, CYIdentifierVariable
);
222 return Variable(context
);
225 void CYDeclarations::Replace(CYContext
&context
) { $
T()
226 declaration_
->Replace(context
);
227 next_
->Replace(context
);
230 CYProperty
*CYDeclarations::Property(CYContext
&context
) { $
T(NULL
)
231 return $
CYProperty(declaration_
->identifier_
, declaration_
->initialiser_
?: $U
, next_
->Property(context
));
234 CYFunctionParameter
*CYDeclarations::Parameter(CYContext
&context
) { $
T(NULL
)
235 return $
CYFunctionParameter(declaration_
->identifier_
, next_
->Parameter(context
));
238 CYArgument
*CYDeclarations::Argument(CYContext
&context
) { $
T(NULL
)
239 return $
CYArgument(declaration_
->initialiser_
?: $U
, next_
->Argument(context
));
242 CYCompound
*CYDeclarations::Compound(CYContext
&context
) { $
T(NULL
)
243 CYCompound
*compound(next_
->Compound(context
) ?: $
CYCompound());
244 if (CYAssignment
*assignment
= declaration_
->Assignment(context
))
245 compound
->AddPrev(assignment
);
249 CYExpression
*CYDirectMember::Replace(CYContext
&context
) {
250 context
.Replace(object_
);
251 context
.Replace(property_
);
255 CYStatement
*CYDoWhile::Replace(CYContext
&context
) {
256 context
.Replace(test_
);
257 context
.Replace(code_
);
261 void CYElement::Replace(CYContext
&context
) { $
T()
262 context
.Replace(value_
);
263 next_
->Replace(context
);
266 CYStatement
*CYEmpty::Replace(CYContext
&context
) {
270 CYStatement
*CYExpress::Replace(CYContext
&context
) {
271 while (CYExpress
*express
= dynamic_cast<CYExpress
*>(next_
)) {
272 CYCompound
*compound(dynamic_cast<CYCompound
*>(express
->expression_
));
273 if (compound
== NULL
)
274 compound
= $
CYCompound(express
->expression_
);
275 compound
->AddPrev(expression_
);
276 expression_
= compound
;
277 SetNext(express
->next_
);
280 context
.Replace(expression_
);
281 if (expression_
== NULL
)
287 CYExpression
*CYExpression::AddArgument(CYContext
&context
, CYExpression
*value
) {
288 return $
C1(this, value
);
291 CYExpression
*CYExpression::ClassName(CYContext
&context
, bool object
) {
295 CYStatement
*CYExpression::ForEachIn(CYContext
&context
, CYExpression
*value
) {
296 return $
E($
CYAssign(this, value
));
299 CYAssignment
*CYExpression::Assignment(CYContext
&context
) {
303 CYNumber
*CYFalse::Number(CYContext
&context
) {
307 CYString
*CYFalse::String(CYContext
&context
) {
311 void CYFinally::Replace(CYContext
&context
) { $
T()
312 code_
.Replace(context
);
315 CYStatement
*CYFor::Replace(CYContext
&context
) {
316 context
.Replace(initialiser_
);
317 context
.Replace(test_
);
318 context
.Replace(increment_
);
319 context
.Replace(code_
);
323 CYCompound
*CYForDeclarations::Replace(CYContext
&context
) {
324 declarations_
->Replace(context
);
325 return declarations_
->Compound(context
);
328 // XXX: this still feels highly suboptimal
329 CYStatement
*CYForIn::Replace(CYContext
&context
) {
330 if (CYAssignment
*assignment
= initialiser_
->Assignment(context
))
331 return $
CYBlock($$
->*
336 context
.Replace(initialiser_
);
337 context
.Replace(set_
);
338 context
.Replace(code_
);
342 CYFunctionParameter
*CYForInComprehension::Parameter(CYContext
&context
) const {
343 return $
CYFunctionParameter(name_
);
346 CYStatement
*CYForInComprehension::Replace(CYContext
&context
, CYStatement
*statement
) const {
347 return $
CYForIn($
V(name_
), set_
, CYComprehension::Replace(context
, statement
));
350 CYStatement
*CYForEachIn::Replace(CYContext
&context
) {
351 CYIdentifier
*cys($
I("$cys")), *cyt($
I("$cyt"));
353 return $
CYLet($
L2($
L(cys
, set_
), $
L(cyt
)), $$
->*
354 $
CYForIn($
V(cyt
), $
V(cys
), $
CYBlock($$
->*
355 initialiser_
->ForEachIn(context
, $
M($
V(cys
), $
V(cyt
)))->*
361 CYFunctionParameter
*CYForEachInComprehension::Parameter(CYContext
&context
) const {
362 return $
CYFunctionParameter(name_
);
365 CYStatement
*CYForEachInComprehension::Replace(CYContext
&context
, CYStatement
*statement
) const {
366 CYIdentifier
*cys($
I("cys"));
368 return $
E($
C0($
F(NULL
, $
P1("$cys"), $$
->*
369 $
E($
CYAssign($
V(cys
), set_
))->*
370 $
CYForIn($
V(name_
), $
V(cys
), $
CYBlock($$
->*
371 $
E($
CYAssign($
V(name_
), $
M($
V(cys
), $
V(name_
))))->*
372 CYComprehension::Replace(context
, statement
)
377 void CYFunction::Inject(CYContext
&context
) {
378 context
.Replace(name_
);
379 context
.scope_
->Declare(context
, name_
, CYIdentifierOther
);
382 void CYFunction::Replace_(CYContext
&context
, bool outer
) {
386 CYNonLocal
*nonlocal(context
.nonlocal_
);
387 CYNonLocal
*nextlocal(context
.nextlocal_
);
390 if (nonlocal_
!= NULL
) {
392 context
.nonlocal_
= nonlocal_
;
395 nonlocal_
= $
CYNonLocal();
396 context
.nextlocal_
= nonlocal_
;
399 CYScope
scope(!localize
, context
, code_
.statements_
);
401 if (!outer
&& name_
!= NULL
)
404 if (parameters_
!= NULL
)
405 parameters_
= parameters_
->Replace(context
, code_
);
407 code_
.Replace(context
);
410 context
.NonLocal(code_
.statements_
);
412 context
.nextlocal_
= nextlocal
;
413 context
.nonlocal_
= nonlocal
;
418 CYExpression
*CYFunctionExpression::Replace(CYContext
&context
) {
419 Replace_(context
, false);
423 CYFunctionParameter
*CYFunctionParameter::Replace(CYContext
&context
, CYBlock
&code
) {
424 context
.Replace(name_
);
425 context
.scope_
->Declare(context
, name_
, CYIdentifierArgument
);
427 next_
= next_
->Replace(context
, code
);
431 CYStatement
*CYFunctionStatement::Replace(CYContext
&context
) {
432 Replace_(context
, true);
436 CYIdentifier
*CYIdentifier::Replace(CYContext
&context
) {
437 if (replace_
!= NULL
&& replace_
!= this)
438 return replace_
->Replace(context
);
439 replace_
= context
.scope_
->Lookup(context
, this);
443 CYStatement
*CYIf::Replace(CYContext
&context
) {
444 context
.Replace(test_
);
445 context
.Replace(true_
);
446 context
.Replace(false_
);
450 CYFunctionParameter
*CYIfComprehension::Parameter(CYContext
&context
) const {
454 CYStatement
*CYIfComprehension::Replace(CYContext
&context
, CYStatement
*statement
) const {
455 return $
CYIf(test_
, CYComprehension::Replace(context
, statement
));
458 CYExpression
*CYIndirect::Replace(CYContext
&context
) {
459 return $
M(rhs_
, $
S("$cyi"));
462 CYExpression
*CYIndirectMember::Replace(CYContext
&context
) {
463 return $
M($
CYIndirect(object_
), property_
);
466 CYExpression
*CYInfix::Replace(CYContext
&context
) {
467 context
.Replace(lhs_
);
468 context
.Replace(rhs_
);
472 CYStatement
*CYLabel::Replace(CYContext
&context
) {
473 context
.Replace(statement_
);
477 CYStatement
*CYLet::Replace(CYContext
&context
) {
478 return $
E($
CYCall(CYNonLocalize(context
, $
CYFunctionExpression(NULL
, declarations_
->Parameter(context
), code_
)), declarations_
->Argument(context
)));
484 CYExpression
*New::AddArgument(CYContext
&context
, CYExpression
*value
) {
485 CYSetLast(arguments_
, $
CYArgument(value
));
489 CYExpression
*New::Replace(CYContext
&context
) {
490 context
.Replace(constructor_
);
491 arguments_
->Replace(context
);
497 CYNumber
*CYNull::Number(CYContext
&context
) {
501 CYString
*CYNull::String(CYContext
&context
) {
505 CYNumber
*CYNumber::Number(CYContext
&context
) {
509 CYString
*CYNumber::String(CYContext
&context
) {
510 // XXX: there is a precise algorithm for this
511 return $
S(apr_psprintf($pool
, "%.17g", Value()));
514 CYExpression
*CYObject::Replace(CYContext
&context
) {
515 properties_
->Replace(context
);
519 CYFunctionParameter
*CYOptionalFunctionParameter::Replace(CYContext
&context
, CYBlock
&code
) {
520 CYFunctionParameter
*parameter($
CYFunctionParameter(name_
, next_
));
521 parameter
= parameter
->Replace(context
, code
);
522 context
.Replace(initializer_
);
524 CYVariable
*name($
V(name_
));
525 code
.AddPrev($
CYIf($
CYIdentical($
CYTypeOf(name
), $
S("undefined")), $$
->*
526 $
E($
CYAssign(name
, initializer_
))
532 CYExpression
*CYPostfix::Replace(CYContext
&context
) {
533 context
.Replace(lhs_
);
537 CYExpression
*CYPrefix::Replace(CYContext
&context
) {
538 context
.Replace(rhs_
);
542 // XXX: this is evil evil black magic. don't ask, don't tell... don't believe!
543 #define MappingSet "0etnirsoalfucdphmgyvbxTwSNECAFjDLkMOIBPqzRH$_WXUVGYKQJZ"
544 //#define MappingSet "0abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_"
547 struct IdentifierUsageLess
:
548 std::binary_function
<CYIdentifier
*, CYIdentifier
*, bool>
550 _finline
bool operator ()(CYIdentifier
*lhs
, CYIdentifier
*rhs
) const {
551 if (lhs
->usage_
!= rhs
->usage_
)
552 return lhs
->usage_
> rhs
->usage_
;
557 typedef std::set
<CYIdentifier
*, IdentifierUsageLess
> IdentifierUsages
;
560 void CYProgram::Replace(CYContext
&context
) {
561 CYScope
scope(true, context
, statements_
);
563 context
.nextlocal_
= $
CYNonLocal();
564 context
.ReplaceAll(statements_
);
565 context
.NonLocal(statements_
);
571 CYCStringSet external
;
572 for (CYIdentifierValueSet::const_iterator
i(scope
.identifiers_
.begin()); i
!= scope
.identifiers_
.end(); ++i
)
573 external
.insert((*i
)->Word());
575 IdentifierUsages usages
;
577 if (offset
< context
.rename_
.size())
578 CYForEach (i
, context
.rename_
[offset
].identifier_
)
581 // XXX: totalling the probable occurrences and sorting by them would improve the result
582 for (CYIdentifierUsageVector::const_iterator
i(context
.rename_
.begin()); i
!= context
.rename_
.end(); ++i
, ++offset
) {
583 //std::cout << *i << ":" << (*i)->offset_ << std::endl;
587 if (context
.options_
.verbose_
)
588 name
= apr_psprintf($pool
, "$%"APR_SIZE_T_FMT
"", offset
);
594 unsigned position(7), local(offset
+ 1);
597 unsigned index(local
% (sizeof(MappingSet
) - 1));
598 local
/= sizeof(MappingSet
) - 1;
599 id
[--position
] = MappingSet
[index
];
600 } while (local
!= 0);
602 if (external
.find(id
+ position
) != external
.end()) {
607 name
= apr_pstrmemdup($pool
, id
+ position
, 7 - position
);
608 // XXX: at some point, this could become a keyword
611 CYForEach (identifier
, i
->identifier_
)
612 identifier
->Set(name
);
616 void CYProperty::Replace(CYContext
&context
) { $
T()
617 context
.Replace(value_
);
618 next_
->Replace(context
);
621 CYStatement
*CYReturn::Replace(CYContext
&context
) {
622 if (context
.nonlocal_
!= NULL
) {
623 CYProperty
*value(value_
== NULL
? NULL
: $
CYProperty($
S("$cyv"), value_
));
624 return $
cy::Syntax::Throw($
CYObject(
625 $
CYProperty($
S("$cyk"), $
V(context
.nonlocal_
->Target(context
)), value
)
629 context
.Replace(value_
);
633 CYExpression
*CYRubyBlock::Replace(CYContext
&context
) {
634 // XXX: this needs to do something much more epic to handle return
635 return call_
->AddArgument(context
, proc_
->Replace(context
));
638 CYExpression
*CYRubyProc::Replace(CYContext
&context
) {
639 return CYNonLocalize(context
, $
CYFunctionExpression(NULL
, parameters_
, code_
));
642 CYScope::CYScope(bool transparent
, CYContext
&context
, CYStatement
*&statements
) :
643 transparent_(transparent
),
645 statements_(statements
),
646 parent_(context
.scope_
)
648 context_
.scope_
= this;
651 CYScope::~CYScope() {
654 void CYScope::Close() {
655 context_
.scope_
= parent_
;
656 Scope(context_
, statements_
);
659 void CYScope::Declare(CYContext
&context
, CYIdentifier
*identifier
, CYIdentifierFlags flags
) {
660 if (!transparent_
|| flags
== CYIdentifierArgument
|| flags
== CYIdentifierCatch
)
661 internal_
.insert(CYIdentifierAddressFlagsMap::value_type(identifier
, flags
));
662 else if (parent_
!= NULL
)
663 parent_
->Declare(context
, identifier
, flags
);
666 CYIdentifier
*CYScope::Lookup(CYContext
&context
, CYIdentifier
*identifier
) {
667 std::pair
<CYIdentifierValueSet::iterator
, bool> insert(identifiers_
.insert(identifier
));
668 return *insert
.first
;
671 void CYScope::Merge(CYContext
&context
, CYIdentifier
*identifier
) {
672 std::pair
<CYIdentifierValueSet::iterator
, bool> insert(identifiers_
.insert(identifier
));
673 if (!insert
.second
) {
674 if ((*insert
.first
)->offset_
< identifier
->offset_
)
675 (*insert
.first
)->offset_
= identifier
->offset_
;
676 identifier
->replace_
= *insert
.first
;
677 (*insert
.first
)->usage_
+= identifier
->usage_
+ 1;
682 struct IdentifierOffset
{
684 CYIdentifierFlags flags_
;
686 CYIdentifier
*identifier_
;
688 IdentifierOffset(CYIdentifier
*identifier
, CYIdentifierFlags flags
) :
689 offset_(identifier
->offset_
),
691 usage_(identifier
->usage_
),
692 identifier_(identifier
)
697 struct IdentifierOffsetLess
:
698 std::binary_function
<const IdentifierOffset
&, const IdentifierOffset
&, bool>
700 _finline
bool operator ()(const IdentifierOffset
&lhs
, const IdentifierOffset
&rhs
) const {
701 if (lhs
.offset_
!= rhs
.offset_
)
702 return lhs
.offset_
< rhs
.offset_
;
703 if (lhs
.flags_
!= rhs
.flags_
)
704 return lhs
.flags_
< rhs
.flags_
;
705 /*if (lhs.usage_ != rhs.usage_)
706 return lhs.usage_ < rhs.usage_;*/
707 return lhs
.identifier_
< rhs
.identifier_
;
711 typedef std::set
<IdentifierOffset
, IdentifierOffsetLess
> IdentifierOffsets
;
714 void CYScope::Scope(CYContext
&context
, CYStatement
*&statements
) {
718 CYDeclarations
*last(NULL
), *curr(NULL
);
720 IdentifierOffsets offsets
;
722 for (CYIdentifierAddressFlagsMap::const_iterator
i(internal_
.begin()); i
!= internal_
.end(); ++i
)
723 if (i
->second
!= CYIdentifierMagic
)
724 offsets
.insert(IdentifierOffset(i
->first
, i
->second
));
728 for (IdentifierOffsets::const_iterator
i(offsets
.begin()); i
!= offsets
.end(); ++i
) {
729 if (i
->flags_
== CYIdentifierVariable
) {
730 CYDeclarations
*next($
CYDeclarations($
CYDeclaration(i
->identifier_
)));
738 if (offset
< i
->offset_
)
740 if (context
.rename_
.size() <= offset
)
741 context
.rename_
.resize(offset
+ 1);
743 CYIdentifierUsage
&rename(context
.rename_
[offset
++]);
744 i
->identifier_
->SetNext(rename
.identifier_
);
745 rename
.identifier_
= i
->identifier_
;
746 rename
.usage_
+= i
->identifier_
->usage_
+ 1;
750 CYVar
*var($
CYVar(last
));
751 var
->SetNext(statements
);
755 for (CYIdentifierValueSet::const_iterator
i(identifiers_
.begin()); i
!= identifiers_
.end(); ++i
)
756 if (internal_
.find(*i
) == internal_
.end()) {
757 //std::cout << *i << '=' << offset << std::endl;
758 if ((*i
)->offset_
< offset
)
759 (*i
)->offset_
= offset
;
760 parent_
->Merge(context
, *i
);
764 CYString
*CYString::Concat(CYContext
&context
, CYString
*rhs
) const {
765 size_t size(size_
+ rhs
->size_
);
766 char *value($
char[size
+ 1]);
767 memcpy(value
, value_
, size_
);
768 memcpy(value
+ size_
, rhs
->value_
, rhs
->size_
);
770 return $
S(value
, size
);
773 CYNumber
*CYString::Number(CYContext
&context
) {
774 // XXX: there is a precise algorithm for this
778 CYString
*CYString::String(CYContext
&context
) {
782 CYStatement
*CYSwitch::Replace(CYContext
&context
) {
783 context
.Replace(value_
);
784 clauses_
->Replace(context
);
788 CYExpression
*CYThis::Replace(CYContext
&context
) {
795 CYStatement
*Throw::Replace(CYContext
&context
) {
796 context
.Replace(value_
);
802 CYExpression
*CYTrivial::Replace(CYContext
&context
) {
806 CYNumber
*CYTrue::Number(CYContext
&context
) {
810 CYString
*CYTrue::String(CYContext
&context
) {
817 CYStatement
*Try::Replace(CYContext
&context
) {
818 code_
.Replace(context
);
819 catch_
->Replace(context
);
820 finally_
->Replace(context
);
826 CYStatement
*CYVar::Replace(CYContext
&context
) {
827 declarations_
->Replace(context
);
828 return $
E(declarations_
->Compound(context
));
831 CYExpression
*CYVariable::Replace(CYContext
&context
) {
832 context
.Replace(name_
);
836 CYStatement
*CYWhile::Replace(CYContext
&context
) {
837 context
.Replace(test_
);
838 context
.Replace(code_
);
842 CYStatement
*CYWith::Replace(CYContext
&context
) {
843 context
.Replace(scope_
);
844 context
.Replace(code_
);
848 CYExpression
*CYWord::ClassName(CYContext
&context
, bool object
) {
849 CYString
*name($
S(this));
851 return $
C1($
V("objc_getClass"), name
);