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 CYExpression
*CYAdd::Replace(CYContext
&context
) {
28 CYInfix::Replace(context
);
30 CYExpression
*lhp(lhs_
->Primitive(context
));
31 CYExpression
*rhp(rhs_
->Primitive(context
));
33 CYString
*lhs(dynamic_cast<CYString
*>(lhp
));
34 CYString
*rhs(dynamic_cast<CYString
*>(rhp
));
36 if (lhs
!= NULL
|| rhs
!= NULL
) {
38 lhs
= lhp
->String(context
);
41 } else if (rhs
== NULL
) {
42 rhs
= rhp
->String(context
);
47 return lhs
->Concat(context
, rhs
);
50 if (CYNumber
*lhn
= lhp
->Number(context
))
51 if (CYNumber
*rhn
= rhp
->Number(context
))
52 return $
D(lhn
->Value() + rhn
->Value());
57 CYExpression
*CYAddressOf::Replace(CYContext
&context
) {
58 CYPrefix::Replace(context
);
59 return $
C0($
M(rhs_
, $
S("$cya")));
62 void CYArgument::Replace(CYContext
&context
) { $
T()
63 context
.Replace(value_
);
64 next_
->Replace(context
);
67 CYExpression
*CYArray::Replace(CYContext
&context
) {
68 elements_
->Replace(context
);
72 CYExpression
*CYArrayComprehension::Replace(CYContext
&context
) {
73 CYVariable
*cyv($
V("$cyv"));
75 return $
C0($
F(NULL
, $
P1("$cyv", comprehensions_
->Parameters(context
)), $$
->*
76 $
E($
CYAssign(cyv
, $
CYArray()))->*
77 comprehensions_
->Replace(context
, $
E($
C1($
M(cyv
, $
S("push")), expression_
)))->*
82 CYExpression
*CYAssignment::Replace(CYContext
&context
) {
83 context
.Replace(lhs_
);
84 context
.Replace(rhs_
);
88 CYStatement
*CYBlock::Replace(CYContext
&context
) {
89 statements_
= statements_
->ReplaceAll(context
);
90 if (statements_
== NULL
)
95 CYStatement
*CYBreak::Replace(CYContext
&context
) {
99 CYExpression
*CYCall::AddArgument(CYContext
&context
, CYExpression
*value
) {
100 CYArgument
**argument(&arguments_
);
101 while (*argument
!= NULL
)
102 argument
= &(*argument
)->next_
;
103 *argument
= $
CYArgument(value
);
107 CYExpression
*CYCall::Replace(CYContext
&context
) {
108 context
.Replace(function_
);
109 arguments_
->Replace(context
);
116 void Catch::Replace(CYContext
&context
) { $
T()
117 CYScope
scope(CYScopeCatch
, context
, code_
.statements_
);
119 context
.Replace(name_
);
120 context
.scope_
->Declare(context
, name_
, CYIdentifierCatch
);
122 code_
.Replace(context
);
128 void CYClause::Replace(CYContext
&context
) { $
T()
129 context
.Replace(case_
);
130 statements_
= statements_
->ReplaceAll(context
);
131 next_
->Replace(context
);
134 CYStatement
*CYComment::Replace(CYContext
&context
) {
138 CYExpression
*CYCompound::Replace(CYContext
&context
) {
139 CYExpression
**last(&expressions_
);
140 for (CYExpression
*next(expressions_
); next
!= NULL
; next
= next
->next_
)
141 last
= &(*last
= next
->Replace(context
))->next_
;
145 CYFunctionParameter
*CYComprehension::Parameters(CYContext
&context
) const { $
T(NULL
)
146 CYFunctionParameter
*next(next_
->Parameters(context
));
147 if (CYFunctionParameter
*parameter
= Parameter(context
)) {
148 parameter
->SetNext(next
);
154 CYStatement
*CYComprehension::Replace(CYContext
&context
, CYStatement
*statement
) const {
155 return next_
== NULL
? statement
: next_
->Replace(context
, statement
);
158 CYExpression
*CYCondition::Replace(CYContext
&context
) {
159 context
.Replace(test_
);
160 context
.Replace(true_
);
161 context
.Replace(false_
);
165 void CYContext::NonLocal(CYStatement
*&statements
) {
166 CYContext
&context(*this);
168 if (nextlocal_
!= NULL
&& nextlocal_
->identifier_
!= NULL
) {
169 CYIdentifier
*cye($
I("$cye")->Replace(context
));
170 CYIdentifier
*unique(nextlocal_
->identifier_
->Replace(context
));
172 CYStatement
*declare(
173 $
CYVar($
L1($
L(unique
, $
CYObject()))));
175 cy::Syntax::Catch
*rescue(
176 $
cy::Syntax::Catch(cye
, $$
->*
177 $
CYIf($
CYIdentical($
M($
V(cye
), $
S("$cyk")), $
V(unique
)), $$
->*
178 $
CYReturn($
M($
V(cye
), $
S("$cyv"))))->*
179 $
cy::Syntax::Throw($
V(cye
))));
181 context
.Replace(declare
);
182 rescue
->Replace(context
);
186 $
cy::Syntax::Try(statements
, rescue
, NULL
);
190 CYIdentifier
*CYContext::Unique() {
191 return $
CYIdentifier(apr_psprintf($pool
, "$cy%u", unique_
++));
194 CYStatement
*CYContinue::Replace(CYContext
&context
) {
198 CYAssignment
*CYDeclaration::Assignment(CYContext
&context
) {
199 CYExpression
*variable(Replace(context
));
200 return initialiser_
== NULL
? NULL
: $
CYAssign(variable
, initialiser_
);
203 CYExpression
*CYDeclaration::ForEachIn(CYContext
&context
) {
204 return $
V(identifier_
);
207 CYExpression
*CYDeclaration::Replace(CYContext
&context
) {
208 context
.Replace(identifier_
);
209 context
.scope_
->Declare(context
, identifier_
, CYIdentifierVariable
);
210 return $
V(identifier_
);
213 CYProperty
*CYDeclarations::Property(CYContext
&context
) { $
T(NULL
)
214 return $
CYProperty(declaration_
->identifier_
, declaration_
->initialiser_
?: $U
, next_
->Property(context
));
217 CYCompound
*CYDeclarations::Replace(CYContext
&context
) {
218 CYCompound
*compound
;
219 if (next_
== NULL
) compound
:
220 compound
= $
CYCompound();
222 compound
= next_
->Replace(context
);
223 if (compound
== NULL
)
227 if (CYAssignment
*assignment
= declaration_
->Assignment(context
))
228 compound
->AddPrev(assignment
);
232 CYExpression
*CYDirectMember::Replace(CYContext
&context
) {
237 CYStatement
*CYDoWhile::Replace(CYContext
&context
) {
238 context
.Replace(test_
);
239 context
.Replace(code_
);
243 void CYElement::Replace(CYContext
&context
) { $
T()
244 context
.Replace(value_
);
245 next_
->Replace(context
);
248 CYStatement
*CYEmpty::Collapse(CYContext
&context
) {
252 CYStatement
*CYEmpty::Replace(CYContext
&context
) {
256 CYStatement
*CYExpress::Collapse(CYContext
&context
) {
257 if (CYExpress
*express
= dynamic_cast<CYExpress
*>(next_
)) {
258 CYCompound
*next(dynamic_cast<CYCompound
*>(express
->expression_
));
260 next
= $
CYCompound(express
->expression_
);
261 next
->AddPrev(expression_
);
263 SetNext(express
->next_
);
269 CYStatement
*CYExpress::Replace(CYContext
&context
) {
270 context
.Replace(expression_
);
271 if (expression_
== NULL
)
276 CYExpression
*CYExpression::AddArgument(CYContext
&context
, CYExpression
*value
) {
277 return $
C1(this, value
);
280 CYExpression
*CYExpression::ClassName(CYContext
&context
, bool object
) {
284 CYExpression
*CYExpression::ForEachIn(CYContext
&context
) {
288 CYNumber
*CYFalse::Number(CYContext
&context
) {
292 CYString
*CYFalse::String(CYContext
&context
) {
296 void CYFinally::Replace(CYContext
&context
) { $
T()
297 code_
.Replace(context
);
300 CYStatement
*CYFor::Replace(CYContext
&context
) {
301 context
.Replace(initialiser_
);
302 context
.Replace(test_
);
303 context
.Replace(increment_
);
304 context
.Replace(code_
);
308 CYStatement
*CYForIn::Replace(CYContext
&context
) {
309 // XXX: this actually might need a prefix statement
310 context
.Replace(initialiser_
);
311 context
.Replace(set_
);
312 context
.Replace(code_
);
316 CYFunctionParameter
*CYForInComprehension::Parameter(CYContext
&context
) const {
317 return $
CYFunctionParameter(name_
);
320 CYStatement
*CYForInComprehension::Replace(CYContext
&context
, CYStatement
*statement
) const {
321 return $
CYForIn($
V(name_
), set_
, CYComprehension::Replace(context
, statement
));
324 CYStatement
*CYForEachIn::Replace(CYContext
&context
) {
325 CYIdentifier
*cys($
I("$cys")), *cyt($
I("$cyt"));
327 return $
CYLet($
L2($
L(cys
, set_
), $
L(cyt
)), $$
->*
328 $
CYForIn($
V(cyt
), $
V(cys
), $
CYBlock($$
->*
329 $
E($
CYAssign(initialiser_
->ForEachIn(context
), $
M($
V(cys
), $
V(cyt
))))->*
335 CYFunctionParameter
*CYForEachInComprehension::Parameter(CYContext
&context
) const {
336 return $
CYFunctionParameter(name_
);
339 CYStatement
*CYForEachInComprehension::Replace(CYContext
&context
, CYStatement
*statement
) const {
340 CYIdentifier
*cys($
I("cys"));
342 return $
E($
C0($
F(NULL
, $
P1("$cys"), $$
->*
343 $
E($
CYAssign($
V(cys
), set_
))->*
344 $
CYForIn($
V(name_
), $
V(cys
), $
CYBlock($$
->*
345 $
E($
CYAssign($
V(name_
), $
M($
V(cys
), $
V(name_
))))->*
346 CYComprehension::Replace(context
, statement
)
351 void CYFunction::Inject(CYContext
&context
) {
352 context
.Replace(name_
);
353 context
.scope_
->Declare(context
, name_
, CYIdentifierOther
);
356 void CYFunction::Replace_(CYContext
&context
, bool outer
) {
360 CYScope
scope(CYScopeFunction
, context
, code_
.statements_
);
362 CYNonLocal
*nonlocal(context
.nonlocal_
);
363 CYNonLocal
*nextlocal(context
.nextlocal_
);
366 if (nonlocal_
!= NULL
) {
368 context
.nonlocal_
= nonlocal_
;
371 nonlocal_
= $
CYNonLocal();
372 context
.nextlocal_
= nonlocal_
;
375 if (!outer
&& name_
!= NULL
)
378 if (parameters_
!= NULL
)
379 parameters_
= parameters_
->Replace(context
, code_
);
381 code_
.Replace(context
);
384 context
.NonLocal(code_
.statements_
);
386 context
.nextlocal_
= nextlocal
;
387 context
.nonlocal_
= nonlocal
;
392 CYExpression
*CYFunctionExpression::Replace(CYContext
&context
) {
393 Replace_(context
, false);
397 CYFunctionParameter
*CYFunctionParameter::Replace(CYContext
&context
, CYBlock
&code
) {
398 context
.Replace(name_
);
399 context
.scope_
->Declare(context
, name_
, CYIdentifierArgument
);
401 next_
= next_
->Replace(context
, code
);
405 CYStatement
*CYFunctionStatement::Replace(CYContext
&context
) {
406 Replace_(context
, true);
410 CYIdentifier
*CYIdentifier::Replace(CYContext
&context
) {
411 if (replace_
!= NULL
&& replace_
!= this)
412 return replace_
->Replace(context
);
413 replace_
= context
.scope_
->Lookup(context
, this);
417 CYStatement
*CYIf::Replace(CYContext
&context
) {
418 context
.Replace(test_
);
419 context
.Replace(true_
);
420 context
.Replace(false_
);
424 CYFunctionParameter
*CYIfComprehension::Parameter(CYContext
&context
) const {
428 CYStatement
*CYIfComprehension::Replace(CYContext
&context
, CYStatement
*statement
) const {
429 return $
CYIf(test_
, CYComprehension::Replace(context
, statement
));
432 CYExpression
*CYIndirect::Replace(CYContext
&context
) {
433 CYPrefix::Replace(context
);
434 return $
M(rhs_
, $
S("$cyi"));
437 CYExpression
*CYIndirectMember::Replace(CYContext
&context
) {
439 return $
M($
CYIndirect(object_
), property_
);
442 CYExpression
*CYInfix::Replace(CYContext
&context
) {
443 context
.Replace(lhs_
);
444 context
.Replace(rhs_
);
448 CYStatement
*CYLabel::Replace(CYContext
&context
) {
449 context
.Replace(statement_
);
453 CYStatement
*CYLet::Replace(CYContext
&context
) {
454 return $
CYWith($
CYObject(declarations_
->Property(context
)), &code_
);
457 void CYMember::Replace_(CYContext
&context
) {
458 context
.Replace(object_
);
459 context
.Replace(property_
);
465 CYExpression
*New::AddArgument(CYContext
&context
, CYExpression
*value
) {
466 CYArgument
**argument(&arguments_
);
467 while (*argument
!= NULL
)
468 argument
= &(*argument
)->next_
;
469 *argument
= $
CYArgument(value
);
473 CYExpression
*New::Replace(CYContext
&context
) {
474 context
.Replace(constructor_
);
475 arguments_
->Replace(context
);
481 CYNumber
*CYNull::Number(CYContext
&context
) {
485 CYString
*CYNull::String(CYContext
&context
) {
489 CYNumber
*CYNumber::Number(CYContext
&context
) {
493 CYString
*CYNumber::String(CYContext
&context
) {
494 // XXX: there is a precise algorithm for this
495 return $
S(apr_psprintf($pool
, "%.17g", Value()));
498 CYExpression
*CYObject::Replace(CYContext
&context
) {
499 properties_
->Replace(context
);
503 CYFunctionParameter
*CYOptionalFunctionParameter::Replace(CYContext
&context
, CYBlock
&code
) {
504 CYFunctionParameter
*parameter($
CYFunctionParameter(name_
, next_
));
505 parameter
= parameter
->Replace(context
, code
);
506 context
.Replace(initializer_
);
508 CYVariable
*name($
V(name_
));
509 code
.AddPrev($
CYIf($
CYIdentical($
CYTypeOf(name
), $
S("undefined")), $$
->*
510 $
E($
CYAssign(name
, initializer_
))
516 CYExpression
*CYPostfix::Replace(CYContext
&context
) {
517 context
.Replace(lhs_
);
521 CYExpression
*CYPrefix::Replace(CYContext
&context
) {
522 context
.Replace(rhs_
);
526 // XXX: this is evil evil black magic. don't ask, don't tell... don't believe!
527 #define MappingSet "0etnirsoalfucdphmgyvbxTwSNECAFjDLkMOIBPqzRH$_WXUVGYKQJZ"
528 //#define MappingSet "0abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_"
531 struct IdentifierUsageLess
:
532 std::binary_function
<CYIdentifier
*, CYIdentifier
*, bool>
534 _finline
bool operator ()(CYIdentifier
*lhs
, CYIdentifier
*rhs
) const {
535 if (lhs
->usage_
!= rhs
->usage_
)
536 return lhs
->usage_
> rhs
->usage_
;
541 typedef std::set
<CYIdentifier
*, IdentifierUsageLess
> IdentifierUsages
;
544 void CYProgram::Replace(CYContext
&context
) {
545 CYScope
scope(CYScopeProgram
, context
, statements_
);
547 context
.nextlocal_
= $
CYNonLocal();
548 statements_
= statements_
->ReplaceAll(context
);
549 context
.NonLocal(statements_
);
555 CYCStringSet external
;
556 for (CYIdentifierValueSet::const_iterator
i(scope
.identifiers_
.begin()); i
!= scope
.identifiers_
.end(); ++i
)
557 external
.insert((*i
)->Word());
559 IdentifierUsages usages
;
561 if (offset
< context
.rename_
.size())
562 for (CYIdentifier
*i(context
.rename_
[offset
].identifier_
); i
!= NULL
; i
= i
->next_
)
565 // XXX: totalling the probable occurrences and sorting by them would improve the result
566 for (CYIdentifierUsageVector::const_iterator
i(context
.rename_
.begin()); i
!= context
.rename_
.end(); ++i
, ++offset
) {
567 //std::cout << *i << ":" << (*i)->offset_ << std::endl;
571 if (context
.options_
.verbose_
)
572 name
= apr_psprintf($pool
, "$%"APR_SIZE_T_FMT
"", offset
);
578 unsigned position(7), local(offset
+ 1);
581 unsigned index(local
% (sizeof(MappingSet
) - 1));
582 local
/= sizeof(MappingSet
) - 1;
583 id
[--position
] = MappingSet
[index
];
584 } while (local
!= 0);
586 if (external
.find(id
+ position
) != external
.end()) {
591 name
= apr_pstrmemdup($pool
, id
+ position
, 7 - position
);
592 // XXX: at some point, this could become a keyword
595 for (CYIdentifier
*identifier(i
->identifier_
); identifier
!= NULL
; identifier
= identifier
->next_
)
596 identifier
->Set(name
);
600 void CYProperty::Replace(CYContext
&context
) { $
T()
601 context
.Replace(value_
);
602 next_
->Replace(context
);
605 CYStatement
*CYReturn::Replace(CYContext
&context
) {
606 if (context
.nonlocal_
!= NULL
) {
607 CYProperty
*value(value_
== NULL
? NULL
: $
CYProperty($
S("$cyv"), value_
));
608 return $
cy::Syntax::Throw($
CYObject(
609 $
CYProperty($
S("$cyk"), $
V(context
.nonlocal_
->Target(context
)), value
)
613 context
.Replace(value_
);
617 CYExpression
*CYRubyBlock::Replace(CYContext
&context
) {
618 // XXX: this needs to do something much more epic to handle return
619 return call_
->AddArgument(context
, proc_
->Replace(context
));
622 CYExpression
*CYRubyProc::Replace(CYContext
&context
) {
623 CYFunctionExpression
*function($
CYFunctionExpression(NULL
, parameters_
, code_
));
624 function
->nonlocal_
= context
.nextlocal_
;
628 CYScope::CYScope(CYScopeType type
, CYContext
&context
, CYStatement
*&statements
) :
631 statements_(statements
),
632 parent_(context
.scope_
)
634 context_
.scope_
= this;
637 void CYScope::Close() {
638 context_
.scope_
= parent_
;
639 Scope(context_
, statements_
);
642 void CYScope::Declare(CYContext
&context
, CYIdentifier
*identifier
, CYIdentifierFlags flags
) {
643 if (type_
== CYScopeCatch
&& flags
!= CYIdentifierCatch
)
644 parent_
->Declare(context
, identifier
, flags
);
646 internal_
.insert(CYIdentifierAddressFlagsMap::value_type(identifier
, flags
));
649 CYIdentifier
*CYScope::Lookup(CYContext
&context
, CYIdentifier
*identifier
) {
650 std::pair
<CYIdentifierValueSet::iterator
, bool> insert(identifiers_
.insert(identifier
));
651 return *insert
.first
;
654 void CYScope::Merge(CYContext
&context
, CYIdentifier
*identifier
) {
655 std::pair
<CYIdentifierValueSet::iterator
, bool> insert(identifiers_
.insert(identifier
));
656 if (!insert
.second
) {
657 if ((*insert
.first
)->offset_
< identifier
->offset_
)
658 (*insert
.first
)->offset_
= identifier
->offset_
;
659 identifier
->replace_
= *insert
.first
;
660 (*insert
.first
)->usage_
+= identifier
->usage_
+ 1;
665 struct IdentifierOffset
{
667 CYIdentifierFlags flags_
;
669 CYIdentifier
*identifier_
;
671 IdentifierOffset(CYIdentifier
*identifier
, CYIdentifierFlags flags
) :
672 offset_(identifier
->offset_
),
674 usage_(identifier
->usage_
),
675 identifier_(identifier
)
680 struct IdentifierOffsetLess
:
681 std::binary_function
<const IdentifierOffset
&, const IdentifierOffset
&, bool>
683 _finline
bool operator ()(const IdentifierOffset
&lhs
, const IdentifierOffset
&rhs
) const {
684 if (lhs
.offset_
!= rhs
.offset_
)
685 return lhs
.offset_
< rhs
.offset_
;
686 if (lhs
.flags_
!= rhs
.flags_
)
687 return lhs
.flags_
< rhs
.flags_
;
688 /*if (lhs.usage_ != rhs.usage_)
689 return lhs.usage_ < rhs.usage_;*/
690 return lhs
.identifier_
< rhs
.identifier_
;
694 typedef std::set
<IdentifierOffset
, IdentifierOffsetLess
> IdentifierOffsets
;
697 void CYScope::Scope(CYContext
&context
, CYStatement
*&statements
) {
701 CYDeclarations
*last(NULL
), *curr(NULL
);
703 IdentifierOffsets offsets
;
705 for (CYIdentifierAddressFlagsMap::const_iterator
i(internal_
.begin()); i
!= internal_
.end(); ++i
)
706 if (i
->second
!= CYIdentifierMagic
)
707 offsets
.insert(IdentifierOffset(i
->first
, i
->second
));
711 for (IdentifierOffsets::const_iterator
i(offsets
.begin()); i
!= offsets
.end(); ++i
) {
712 if (i
->flags_
== CYIdentifierVariable
) {
713 CYDeclarations
*next($
CYDeclarations($
CYDeclaration(i
->identifier_
)));
721 if (offset
< i
->offset_
)
723 if (context
.rename_
.size() <= offset
)
724 context
.rename_
.resize(offset
+ 1);
726 CYIdentifierUsage
&rename(context
.rename_
[offset
++]);
727 i
->identifier_
->SetNext(rename
.identifier_
);
728 rename
.identifier_
= i
->identifier_
;
729 rename
.usage_
+= i
->identifier_
->usage_
+ 1;
733 CYVar
*var($
CYVar(last
));
734 var
->SetNext(statements
);
738 for (CYIdentifierValueSet::const_iterator
i(identifiers_
.begin()); i
!= identifiers_
.end(); ++i
)
739 if (internal_
.find(*i
) == internal_
.end()) {
740 //std::cout << *i << '=' << offset << std::endl;
741 if ((*i
)->offset_
< offset
)
742 (*i
)->offset_
= offset
;
743 parent_
->Merge(context
, *i
);
747 CYStatement
*CYStatement::Collapse(CYContext
&context
) {
751 CYStatement
*CYStatement::ReplaceAll(CYContext
&context
) { $
T(NULL
)
752 CYStatement
*replace(this);
753 context
.Replace(replace
);
754 replace
->SetNext(next_
->ReplaceAll(context
));
755 return replace
->Collapse(context
);
758 CYString
*CYString::Concat(CYContext
&context
, CYString
*rhs
) const {
759 size_t size(size_
+ rhs
->size_
);
760 char *value($
char[size
+ 1]);
761 memcpy(value
, value_
, size_
);
762 memcpy(value
+ size_
, rhs
->value_
, rhs
->size_
);
764 return $
S(value
, size
);
767 CYNumber
*CYString::Number(CYContext
&context
) {
768 // XXX: there is a precise algorithm for this
772 CYString
*CYString::String(CYContext
&context
) {
776 CYStatement
*CYSwitch::Replace(CYContext
&context
) {
777 context
.Replace(value_
);
778 clauses_
->Replace(context
);
782 CYExpression
*CYThis::Replace(CYContext
&context
) {
789 CYStatement
*Throw::Replace(CYContext
&context
) {
790 context
.Replace(value_
);
796 CYExpression
*CYTrivial::Replace(CYContext
&context
) {
800 CYNumber
*CYTrue::Number(CYContext
&context
) {
804 CYString
*CYTrue::String(CYContext
&context
) {
811 CYStatement
*Try::Replace(CYContext
&context
) {
812 code_
.Replace(context
);
813 catch_
->Replace(context
);
814 finally_
->Replace(context
);
820 CYStatement
*CYVar::Replace(CYContext
&context
) {
821 return $
E(declarations_
->Replace(context
));
824 CYExpression
*CYVariable::Replace(CYContext
&context
) {
825 context
.Replace(name_
);
829 CYStatement
*CYWhile::Replace(CYContext
&context
) {
830 context
.Replace(test_
);
831 context
.Replace(code_
);
835 CYStatement
*CYWith::Replace(CYContext
&context
) {
836 context
.Replace(scope_
);
837 context
.Replace(code_
);
841 CYExpression
*CYWord::ClassName(CYContext
&context
, bool object
) {
842 CYString
*name($
S(this));
844 return $
C1($
V("objc_getClass"), name
);