]> git.saurik.com Git - cycript.git/blame - Replace.cpp
Move LexSetRegEx to new "post-lookahead" paradigm.
[cycript.git] / Replace.cpp
CommitLineData
b3378a02 1/* Cycript - Optimizing JavaScript Compiler/Runtime
c1d3e52e 2 * Copyright (C) 2009-2015 Jay Freeman (saurik)
4644480a
JF
3*/
4
f95d2598 5/* GNU Affero General Public License, Version 3 {{{ */
4644480a 6/*
f95d2598
JF
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.
11
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
c15969fd 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
f95d2598
JF
15 * GNU Affero General Public License for more details.
16
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/>.
b3378a02 19**/
4644480a
JF
20/* }}} */
21
3b52fd1a
JF
22#include <iomanip>
23
20052ff7
JF
24#include "Replace.hpp"
25#include "Syntax.hpp"
26
61fe0c53
JF
27CYFunctionExpression *CYNonLocalize(CYContext &context, CYFunctionExpression *function) {
28 function->nonlocal_ = context.nextlocal_;
29 return function;
30}
31
c5b15840
JF
32CYFunctionExpression *CYSuperize(CYContext &context, CYFunctionExpression *function) {
33 function->super_ = context.super_;
34 return function;
35}
36
a196a97a
JF
37CYStatement *CYDefineProperty(CYExpression *object, CYExpression *name, bool configurable, bool enumerable, CYProperty *descriptor) {
38 return $E($C3($M($V("Object"), $S("defineProperty")), object, name, $ CYObject(CYList<CYProperty>()
39 ->* (configurable ? $ CYPropertyValue($S("configurable"), $ CYTrue()) : NULL)
40 ->* (enumerable ? $ CYPropertyValue($S("enumerable"), $ CYTrue()) : NULL)
41 ->* descriptor)));
42}
43
12e37ba3
JF
44static void CYImplicitReturn(CYStatement *&code) {
45 if (CYStatement *&last = CYGetLast(code))
46 last = last->Return();
47}
48
4644480a
JF
49CYExpression *CYAdd::Replace(CYContext &context) {
50 CYInfix::Replace(context);
51
fd5cdf97
JF
52 CYString *lhs(dynamic_cast<CYString *>(lhs_));
53 CYString *rhs(dynamic_cast<CYString *>(rhs_));
4644480a
JF
54
55 if (lhs != NULL || rhs != NULL) {
56 if (lhs == NULL) {
fd5cdf97 57 lhs = lhs_->String(context);
4644480a 58 if (lhs == NULL)
029bc65b 59 return this;
4644480a 60 } else if (rhs == NULL) {
fd5cdf97 61 rhs = rhs_->String(context);
4644480a 62 if (rhs == NULL)
029bc65b 63 return this;
4644480a
JF
64 }
65
66 return lhs->Concat(context, rhs);
67 }
68
fd5cdf97
JF
69 if (CYNumber *lhn = lhs_->Number(context))
70 if (CYNumber *rhn = rhs_->Number(context))
4644480a
JF
71 return $D(lhn->Value() + rhn->Value());
72
029bc65b 73 return this;
4644480a
JF
74}
75
3b52fd1a 76CYExpression *CYAddressOf::Replace(CYContext &context) {
3b52fd1a
JF
77 return $C0($M(rhs_, $S("$cya")));
78}
79
5192746c 80CYArgument *CYArgument::Replace(CYContext &context) { $T(NULL)
3b52fd1a 81 context.Replace(value_);
5192746c
JF
82 next_ = next_->Replace(context);
83
84 if (value_ == NULL) {
85 if (next_ == NULL)
86 return NULL;
87 else
88 value_ = $U;
89 }
90
91 return this;
3b52fd1a
JF
92}
93
94CYExpression *CYArray::Replace(CYContext &context) {
fc8fc33d
JF
95 if (elements_ != NULL)
96 elements_->Replace(context);
029bc65b 97 return this;
3b52fd1a
JF
98}
99
100CYExpression *CYArrayComprehension::Replace(CYContext &context) {
101 CYVariable *cyv($V("$cyv"));
102
c5b15840 103 return $C0($F(NULL, $P1($L($I("$cyv")), comprehensions_->Parameters(context)), $$->*
3b52fd1a
JF
104 $E($ CYAssign(cyv, $ CYArray()))->*
105 comprehensions_->Replace(context, $E($C1($M(cyv, $S("push")), expression_)))->*
106 $ CYReturn(cyv)
107 ));
108}
109
110CYExpression *CYAssignment::Replace(CYContext &context) {
111 context.Replace(lhs_);
112 context.Replace(rhs_);
029bc65b 113 return this;
3b52fd1a
JF
114}
115
12e37ba3
JF
116CYStatement *CYBlock::Return() {
117 CYImplicitReturn(code_);
118 return this;
119}
120
3b52fd1a 121CYStatement *CYBlock::Replace(CYContext &context) {
b0385401
JF
122 context.ReplaceAll(code_);
123 if (code_ == NULL)
029bc65b
JF
124 return $ CYEmpty();
125 return this;
3b52fd1a
JF
126}
127
128CYStatement *CYBreak::Replace(CYContext &context) {
029bc65b 129 return this;
3b52fd1a
JF
130}
131
6c093cce
JF
132CYExpression *CYCall::AddArgument(CYContext &context, CYExpression *value) {
133 CYArgument **argument(&arguments_);
134 while (*argument != NULL)
135 argument = &(*argument)->next_;
136 *argument = $ CYArgument(value);
137 return this;
138}
139
3b52fd1a
JF
140CYExpression *CYCall::Replace(CYContext &context) {
141 context.Replace(function_);
142 arguments_->Replace(context);
029bc65b 143 return this;
3b52fd1a
JF
144}
145
37954781
JF
146namespace cy {
147namespace Syntax {
148
149void Catch::Replace(CYContext &context) { $T()
50a3d79f 150 CYScope scope(true, context);
daf22a65
JF
151
152 context.Replace(name_);
153 context.scope_->Declare(context, name_, CYIdentifierCatch);
154
b0385401
JF
155 context.ReplaceAll(code_);
156 scope.Close(context, code_);
3b52fd1a
JF
157}
158
37954781
JF
159} }
160
c5b15840
JF
161CYExpression *CYClassExpression::Replace(CYContext &context) {
162 CYBuilder builder;
163
164 CYIdentifier *super(context.Unique());
165
166 CYIdentifier *old(context.super_);
167 context.super_ = super;
168
169 CYIdentifier *constructor(context.Unique());
170 CYForEach (member, tail_->static_)
171 member->Replace(context, builder, $V(constructor), true);
172
173 CYIdentifier *prototype(context.Unique());
174 CYForEach (member, tail_->instance_)
175 member->Replace(context, builder, $V(prototype), true);
176
177 if (tail_->constructor_ == NULL)
178 tail_->constructor_ = $ CYFunctionExpression(NULL, NULL, NULL);
179 tail_->constructor_ = CYSuperize(context, tail_->constructor_);
180
181 context.super_ = old;
182
183 return $C1($ CYFunctionExpression(NULL, $P($L(super)), $$
184 ->* $ CYVar($L1($L(constructor, tail_->constructor_)))
185 ->* $ CYVar($L1($L(prototype, $ CYFunctionExpression(NULL, NULL, NULL))))
186 ->* $E($ CYAssign($M($V(prototype), $S("prototype")), $M($V(super), $S("prototype"))))
187 ->* $E($ CYAssign($V(prototype), $N($V(prototype))))
a196a97a 188 ->* CYDefineProperty($V(prototype), $S("constructor"), false, false, $ CYPropertyValue($S("value"), $V(constructor)))
c5b15840
JF
189 ->* $ CYVar(builder.declarations_)
190 ->* builder.statements_
a196a97a 191 ->* CYDefineProperty($V(constructor), $S("prototype"), false, false, $ CYPropertyValue($S("value"), $V(prototype)))
c5b15840
JF
192 ->* $ CYReturn($V(constructor))
193 ), tail_->extends_ ?: $V($I("Object")));
194}
195
196CYStatement *CYClassStatement::Replace(CYContext &context) {
197 return $ CYVar($L1($L(name_, $ CYClassExpression(name_, tail_))));
198}
199
3b52fd1a
JF
200void CYClause::Replace(CYContext &context) { $T()
201 context.Replace(case_);
b0385401 202 context.ReplaceAll(code_);
3b52fd1a
JF
203 next_->Replace(context);
204}
205
206CYExpression *CYCompound::Replace(CYContext &context) {
fd5cdf97
JF
207 context.Replace(expression_);
208 context.Replace(next_);
209
210 if (CYCompound *compound = dynamic_cast<CYCompound *>(expression_)) {
211 expression_ = compound->expression_;
212 compound->expression_ = compound->next_;
213 compound->next_ = next_;
214 next_ = compound;
215 }
216
9efd8b03 217 return this;
3b52fd1a
JF
218}
219
b0385401
JF
220CYFunctionParameter *CYCompound::Parameter() const {
221 CYFunctionParameter *next(next_->Parameter());
222 if (next == NULL)
e06e5ee1 223 return NULL;
0afc9ba3
JF
224
225 CYFunctionParameter *parameter(expression_->Parameter());
226 if (parameter == NULL)
227 return NULL;
228
229 parameter->SetNext(next);
230 return parameter;
231}
232
3b52fd1a
JF
233CYFunctionParameter *CYComprehension::Parameters(CYContext &context) const { $T(NULL)
234 CYFunctionParameter *next(next_->Parameters(context));
235 if (CYFunctionParameter *parameter = Parameter(context)) {
236 parameter->SetNext(next);
237 return parameter;
238 } else
239 return next;
240}
241
242CYStatement *CYComprehension::Replace(CYContext &context, CYStatement *statement) const {
243 return next_ == NULL ? statement : next_->Replace(context, statement);
244}
245
c5b15840
JF
246CYExpression *CYComputed::PropertyName(CYContext &context) {
247 return expression_;
248}
249
3b52fd1a
JF
250CYExpression *CYCondition::Replace(CYContext &context) {
251 context.Replace(test_);
252 context.Replace(true_);
253 context.Replace(false_);
029bc65b 254 return this;
3b52fd1a
JF
255}
256
ab2aa221
JF
257void CYContext::NonLocal(CYStatement *&statements) {
258 CYContext &context(*this);
259
06293152 260 if (nextlocal_ != NULL && nextlocal_->identifier_ != NULL) {
daf22a65
JF
261 CYIdentifier *cye($I("$cye")->Replace(context));
262 CYIdentifier *unique(nextlocal_->identifier_->Replace(context));
263
264 CYStatement *declare(
c5b15840 265 $ CYVar($L1($L(unique, $ CYObject()))));
daf22a65
JF
266
267 cy::Syntax::Catch *rescue(
268 $ cy::Syntax::Catch(cye, $$->*
4e58e244
JF
269 $ CYIf($ CYIdentical($M($V(cye), $S("$cyk")), $V(unique)), $$->*
270 $ CYReturn($M($V(cye), $S("$cyv"))))->*
271 $ cy::Syntax::Throw($V(cye))));
daf22a65 272
b0385401 273 // XXX: I don't understand any of this
577bfbfa 274 context.Replace(declare);
daf22a65 275 rescue->Replace(context);
ab2aa221
JF
276
277 statements = $$->*
daf22a65
JF
278 declare->*
279 $ cy::Syntax::Try(statements, rescue, NULL);
ab2aa221
JF
280 }
281}
282
283CYIdentifier *CYContext::Unique() {
0cbeddf8 284 return $ CYIdentifier($pool.strcat("$cy", $pool.itoa(unique_++), NULL));
ab2aa221
JF
285}
286
3b52fd1a 287CYStatement *CYContinue::Replace(CYContext &context) {
029bc65b
JF
288 return this;
289}
290
c8a0500b
JF
291CYStatement *CYDebugger::Replace(CYContext &context) {
292 return this;
293}
294
029bc65b 295CYAssignment *CYDeclaration::Assignment(CYContext &context) {
15b88a33
JF
296 if (initialiser_ == NULL)
297 return NULL;
127c1a9c
JF
298
299 CYAssignment *value($ CYAssign(Variable(context), initialiser_));
300 initialiser_ = NULL;
301 return value;
15b88a33
JF
302}
303
304CYVariable *CYDeclaration::Variable(CYContext &context) {
305 return $V(identifier_);
3b52fd1a
JF
306}
307
ad3b38bb 308CYStatement *CYDeclaration::ForEachIn(CYContext &context, CYExpression *value) {
c8a0500b 309 return $ CYVar($L1($ CYDeclaration(identifier_, value)));
3b52fd1a
JF
310}
311
029bc65b 312CYExpression *CYDeclaration::Replace(CYContext &context) {
15b88a33
JF
313 context.Replace(identifier_);
314 context.scope_->Declare(context, identifier_, CYIdentifierVariable);
315 return Variable(context);
316}
317
318void CYDeclarations::Replace(CYContext &context) { $T()
319 declaration_->Replace(context);
320 next_->Replace(context);
3b52fd1a
JF
321}
322
15b88a33 323CYFunctionParameter *CYDeclarations::Parameter(CYContext &context) { $T(NULL)
c8a0500b 324 return $ CYFunctionParameter($ CYDeclaration(declaration_->identifier_), next_->Parameter(context));
15b88a33
JF
325}
326
327CYArgument *CYDeclarations::Argument(CYContext &context) { $T(NULL)
5192746c 328 return $ CYArgument(declaration_->initialiser_, next_->Argument(context));
15b88a33
JF
329}
330
b0385401
JF
331CYExpression *CYDeclarations::Expression(CYContext &context) { $T(NULL)
332 CYExpression *compound(next_->Expression(context));
029bc65b 333 if (CYAssignment *assignment = declaration_->Assignment(context))
b0385401
JF
334 if (compound == NULL)
335 compound = assignment;
336 else
337 compound = $ CYCompound(assignment, compound);
029bc65b 338 return compound;
3b52fd1a
JF
339}
340
341CYExpression *CYDirectMember::Replace(CYContext &context) {
ca0f097f
JF
342 context.Replace(object_);
343 context.Replace(property_);
029bc65b 344 return this;
3b52fd1a
JF
345}
346
347CYStatement *CYDoWhile::Replace(CYContext &context) {
348 context.Replace(test_);
b0385401 349 context.ReplaceAll(code_);
029bc65b 350 return this;
3b52fd1a
JF
351}
352
fc8fc33d 353void CYElementSpread::Replace(CYContext &context) {
3b52fd1a 354 context.Replace(value_);
fc8fc33d
JF
355}
356
357void CYElementValue::Replace(CYContext &context) {
358 context.Replace(value_);
359 if (next_ != NULL)
360 next_->Replace(context);
3b52fd1a
JF
361}
362
363CYStatement *CYEmpty::Replace(CYContext &context) {
9cd63688 364 return NULL;
029bc65b
JF
365}
366
9a39f705
JF
367CYExpression *CYEncodedType::Replace(CYContext &context) {
368 return typed_->Replace(context);
369}
370
12e37ba3
JF
371CYStatement *CYExpress::Return() {
372 return $ CYReturn(expression_);
373}
374
720a57a8 375CYStatement *CYExpress::Replace(CYContext &context) {
3b52fd1a 376 context.Replace(expression_);
029bc65b 377 return this;
3b52fd1a
JF
378}
379
6c093cce
JF
380CYExpression *CYExpression::AddArgument(CYContext &context, CYExpression *value) {
381 return $C1(this, value);
382}
383
ad3b38bb
JF
384CYStatement *CYExpression::ForEachIn(CYContext &context, CYExpression *value) {
385 return $E($ CYAssign(this, value));
3b52fd1a
JF
386}
387
ae65d594
JF
388CYAssignment *CYExpression::Assignment(CYContext &context) {
389 return NULL;
390}
391
0afc9ba3
JF
392CYFunctionParameter *CYExpression::Parameter() const {
393 return NULL;
394}
395
c5587ed7
JF
396CYStatement *CYExternal::Replace(CYContext &context) {
397 return $E($ CYAssign($V(typed_->identifier_), $C1(typed_->Replace(context), $C2($V("dlsym"), $V("RTLD_DEFAULT"), $S(typed_->identifier_->Word())))));
398}
399
4644480a
JF
400CYNumber *CYFalse::Number(CYContext &context) {
401 return $D(0);
402}
403
404CYString *CYFalse::String(CYContext &context) {
405 return $S("false");
406}
407
a0be43fc
JF
408CYExpression *CYFatArrow::Replace(CYContext &context) {
409 CYFunctionExpression *function($ CYFunctionExpression(NULL, parameters_, code_));
410 function->this_.SetNext(context.this_);
411 return function;
412}
413
3b52fd1a 414void CYFinally::Replace(CYContext &context) { $T()
b0385401 415 context.ReplaceAll(code_);
3b52fd1a
JF
416}
417
418CYStatement *CYFor::Replace(CYContext &context) {
029bc65b 419 context.Replace(initialiser_);
3b52fd1a
JF
420 context.Replace(test_);
421 context.Replace(increment_);
b0385401 422 context.ReplaceAll(code_);
029bc65b 423 return this;
3b52fd1a
JF
424}
425
b0385401 426CYExpression *CYForDeclarations::Replace(CYContext &context) {
15b88a33 427 declarations_->Replace(context);
b0385401 428 return declarations_->Expression(context);
15b88a33
JF
429}
430
431// XXX: this still feels highly suboptimal
3b52fd1a 432CYStatement *CYForIn::Replace(CYContext &context) {
127c1a9c 433 if (CYAssignment *assignment = initialiser_->Assignment(context))
15b88a33
JF
434 return $ CYBlock($$->*
435 $E(assignment)->*
436 this
437 );
ae65d594 438
127c1a9c
JF
439 context.Replace(initialiser_);
440 context.Replace(set_);
b0385401 441 context.ReplaceAll(code_);
15b88a33 442 return this;
3b52fd1a
JF
443}
444
445CYFunctionParameter *CYForInComprehension::Parameter(CYContext &context) const {
4e3c9056 446 return $ CYFunctionParameter(declaration_);
3b52fd1a
JF
447}
448
449CYStatement *CYForInComprehension::Replace(CYContext &context, CYStatement *statement) const {
4e3c9056 450 return $ CYForIn(declaration_->Variable(context), set_, CYComprehension::Replace(context, statement));
3b52fd1a
JF
451}
452
d5618df7 453CYStatement *CYForOf::Replace(CYContext &context) {
04ea132d
JF
454 if (CYAssignment *assignment = initialiser_->Assignment(context))
455 return $ CYBlock($$->*
456 $E(assignment)->*
457 this
458 );
459
ca6a1b2b 460 CYIdentifier *cys(context.Unique()), *cyt(context.Unique());
3b52fd1a 461
ca6a1b2b
JF
462 return $ CYBlock($$
463 ->* $ CYLet($L2($L(cys, set_), $L(cyt)))
464 ->* $ CYForIn($V(cyt), $V(cys), $ CYBlock($$
465 ->* initialiser_->ForEachIn(context, $M($V(cys), $V(cyt)))
466 ->* code_
467 )));
3b52fd1a
JF
468}
469
d5618df7 470CYFunctionParameter *CYForOfComprehension::Parameter(CYContext &context) const {
4e3c9056 471 return $ CYFunctionParameter(declaration_);
3b52fd1a
JF
472}
473
d5618df7 474CYStatement *CYForOfComprehension::Replace(CYContext &context, CYStatement *statement) const {
55c63f1d 475 CYIdentifier *cys($I("$cys"));
3b52fd1a 476
c5b15840 477 return $E($C0($F(NULL, $P1($L($I("$cys"))), $$->*
2eb8215d 478 $E($ CYAssign($V(cys), set_))->*
4e3c9056
JF
479 $ CYForIn(declaration_->Variable(context), $V(cys), $ CYBlock($$->*
480 $E($ CYAssign(declaration_->Variable(context), $M($V(cys), declaration_->Variable(context))))->*
3b52fd1a
JF
481 CYComprehension::Replace(context, statement)
482 ))
483 )));
484}
485
c5b15840 486void CYFunction::Replace(CYContext &context) {
a0be43fc 487 CYThisScope *_this(context.this_);
12e37ba3
JF
488 context.this_ = &this_;
489 context.this_ = CYGetLast(context.this_);
a0be43fc 490
c5b15840
JF
491 CYIdentifier *super(context.super_);
492 context.super_ = super_;
493
06293152
JF
494 CYNonLocal *nonlocal(context.nonlocal_);
495 CYNonLocal *nextlocal(context.nextlocal_);
496
ab2aa221 497 bool localize;
06293152 498 if (nonlocal_ != NULL) {
ab2aa221 499 localize = false;
06293152
JF
500 context.nonlocal_ = nonlocal_;
501 } else {
ab2aa221
JF
502 localize = true;
503 nonlocal_ = $ CYNonLocal();
06293152 504 context.nextlocal_ = nonlocal_;
ab2aa221
JF
505 }
506
50a3d79f 507 CYScope scope(!localize, context);
61fe0c53 508
c8a0500b 509 parameters_->Replace(context, code_);
c5b15840 510
b0385401 511 context.ReplaceAll(code_);
029bc65b 512
12e37ba3
JF
513 if (implicit_)
514 CYImplicitReturn(code_);
515
c5b15840
JF
516 if (CYIdentifier *identifier = this_.identifier_) {
517 context.scope_->Declare(context, identifier, CYIdentifierVariable);
518 code_ = $$
519 ->*$E($ CYAssign($V(identifier), $ CYThis()))
520 ->*code_
521 ;
522 }
a0be43fc 523
ab2aa221 524 if (localize)
b0385401 525 context.NonLocal(code_);
06293152
JF
526
527 context.nextlocal_ = nextlocal;
ab2aa221
JF
528 context.nonlocal_ = nonlocal;
529
c5b15840 530 context.super_ = super;
a0be43fc
JF
531 context.this_ = _this;
532
b0385401 533 scope.Close(context, code_);
3b52fd1a
JF
534}
535
536CYExpression *CYFunctionExpression::Replace(CYContext &context) {
c5b15840
JF
537 CYScope scope(false, context);
538 if (name_ != NULL)
539 context.scope_->Declare(context, name_, CYIdentifierOther);
540 CYFunction::Replace(context);
541 scope.Close(context, code_);
029bc65b
JF
542 return this;
543}
544
b0385401 545void CYFunctionParameter::Replace(CYContext &context, CYStatement *&statements) { $T()
c8a0500b
JF
546 CYAssignment *assignment(initialiser_->Assignment(context));
547 context.Replace(initialiser_);
548
b0385401 549 next_->Replace(context, statements);
c8a0500b
JF
550
551 if (assignment != NULL)
b0385401
JF
552 statements = $$->*
553 // XXX: this cast is quite incorrect
554 $ CYIf($ CYIdentical($ CYTypeOf(dynamic_cast<CYExpression *>(initialiser_)), $S("undefined")), $$->*
555 $E(assignment)
556 )->*
557 statements;
3b52fd1a
JF
558}
559
560CYStatement *CYFunctionStatement::Replace(CYContext &context) {
c5b15840
JF
561 context.scope_->Declare(context, name_, CYIdentifierOther);
562 CYFunction::Replace(context);
029bc65b
JF
563 return this;
564}
565
566CYIdentifier *CYIdentifier::Replace(CYContext &context) {
a846a8cd 567 if (replace_ != NULL && replace_ != this)
de9fc71b 568 return replace_->Replace(context);
a846a8cd 569 replace_ = context.scope_->Lookup(context, this);
a86e34d0 570 return replace_;
3b52fd1a
JF
571}
572
12e37ba3
JF
573CYStatement *CYIf::Return() {
574 CYImplicitReturn(true_);
575 CYImplicitReturn(false_);
576 return this;
577}
578
3b52fd1a
JF
579CYStatement *CYIf::Replace(CYContext &context) {
580 context.Replace(test_);
b0385401
JF
581 context.ReplaceAll(true_);
582 context.ReplaceAll(false_);
029bc65b 583 return this;
3b52fd1a
JF
584}
585
586CYFunctionParameter *CYIfComprehension::Parameter(CYContext &context) const {
587 return NULL;
588}
589
590CYStatement *CYIfComprehension::Replace(CYContext &context, CYStatement *statement) const {
591 return $ CYIf(test_, CYComprehension::Replace(context, statement));
592}
593
7b750785 594CYStatement *CYImport::Replace(CYContext &context) {
c5b15840 595 return $ CYVar($L1($L($I(module_->part_->Word()), $C1($V("require"), module_->Replace(context, "/")))));
7b750785
JF
596}
597
3b52fd1a 598CYExpression *CYIndirect::Replace(CYContext &context) {
3b52fd1a
JF
599 return $M(rhs_, $S("$cyi"));
600}
601
602CYExpression *CYIndirectMember::Replace(CYContext &context) {
3b52fd1a
JF
603 return $M($ CYIndirect(object_), property_);
604}
605
606CYExpression *CYInfix::Replace(CYContext &context) {
607 context.Replace(lhs_);
608 context.Replace(rhs_);
029bc65b 609 return this;
3b52fd1a
JF
610}
611
612CYStatement *CYLabel::Replace(CYContext &context) {
613 context.Replace(statement_);
029bc65b 614 return this;
3b52fd1a
JF
615}
616
690cf1a8 617CYExpression *CYLambda::Replace(CYContext &context) {
b0385401 618 return $N2($V("Functor"), $ CYFunctionExpression(NULL, parameters_->Parameters(context), code_), parameters_->TypeSignature(context, typed_->Replace(context)));
690cf1a8
JF
619}
620
ca6a1b2b
JF
621CYStatement *CYLet::Replace(CYContext &context) {
622 declarations_->Replace(context);
623 if (CYExpression *expression = declarations_->Expression(context))
624 return $E(expression);
625 return $ CYEmpty();
550ee46a
JF
626}
627
c5b15840
JF
628CYFunctionExpression *CYMethod::Constructor() {
629 return NULL;
630}
631
632void CYMethod::Replace(CYContext &context) {
633 CYFunction::Replace(context);
634}
635
7b750785
JF
636CYString *CYModule::Replace(CYContext &context, const char *separator) const {
637 if (next_ == NULL)
638 return $ CYString(part_);
639 return $ CYString($pool.strcat(next_->Replace(context, separator)->Value(), separator, part_->Word(), NULL));
640}
641
62f398e4
JF
642CYExpression *CYMultiply::Replace(CYContext &context) {
643 CYInfix::Replace(context);
644
fd5cdf97
JF
645 if (CYNumber *lhn = lhs_->Number(context))
646 if (CYNumber *rhn = rhs_->Number(context))
62f398e4
JF
647 return $D(lhn->Value() * rhn->Value());
648
649 return this;
650}
651
2eb8215d
JF
652namespace cy {
653namespace Syntax {
654
655CYExpression *New::AddArgument(CYContext &context, CYExpression *value) {
bf45251b 656 CYSetLast(arguments_) = $ CYArgument(value);
6c093cce
JF
657 return this;
658}
659
2eb8215d 660CYExpression *New::Replace(CYContext &context) {
3b52fd1a
JF
661 context.Replace(constructor_);
662 arguments_->Replace(context);
029bc65b 663 return this;
3b52fd1a
JF
664}
665
2eb8215d
JF
666} }
667
4644480a
JF
668CYNumber *CYNull::Number(CYContext &context) {
669 return $D(0);
670}
671
672CYString *CYNull::String(CYContext &context) {
673 return $S("null");
674}
675
676CYNumber *CYNumber::Number(CYContext &context) {
677 return this;
678}
679
680CYString *CYNumber::String(CYContext &context) {
681 // XXX: there is a precise algorithm for this
0cbeddf8 682 return $S($pool.sprintf(24, "%.17g", Value()));
4644480a
JF
683}
684
c5b15840
JF
685CYExpression *CYNumber::PropertyName(CYContext &context) {
686 return String(context);
687}
688
3b52fd1a 689CYExpression *CYObject::Replace(CYContext &context) {
c5b15840
JF
690 CYBuilder builder;
691 if (properties_ != NULL)
692 properties_ = properties_->ReplaceAll(context, builder, $ CYThis(), false);
693
694 if (builder) {
695 return $C1($M($ CYFunctionExpression(NULL, builder.declarations_->Parameter(context),
696 builder.statements_->*
697 $ CYReturn($ CYThis())
698 ), $S("call")), this, builder.declarations_->Argument(context));
699 }
700
701 CYForEach (property, properties_)
702 property->Replace(context);
029bc65b 703 return this;
3b52fd1a
JF
704}
705
b0385401
JF
706CYExpression *CYParenthetical::Replace(CYContext &context) {
707 return expression_;
708}
709
3b52fd1a
JF
710CYExpression *CYPostfix::Replace(CYContext &context) {
711 context.Replace(lhs_);
029bc65b 712 return this;
3b52fd1a
JF
713}
714
715CYExpression *CYPrefix::Replace(CYContext &context) {
716 context.Replace(rhs_);
029bc65b 717 return this;
3b52fd1a
JF
718}
719
c5b15840
JF
720CYProperty *CYProperty::ReplaceAll(CYContext &context, CYBuilder &builder, CYExpression *self, bool update) {
721 update |= name_->Computed();
722 if (update)
a196a97a 723 Replace(context, builder, self, false);
c5b15840
JF
724 if (next_ != NULL)
725 next_ = next_->ReplaceAll(context, builder, self, update);
726 return update ? next_ : this;
727}
728
a196a97a 729void CYProperty::Replace(CYContext &context, CYBuilder &builder, CYExpression *self, bool protect) {
c5b15840 730 CYExpression *name(name_->PropertyName(context));
a196a97a 731 if (name_->Computed()) {
c5b15840
JF
732 CYIdentifier *unique(context.Unique());
733 builder.declarations_->*$L1($L(unique, name));
734 name = $V(unique);
735 }
736
a196a97a 737 Replace(context, builder, self, name, protect);
c5b15840
JF
738}
739
a196a97a 740void CYPropertyGetter::Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name, bool protect) {
c5b15840
JF
741 CYIdentifier *unique(context.Unique());
742 builder.declarations_
743 ->* $L1($L(unique, CYSuperize(context, $ CYFunctionExpression(NULL, parameters_, code_))));
744 builder.statements_
a196a97a 745 ->* CYDefineProperty(self, name, true, !protect, $ CYPropertyValue($S("get"), $V(unique)));
c5b15840
JF
746}
747
748CYFunctionExpression *CYPropertyMethod::Constructor() {
749 return name_->Constructor() ? $ CYFunctionExpression(NULL, parameters_, code_) : NULL;
750}
751
a196a97a 752void CYPropertyMethod::Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name, bool protect) {
c5b15840
JF
753 CYIdentifier *unique(context.Unique());
754 builder.declarations_
755 ->* $L1($L(unique, CYSuperize(context, $ CYFunctionExpression(NULL, parameters_, code_))));
756 builder.statements_
a196a97a
JF
757 ->* (!protect ? $E($ CYAssign($M(self, name), $V(unique))) :
758 CYDefineProperty(self, name, true, !protect, $ CYPropertyValue($S("value"), $V(unique), $ CYPropertyValue($S("writable"), $ CYTrue()))));
c5b15840
JF
759}
760
a196a97a 761void CYPropertySetter::Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name, bool protect) {
c5b15840
JF
762 CYIdentifier *unique(context.Unique());
763 builder.declarations_
764 ->* $L1($L(unique, CYSuperize(context, $ CYFunctionExpression(NULL, parameters_, code_))));
765 builder.statements_
a196a97a 766 ->* CYDefineProperty(self, name, true, !protect, $ CYPropertyValue($S("set"), $V(unique)));
c5b15840
JF
767}
768
a196a97a
JF
769void CYPropertyValue::Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name, bool protect) {
770 _assert(!protect);
c5b15840
JF
771 CYIdentifier *unique(context.Unique());
772 builder.declarations_
773 ->* $L1($L(unique, value_));
774 builder.statements_
775 ->* $E($ CYAssign($M(self, name), $V(unique)));
776}
777
778void CYPropertyValue::Replace(CYContext &context) {
779 context.Replace(value_);
780}
781
10711823 782// XXX: this is evil evil black magic. don't ask, don't tell... don't believe!
45d0c928 783#define MappingSet "0etnirsoalfucdphmgyvbxTwSNECAFjDLkMOIBPqzRH$_WXUVGYKQJZ"
10711823 784//#define MappingSet "0abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_"
45d0c928 785
e013809d
JF
786namespace {
787 struct IdentifierUsageLess :
788 std::binary_function<CYIdentifier *, CYIdentifier *, bool>
789 {
790 _finline bool operator ()(CYIdentifier *lhs, CYIdentifier *rhs) const {
791 if (lhs->usage_ != rhs->usage_)
792 return lhs->usage_ > rhs->usage_;
793 return lhs < rhs;
794 }
795 };
796
797 typedef std::set<CYIdentifier *, IdentifierUsageLess> IdentifierUsages;
798}
799
a7d8b413 800void CYScript::Replace(CYContext &context) {
50a3d79f 801 CYScope scope(true, context);
ab2aa221 802
06293152 803 context.nextlocal_ = $ CYNonLocal();
b0385401
JF
804 context.ReplaceAll(code_);
805 context.NonLocal(code_);
ab2aa221 806
b0385401 807 scope.Close(context, code_);
14ec9e00
JF
808
809 size_t offset(0);
810
6a981250 811 CYCStringSet external;
a846a8cd 812 for (CYIdentifierValueSet::const_iterator i(scope.identifiers_.begin()); i != scope.identifiers_.end(); ++i)
6a981250
JF
813 external.insert((*i)->Word());
814
e013809d
JF
815 IdentifierUsages usages;
816
a846a8cd 817 if (offset < context.rename_.size())
c2c9f509
JF
818 CYForEach (i, context.rename_[offset].identifier_)
819 usages.insert(i);
e013809d 820
14ec9e00 821 // XXX: totalling the probable occurrences and sorting by them would improve the result
a846a8cd 822 for (CYIdentifierUsageVector::const_iterator i(context.rename_.begin()); i != context.rename_.end(); ++i, ++offset) {
de9fc71b
JF
823 //std::cout << *i << ":" << (*i)->offset_ << std::endl;
824
14ec9e00
JF
825 const char *name;
826
827 if (context.options_.verbose_)
0cbeddf8 828 name = $pool.strcat("$", $pool.itoa(offset), NULL);
14ec9e00
JF
829 else {
830 char id[8];
831 id[7] = '\0';
832
833 id:
834 unsigned position(7), local(offset + 1);
835
836 do {
45d0c928
JF
837 unsigned index(local % (sizeof(MappingSet) - 1));
838 local /= sizeof(MappingSet) - 1;
839 id[--position] = MappingSet[index];
14ec9e00
JF
840 } while (local != 0);
841
6a981250 842 if (external.find(id + position) != external.end()) {
14ec9e00
JF
843 ++offset;
844 goto id;
845 }
846
b799113b 847 name = $pool.strmemdup(id + position, 7 - position);
14ec9e00
JF
848 // XXX: at some point, this could become a keyword
849 }
850
c2c9f509 851 CYForEach (identifier, i->identifier_)
14ec9e00
JF
852 identifier->Set(name);
853 }
3b52fd1a
JF
854}
855
3b52fd1a 856CYStatement *CYReturn::Replace(CYContext &context) {
ab2aa221 857 if (context.nonlocal_ != NULL) {
c5b15840 858 CYProperty *value(value_ == NULL ? NULL : $ CYPropertyValue($S("$cyv"), value_));
ab2aa221 859 return $ cy::Syntax::Throw($ CYObject(
c5b15840 860 $ CYPropertyValue($S("$cyk"), $V(context.nonlocal_->Target(context)), value)
ab2aa221
JF
861 ));
862 }
863
3b52fd1a 864 context.Replace(value_);
029bc65b
JF
865 return this;
866}
867
6c093cce 868CYExpression *CYRubyBlock::Replace(CYContext &context) {
6c093cce
JF
869 return call_->AddArgument(context, proc_->Replace(context));
870}
871
1abe53bf
JF
872CYExpression *CYRubyBlock::AddArgument(CYContext &context, CYExpression *value) {
873 return Replace(context)->AddArgument(context, value);
874}
875
6c093cce 876CYExpression *CYRubyProc::Replace(CYContext &context) {
12e37ba3
JF
877 CYFunctionExpression *function($ CYFunctionExpression(NULL, parameters_, code_));
878 function = CYNonLocalize(context, function);
879 function->implicit_ = true;
880 return function;
6c093cce
JF
881}
882
50a3d79f 883CYScope::CYScope(bool transparent, CYContext &context) :
61fe0c53 884 transparent_(transparent),
daf22a65
JF
885 parent_(context.scope_)
886{
50a3d79f 887 context.scope_ = this;
daf22a65
JF
888}
889
a86e34d0 890void CYScope::Declare(CYContext &context, CYIdentifier *identifier, CYIdentifierFlags flags) {
61fe0c53 891 if (!transparent_ || flags == CYIdentifierArgument || flags == CYIdentifierCatch)
daf22a65 892 internal_.insert(CYIdentifierAddressFlagsMap::value_type(identifier, flags));
61fe0c53
JF
893 else if (parent_ != NULL)
894 parent_->Declare(context, identifier, flags);
a86e34d0
JF
895}
896
897CYIdentifier *CYScope::Lookup(CYContext &context, CYIdentifier *identifier) {
898 std::pair<CYIdentifierValueSet::iterator, bool> insert(identifiers_.insert(identifier));
899 return *insert.first;
900}
901
6a981250 902void CYScope::Merge(CYContext &context, CYIdentifier *identifier) {
10711823 903 std::pair<CYIdentifierValueSet::iterator, bool> insert(identifiers_.insert(identifier));
6a981250
JF
904 if (!insert.second) {
905 if ((*insert.first)->offset_ < identifier->offset_)
906 (*insert.first)->offset_ = identifier->offset_;
907 identifier->replace_ = *insert.first;
e013809d 908 (*insert.first)->usage_ += identifier->usage_ + 1;
029bc65b
JF
909 }
910}
911
10711823
JF
912namespace {
913 struct IdentifierOffset {
914 size_t offset_;
915 CYIdentifierFlags flags_;
e013809d 916 size_t usage_;
10711823
JF
917 CYIdentifier *identifier_;
918
e013809d
JF
919 IdentifierOffset(CYIdentifier *identifier, CYIdentifierFlags flags) :
920 offset_(identifier->offset_),
10711823 921 flags_(flags),
e013809d 922 usage_(identifier->usage_),
10711823
JF
923 identifier_(identifier)
924 {
925 }
926 };
927
928 struct IdentifierOffsetLess :
929 std::binary_function<const IdentifierOffset &, const IdentifierOffset &, bool>
930 {
931 _finline bool operator ()(const IdentifierOffset &lhs, const IdentifierOffset &rhs) const {
932 if (lhs.offset_ != rhs.offset_)
933 return lhs.offset_ < rhs.offset_;
934 if (lhs.flags_ != rhs.flags_)
935 return lhs.flags_ < rhs.flags_;
e013809d 936 /*if (lhs.usage_ != rhs.usage_)
a846a8cd 937 return lhs.usage_ < rhs.usage_;*/
10711823
JF
938 return lhs.identifier_ < rhs.identifier_;
939 }
940 };
941
942 typedef std::set<IdentifierOffset, IdentifierOffsetLess> IdentifierOffsets;
943}
944
50a3d79f
JF
945void CYScope::Close(CYContext &context, CYStatement *&statements) {
946 context.scope_ = parent_;
947
2c81c6df
JF
948 if (parent_ == NULL)
949 return;
950
029bc65b 951 CYDeclarations *last(NULL), *curr(NULL);
14ec9e00 952
10711823 953 IdentifierOffsets offsets;
6a981250 954
10711823 955 for (CYIdentifierAddressFlagsMap::const_iterator i(internal_.begin()); i != internal_.end(); ++i)
a846a8cd 956 if (i->second != CYIdentifierMagic)
e013809d 957 offsets.insert(IdentifierOffset(i->first, i->second));
10711823
JF
958
959 size_t offset(0);
960
961 for (IdentifierOffsets::const_iterator i(offsets.begin()); i != offsets.end(); ++i) {
962 if (i->flags_ == CYIdentifierVariable) {
963 CYDeclarations *next($ CYDeclarations($ CYDeclaration(i->identifier_)));
029bc65b
JF
964 if (last == NULL)
965 last = next;
966 if (curr != NULL)
967 curr->SetNext(next);
968 curr = next;
969 }
029bc65b 970
10711823
JF
971 if (offset < i->offset_)
972 offset = i->offset_;
a846a8cd
JF
973 if (context.rename_.size() <= offset)
974 context.rename_.resize(offset + 1);
10711823 975
a846a8cd 976 CYIdentifierUsage &rename(context.rename_[offset++]);
e013809d
JF
977 i->identifier_->SetNext(rename.identifier_);
978 rename.identifier_ = i->identifier_;
979 rename.usage_ += i->identifier_->usage_ + 1;
6a981250
JF
980 }
981
029bc65b
JF
982 if (last != NULL) {
983 CYVar *var($ CYVar(last));
984 var->SetNext(statements);
985 statements = var;
986 }
987
6a981250
JF
988 for (CYIdentifierValueSet::const_iterator i(identifiers_.begin()); i != identifiers_.end(); ++i)
989 if (internal_.find(*i) == internal_.end()) {
de9fc71b 990 //std::cout << *i << '=' << offset << std::endl;
6a981250
JF
991 if ((*i)->offset_ < offset)
992 (*i)->offset_ = offset;
993 parent_->Merge(context, *i);
994 }
029bc65b
JF
995}
996
fc8fc33d
JF
997CYElementValue *CYSpan::Replace(CYContext &context) { $T(NULL)
998 return $ CYElementValue(expression_, $ CYElementValue(string_, next_->Replace(context)));
b900e1a4
JF
999}
1000
12e37ba3
JF
1001CYStatement *CYStatement::Return() {
1002 return this;
1003}
1004
4644480a
JF
1005CYString *CYString::Concat(CYContext &context, CYString *rhs) const {
1006 size_t size(size_ + rhs->size_);
2eb8215d 1007 char *value($ char[size + 1]);
4644480a
JF
1008 memcpy(value, value_, size_);
1009 memcpy(value + size_, rhs->value_, rhs->size_);
1010 value[size] = '\0';
a14eb702 1011 return $S(value, size);
4644480a
JF
1012}
1013
1014CYNumber *CYString::Number(CYContext &context) {
1015 // XXX: there is a precise algorithm for this
1016 return NULL;
1017}
1018
c5b15840
JF
1019CYExpression *CYString::PropertyName(CYContext &context) {
1020 return this;
1021}
1022
4644480a
JF
1023CYString *CYString::String(CYContext &context) {
1024 return this;
1025}
1026
c5b15840
JF
1027CYExpression *CYSuperAccess::Replace(CYContext &context) {
1028 return $C1($M($M($M($V(context.super_), $S("prototype")), property_), $S("bind")), $ CYThis());
1029}
1030
1031CYExpression *CYSuperCall::Replace(CYContext &context) {
1032 return $C($C1($M($V(context.super_), $S("bind")), $ CYThis()), arguments_);
1033}
1034
3b52fd1a
JF
1035CYStatement *CYSwitch::Replace(CYContext &context) {
1036 context.Replace(value_);
1037 clauses_->Replace(context);
029bc65b 1038 return this;
3b52fd1a
JF
1039}
1040
b900e1a4 1041CYExpression *CYTemplate::Replace(CYContext &context) {
fc8fc33d 1042 return $C2($M($M($M($V("String"), $S("prototype")), $S("concat")), $S("apply")), $S(""), $ CYArray($ CYElementValue(string_, spans_->Replace(context))));
b900e1a4
JF
1043}
1044
3b52fd1a 1045CYExpression *CYThis::Replace(CYContext &context) {
a0be43fc
JF
1046 if (context.this_ != NULL)
1047 return $V(context.this_->Identifier(context));
029bc65b 1048 return this;
3b52fd1a
JF
1049}
1050
37954781
JF
1051namespace cy {
1052namespace Syntax {
1053
1054CYStatement *Throw::Replace(CYContext &context) {
3b52fd1a 1055 context.Replace(value_);
029bc65b 1056 return this;
3b52fd1a
JF
1057}
1058
37954781
JF
1059} }
1060
3b52fd1a 1061CYExpression *CYTrivial::Replace(CYContext &context) {
029bc65b 1062 return this;
3b52fd1a
JF
1063}
1064
4644480a
JF
1065CYNumber *CYTrue::Number(CYContext &context) {
1066 return $D(1);
1067}
1068
1069CYString *CYTrue::String(CYContext &context) {
1070 return $S("true");
1071}
1072
37954781
JF
1073namespace cy {
1074namespace Syntax {
1075
1076CYStatement *Try::Replace(CYContext &context) {
b0385401 1077 context.ReplaceAll(code_);
3b52fd1a
JF
1078 catch_->Replace(context);
1079 finally_->Replace(context);
029bc65b 1080 return this;
3b52fd1a
JF
1081}
1082
37954781
JF
1083} }
1084
9a39f705
JF
1085CYExpression *CYTypeArrayOf::Replace_(CYContext &context, CYExpression *type) {
1086 return next_->Replace(context, $ CYCall($ CYDirectMember(type, $ CYString("arrayOf")), $ CYArgument(size_)));
690cf1a8
JF
1087}
1088
3fe16be7
JF
1089CYExpression *CYTypeBlockWith::Replace_(CYContext &context, CYExpression *type) {
1090 return next_->Replace(context, $ CYCall($ CYDirectMember(type, $ CYString("blockWith")), parameters_->Argument(context)));
1091}
1092
9a39f705
JF
1093CYExpression *CYTypeConstant::Replace_(CYContext &context, CYExpression *type) {
1094 return next_->Replace(context, $ CYCall($ CYDirectMember(type, $ CYString("constant"))));
690cf1a8
JF
1095}
1096
60097023 1097CYStatement *CYTypeDefinition::Replace(CYContext &context) {
84759b5b 1098 return $E($ CYAssign($V(typed_->identifier_), typed_->Replace(context)));
60097023
JF
1099}
1100
03db6a67
JF
1101CYExpression *CYTypeError::Replace(CYContext &context) {
1102 _assert(false);
1103 return NULL;
1104}
1105
9a39f705
JF
1106CYExpression *CYTypeModifier::Replace(CYContext &context, CYExpression *type) { $T(type)
1107 return Replace_(context, type);
1108}
1109
1110CYExpression *CYTypeFunctionWith::Replace_(CYContext &context, CYExpression *type) {
1111 return next_->Replace(context, $ CYCall($ CYDirectMember(type, $ CYString("functionWith")), parameters_->Argument(context)));
1112}
1113
3fe283c5
JF
1114CYExpression *CYTypeLong::Replace(CYContext &context) {
1115 return $ CYCall($ CYDirectMember(specifier_->Replace(context), $ CYString("long")));
1116}
1117
9a39f705
JF
1118CYExpression *CYTypePointerTo::Replace_(CYContext &context, CYExpression *type) {
1119 return next_->Replace(context, $ CYCall($ CYDirectMember(type, $ CYString("pointerTo"))));
663c538f
JF
1120}
1121
3fe283c5
JF
1122CYExpression *CYTypeShort::Replace(CYContext &context) {
1123 return $ CYCall($ CYDirectMember(specifier_->Replace(context), $ CYString("short")));
1124}
1125
1126CYExpression *CYTypeSigned::Replace(CYContext &context) {
1127 return $ CYCall($ CYDirectMember(specifier_->Replace(context), $ CYString("signed")));
1128}
1129
1130CYExpression *CYTypeUnsigned::Replace(CYContext &context) {
1131 return $ CYCall($ CYDirectMember(specifier_->Replace(context), $ CYString("unsigned")));
1132}
1133
1134CYExpression *CYTypeVariable::Replace(CYContext &context) {
1135 return $V(name_);
1136}
1137
1138CYExpression *CYTypeVoid::Replace(CYContext &context) {
1139 return $N1($V("Type"), $ CYString("v"));
1140}
1141
9a39f705
JF
1142CYExpression *CYTypeVolatile::Replace_(CYContext &context, CYExpression *type) {
1143 return next_->Replace(context, $ CYCall($ CYDirectMember(type, $ CYString("volatile"))));
690cf1a8
JF
1144}
1145
9a39f705 1146CYExpression *CYTypedIdentifier::Replace(CYContext &context) {
3fe283c5 1147 return modifier_->Replace(context, specifier_->Replace(context));
690cf1a8
JF
1148}
1149
00b4cb83
JF
1150CYTypeFunctionWith *CYTypedIdentifier::Function() {
1151 CYTypeModifier **modifier(&modifier_);
1152 if (*modifier == NULL)
1153 return NULL;
1154 while ((*modifier)->next_ != NULL)
1155 modifier = &(*modifier)->next_;
1156 CYTypeFunctionWith *function((*modifier)->Function());
1157 if (function == NULL)
1158 return NULL;
1159 *modifier = NULL;
1160 return function;
1161}
1162
663c538f 1163CYArgument *CYTypedParameter::Argument(CYContext &context) { $T(NULL)
9a39f705 1164 return $ CYArgument(typed_->Replace(context), next_->Argument(context));
663c538f
JF
1165}
1166
690cf1a8
JF
1167CYFunctionParameter *CYTypedParameter::Parameters(CYContext &context) { $T(NULL)
1168 return $ CYFunctionParameter($ CYDeclaration(typed_->identifier_ ?: context.Unique()), next_->Parameters(context));
1169}
1170
1171CYExpression *CYTypedParameter::TypeSignature(CYContext &context, CYExpression *prefix) { $T(prefix)
a2f3ecab 1172 return next_->TypeSignature(context, $ CYAdd(prefix, typed_->Replace(context)));
690cf1a8
JF
1173}
1174
3b52fd1a 1175CYStatement *CYVar::Replace(CYContext &context) {
15b88a33 1176 declarations_->Replace(context);
b0385401
JF
1177 if (CYExpression *expression = declarations_->Expression(context))
1178 return $E(expression);
fd5cdf97 1179 return $ CYEmpty();
3b52fd1a
JF
1180}
1181
1182CYExpression *CYVariable::Replace(CYContext &context) {
577bfbfa 1183 context.Replace(name_);
029bc65b 1184 return this;
3b52fd1a
JF
1185}
1186
0afc9ba3
JF
1187CYFunctionParameter *CYVariable::Parameter() const {
1188 return $ CYFunctionParameter($ CYDeclaration(name_));
1189}
1190
3b52fd1a
JF
1191CYStatement *CYWhile::Replace(CYContext &context) {
1192 context.Replace(test_);
b0385401 1193 context.ReplaceAll(code_);
029bc65b 1194 return this;
3b52fd1a
JF
1195}
1196
1197CYStatement *CYWith::Replace(CYContext &context) {
1198 context.Replace(scope_);
b0385401 1199 context.ReplaceAll(code_);
029bc65b 1200 return this;
3b52fd1a
JF
1201}
1202
c5b15840
JF
1203CYExpression *CYWord::PropertyName(CYContext &context) {
1204 return $S(this);
3b52fd1a 1205}