]> git.saurik.com Git - cycript.git/blame - Replace.cpp
Completed massive refactoring operation to completely isolate Objective-C.
[cycript.git] / Replace.cpp
CommitLineData
4644480a
JF
1/* Cycript - Remove Execution Server and Disassembler
2 * Copyright (C) 2009 Jay Freeman (saurik)
3*/
4
5/* Modified BSD License {{{ */
6/*
7 * Redistribution and use in source and binary
8 * forms, with or without modification, are permitted
9 * provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the
12 * above copyright notice, this list of conditions
13 * and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the
15 * above copyright notice, this list of conditions
16 * and the following disclaimer in the documentation
17 * and/or other materials provided with the
18 * distribution.
19 * 3. The name of the author may not be used to endorse
20 * or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
25 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
34 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
36 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37*/
38/* }}} */
39
3b52fd1a
JF
40#include "Parser.hpp"
41
3b52fd1a
JF
42#include <iomanip>
43
4de0686f 44#include "Replace.hpp"
3b52fd1a 45
4644480a
JF
46CYExpression *CYAdd::Replace(CYContext &context) {
47 CYInfix::Replace(context);
48
49 CYExpression *lhp(lhs_->Primitive(context));
50 CYExpression *rhp(rhs_->Primitive(context));
51
52 CYString *lhs(dynamic_cast<CYString *>(lhp));
53 CYString *rhs(dynamic_cast<CYString *>(rhp));
54
55 if (lhs != NULL || rhs != NULL) {
56 if (lhs == NULL) {
57 lhs = lhp->String(context);
58 if (lhs == NULL)
59 return NULL;
60 } else if (rhs == NULL) {
61 rhs = rhp->String(context);
62 if (rhs == NULL)
63 return NULL;
64 }
65
66 return lhs->Concat(context, rhs);
67 }
68
69 if (CYNumber *lhn = lhp->Number(context))
70 if (CYNumber *rhn = rhp->Number(context))
71 return $D(lhn->Value() + rhn->Value());
72
73 return NULL;
74}
75
3b52fd1a
JF
76CYExpression *CYAddressOf::Replace(CYContext &context) {
77 CYPrefix::Replace(context);
78 return $C0($M(rhs_, $S("$cya")));
79}
80
81void CYArgument::Replace(CYContext &context) { $T()
82 context.Replace(value_);
83 next_->Replace(context);
84}
85
86CYExpression *CYArray::Replace(CYContext &context) {
87 elements_->Replace(context);
88 return NULL;
89}
90
91CYExpression *CYArrayComprehension::Replace(CYContext &context) {
92 CYVariable *cyv($V("$cyv"));
93
94 return $C0($F(NULL, $P1("$cyv", comprehensions_->Parameters(context)), $$->*
95 $E($ CYAssign(cyv, $ CYArray()))->*
96 comprehensions_->Replace(context, $E($C1($M(cyv, $S("push")), expression_)))->*
97 $ CYReturn(cyv)
98 ));
99}
100
101CYExpression *CYAssignment::Replace(CYContext &context) {
102 context.Replace(lhs_);
103 context.Replace(rhs_);
104 return NULL;
105}
106
107CYStatement *CYBlock::Replace(CYContext &context) {
108 statements_ = statements_->ReplaceAll(context);
109 return NULL;
110}
111
112CYStatement *CYBreak::Replace(CYContext &context) {
113 return NULL;
114}
115
116CYExpression *CYCall::Replace(CYContext &context) {
117 context.Replace(function_);
118 arguments_->Replace(context);
119 return NULL;
120}
121
37954781
JF
122namespace cy {
123namespace Syntax {
124
125void Catch::Replace(CYContext &context) { $T()
3b52fd1a
JF
126 code_.Replace(context);
127}
128
37954781
JF
129} }
130
3b52fd1a
JF
131void CYClause::Replace(CYContext &context) { $T()
132 context.Replace(case_);
133 statements_ = statements_->ReplaceAll(context);
134 next_->Replace(context);
135}
136
137CYExpression *CYCompound::Replace(CYContext &context) {
138 expressions_ = expressions_->ReplaceAll(context);
139 return NULL;
140}
141
142CYFunctionParameter *CYComprehension::Parameters(CYContext &context) const { $T(NULL)
143 CYFunctionParameter *next(next_->Parameters(context));
144 if (CYFunctionParameter *parameter = Parameter(context)) {
145 parameter->SetNext(next);
146 return parameter;
147 } else
148 return next;
149}
150
151CYStatement *CYComprehension::Replace(CYContext &context, CYStatement *statement) const {
152 return next_ == NULL ? statement : next_->Replace(context, statement);
153}
154
155CYExpression *CYCondition::Replace(CYContext &context) {
156 context.Replace(test_);
157 context.Replace(true_);
158 context.Replace(false_);
159 return NULL;
160}
161
162CYStatement *CYContinue::Replace(CYContext &context) {
163 return NULL;
164}
165
166CYExpression *CYDeclaration::ForEachIn(CYContext &context) {
167 return $ CYVariable(identifier_);
168}
169
170void CYDeclaration::Replace(CYContext &context) {
171 context.Replace(initialiser_);
172}
173
174void CYDeclarations::Replace(CYContext &context) { $T()
175 declaration_->Replace(context);
176 next_->Replace(context);
177}
178
179CYExpression *CYDirectMember::Replace(CYContext &context) {
180 Replace_(context);
181 return NULL;
182}
183
184CYStatement *CYDoWhile::Replace(CYContext &context) {
185 context.Replace(test_);
186 context.Replace(code_);
187 return NULL;
188}
189
190void CYElement::Replace(CYContext &context) { $T()
191 context.Replace(value_);
192 next_->Replace(context);
193}
194
195CYStatement *CYEmpty::Replace(CYContext &context) {
196 return NULL;
197}
198
199CYStatement *CYExpress::Replace(CYContext &context) {
200 context.Replace(expression_);
201 return NULL;
202}
203
204CYExpression *CYExpression::ClassName(CYContext &context, bool object) {
205 return this;
206}
207
208CYExpression *CYExpression::ForEachIn(CYContext &context) {
209 return this;
210}
211
212CYExpression *CYExpression::ReplaceAll(CYContext &context) { $T(NULL)
213 CYExpression *replace(this);
214 context.Replace(replace);
215
216 if (CYExpression *next = next_->ReplaceAll(context))
217 replace->SetNext(next);
218 else
219 replace->SetNext(next_);
220
221 return replace;
222}
223
4644480a
JF
224CYNumber *CYFalse::Number(CYContext &context) {
225 return $D(0);
226}
227
228CYString *CYFalse::String(CYContext &context) {
229 return $S("false");
230}
231
3b52fd1a
JF
232void CYFinally::Replace(CYContext &context) { $T()
233 code_.Replace(context);
234}
235
236CYStatement *CYFor::Replace(CYContext &context) {
237 // XXX: initialiser_
238 context.Replace(test_);
239 context.Replace(increment_);
240 context.Replace(code_);
241 return NULL;
242}
243
244CYStatement *CYForIn::Replace(CYContext &context) {
245 // XXX: initialiser_
246 context.Replace(set_);
247 context.Replace(code_);
248 return NULL;
249}
250
251CYFunctionParameter *CYForInComprehension::Parameter(CYContext &context) const {
252 return $ CYFunctionParameter(name_);
253}
254
255CYStatement *CYForInComprehension::Replace(CYContext &context, CYStatement *statement) const {
256 return $ CYForIn($ CYVariable(name_), set_, CYComprehension::Replace(context, statement));
257}
258
259CYStatement *CYForEachIn::Replace(CYContext &context) {
260 CYVariable *cys($V("$cys")), *cyt($V("$cyt"));
261
262 return $ CYWith($ CYObject($ CYProperty($S("$cys"), $D(0), $ CYProperty($S("$cyt"), $D(0)))), $ CYBlock($$->*
263 $E($ CYAssign(cys, set_))->*
264 $ CYForIn(cyt, cys, $ CYBlock($$->*
265 $E($ CYAssign(initialiser_->ForEachIn(context), $M(cys, cyt)))->*
266 code_
267 ))
268 ));
269}
270
271CYFunctionParameter *CYForEachInComprehension::Parameter(CYContext &context) const {
272 return $ CYFunctionParameter(name_);
273}
274
275CYStatement *CYForEachInComprehension::Replace(CYContext &context, CYStatement *statement) const {
276 CYVariable *cys($V("$cys")), *name($ CYVariable(name_));
277
278 return $E($C0($F(NULL, $P1("$cys"), $$->*
279 $E($ CYAssign(cys, set_))->*
280 $ CYForIn(name, cys, $ CYBlock($$->*
281 $E($ CYAssign(name, $M(cys, name)))->*
282 CYComprehension::Replace(context, statement)
283 ))
284 )));
285}
286
287void CYFunction::Replace_(CYContext &context) {
288 code_.Replace(context);
289}
290
291CYExpression *CYFunctionExpression::Replace(CYContext &context) {
292 Replace_(context);
293 return NULL;
294}
295
296CYStatement *CYFunctionStatement::Replace(CYContext &context) {
297 Replace_(context);
298 return NULL;
299}
300
301CYStatement *CYIf::Replace(CYContext &context) {
302 context.Replace(test_);
303 context.Replace(true_);
304 context.Replace(false_);
305 return NULL;
306}
307
308CYFunctionParameter *CYIfComprehension::Parameter(CYContext &context) const {
309 return NULL;
310}
311
312CYStatement *CYIfComprehension::Replace(CYContext &context, CYStatement *statement) const {
313 return $ CYIf(test_, CYComprehension::Replace(context, statement));
314}
315
316CYExpression *CYIndirect::Replace(CYContext &context) {
317 CYPrefix::Replace(context);
318 return $M(rhs_, $S("$cyi"));
319}
320
321CYExpression *CYIndirectMember::Replace(CYContext &context) {
322 Replace_(context);
323 return $M($ CYIndirect(object_), property_);
324}
325
326CYExpression *CYInfix::Replace(CYContext &context) {
327 context.Replace(lhs_);
328 context.Replace(rhs_);
329 return NULL;
330}
331
332CYStatement *CYLabel::Replace(CYContext &context) {
333 context.Replace(statement_);
334 return NULL;
335}
336
337void CYMember::Replace_(CYContext &context) {
338 context.Replace(object_);
339 context.Replace(property_);
340}
341
3b52fd1a
JF
342CYExpression *CYNew::Replace(CYContext &context) {
343 context.Replace(constructor_);
344 arguments_->Replace(context);
345 return NULL;
346}
347
4644480a
JF
348CYNumber *CYNull::Number(CYContext &context) {
349 return $D(0);
350}
351
352CYString *CYNull::String(CYContext &context) {
353 return $S("null");
354}
355
356CYNumber *CYNumber::Number(CYContext &context) {
357 return this;
358}
359
360CYString *CYNumber::String(CYContext &context) {
361 // XXX: there is a precise algorithm for this
362 return $S(apr_psprintf(context.pool_, "%.17g", Value()));
363}
364
3b52fd1a
JF
365CYExpression *CYObject::Replace(CYContext &context) {
366 properties_->Replace(context);
367 return NULL;
368}
369
370CYExpression *CYPostfix::Replace(CYContext &context) {
371 context.Replace(lhs_);
372 return NULL;
373}
374
375CYExpression *CYPrefix::Replace(CYContext &context) {
376 context.Replace(rhs_);
377 return NULL;
378}
379
380void CYProgram::Replace(CYContext &context) {
381 statements_ = statements_->ReplaceAll(context);
382}
383
384void CYProperty::Replace(CYContext &context) { $T()
385 context.Replace(value_);
386 next_->Replace(context);
387}
388
389CYStatement *CYReturn::Replace(CYContext &context) {
390 context.Replace(value_);
391 return NULL;
392}
393
3b52fd1a
JF
394CYStatement *CYStatement::ReplaceAll(CYContext &context) { $T(NULL)
395 CYStatement *replace(this);
396 context.Replace(replace);
397
398 if (CYStatement *next = next_->ReplaceAll(context))
399 replace->SetNext(next);
400 else
401 replace->SetNext(next_);
402
403 return replace;
404}
405
4644480a
JF
406CYString *CYString::Concat(CYContext &context, CYString *rhs) const {
407 size_t size(size_ + rhs->size_);
408 char *value(new(context.pool_) char[size + 1]);
409 memcpy(value, value_, size_);
410 memcpy(value + size_, rhs->value_, rhs->size_);
411 value[size] = '\0';
412 return $S(value);
413}
414
415CYNumber *CYString::Number(CYContext &context) {
416 // XXX: there is a precise algorithm for this
417 return NULL;
418}
419
420CYString *CYString::String(CYContext &context) {
421 return this;
422}
423
3b52fd1a
JF
424CYStatement *CYSwitch::Replace(CYContext &context) {
425 context.Replace(value_);
426 clauses_->Replace(context);
427 return NULL;
428}
429
430CYExpression *CYThis::Replace(CYContext &context) {
431 return NULL;
432}
433
37954781
JF
434namespace cy {
435namespace Syntax {
436
437CYStatement *Throw::Replace(CYContext &context) {
3b52fd1a
JF
438 context.Replace(value_);
439 return NULL;
440}
441
37954781
JF
442} }
443
3b52fd1a
JF
444CYExpression *CYTrivial::Replace(CYContext &context) {
445 return NULL;
446}
447
4644480a
JF
448CYNumber *CYTrue::Number(CYContext &context) {
449 return $D(1);
450}
451
452CYString *CYTrue::String(CYContext &context) {
453 return $S("true");
454}
455
37954781
JF
456namespace cy {
457namespace Syntax {
458
459CYStatement *Try::Replace(CYContext &context) {
3b52fd1a
JF
460 code_.Replace(context);
461 catch_->Replace(context);
462 finally_->Replace(context);
463 return NULL;
464}
465
37954781
JF
466} }
467
3b52fd1a
JF
468CYStatement *CYVar::Replace(CYContext &context) {
469 declarations_->Replace(context);
470 return NULL;
471}
472
473CYExpression *CYVariable::Replace(CYContext &context) {
474 return NULL;
475}
476
477CYStatement *CYWhile::Replace(CYContext &context) {
478 context.Replace(test_);
479 context.Replace(code_);
480 return NULL;
481}
482
483CYStatement *CYWith::Replace(CYContext &context) {
484 context.Replace(scope_);
485 context.Replace(code_);
486 return NULL;
487}
488
489CYExpression *CYWord::ClassName(CYContext &context, bool object) {
490 CYString *name($S(this));
491 if (object)
492 return $C1($V("objc_getClass"), name);
493 else
494 return name;
495}