X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/b0385401f63fe31f3cc1459ed159747a445852d6..8a392978b2d6e7db62cdf6d576e071d70fef9b94:/Replace.cpp diff --git a/Replace.cpp b/Replace.cpp index 74f04d9..06b6359 100644 --- a/Replace.cpp +++ b/Replace.cpp @@ -29,6 +29,11 @@ CYFunctionExpression *CYNonLocalize(CYContext &context, CYFunctionExpression *fu return function; } +static void CYImplicitReturn(CYStatement *&code) { + if (CYStatement *&last = CYGetLast(code)) + last = last->Return(); +} + CYExpression *CYAdd::Replace(CYContext &context) { CYInfix::Replace(context); @@ -75,7 +80,8 @@ CYArgument *CYArgument::Replace(CYContext &context) { $T(NULL) } CYExpression *CYArray::Replace(CYContext &context) { - elements_->Replace(context); + if (elements_ != NULL) + elements_->Replace(context); return this; } @@ -95,6 +101,11 @@ CYExpression *CYAssignment::Replace(CYContext &context) { return this; } +CYStatement *CYBlock::Return() { + CYImplicitReturn(code_); + return this; +} + CYStatement *CYBlock::Replace(CYContext &context) { context.ReplaceAll(code_); if (code_ == NULL) @@ -141,10 +152,6 @@ void CYClause::Replace(CYContext &context) { $T() next_->Replace(context); } -CYStatement *CYComment::Replace(CYContext &context) { - return this; -} - CYExpression *CYCompound::Replace(CYContext &context) { context.Replace(expression_); context.Replace(next_); @@ -292,9 +299,14 @@ CYStatement *CYDoWhile::Replace(CYContext &context) { return this; } -void CYElement::Replace(CYContext &context) { $T() +void CYElementSpread::Replace(CYContext &context) { context.Replace(value_); - next_->Replace(context); +} + +void CYElementValue::Replace(CYContext &context) { + context.Replace(value_); + if (next_ != NULL) + next_->Replace(context); } CYStatement *CYEmpty::Replace(CYContext &context) { @@ -305,6 +317,10 @@ CYExpression *CYEncodedType::Replace(CYContext &context) { return typed_->Replace(context); } +CYStatement *CYExpress::Return() { + return $ CYReturn(expression_); +} + CYStatement *CYExpress::Replace(CYContext &context) { context.Replace(expression_); return this; @@ -430,7 +446,8 @@ void CYFunction::Replace_(CYContext &context, bool outer) { Inject(context); CYThisScope *_this(context.this_); - context.this_ = CYGetLast(&this_); + context.this_ = &this_; + context.this_ = CYGetLast(context.this_); CYNonLocal *nonlocal(context.nonlocal_); CYNonLocal *nextlocal(context.nextlocal_); @@ -453,6 +470,9 @@ void CYFunction::Replace_(CYContext &context, bool outer) { parameters_->Replace(context, code_); context.ReplaceAll(code_); + if (implicit_) + CYImplicitReturn(code_); + if (CYIdentifier *identifier = this_.identifier_) code_ = $$->* $ CYVar($L1($ CYDeclaration(identifier, $ CYThis())))->* @@ -501,6 +521,12 @@ CYIdentifier *CYIdentifier::Replace(CYContext &context) { return replace_; } +CYStatement *CYIf::Return() { + CYImplicitReturn(true_); + CYImplicitReturn(false_); + return this; +} + CYStatement *CYIf::Replace(CYContext &context) { context.Replace(test_); context.ReplaceAll(true_); @@ -633,7 +659,7 @@ namespace { typedef std::set IdentifierUsages; } -void CYProgram::Replace(CYContext &context) { +void CYScript::Replace(CYContext &context) { CYScope scope(true, context); context.nextlocal_ = $ CYNonLocal(); @@ -709,12 +735,14 @@ CYStatement *CYReturn::Replace(CYContext &context) { } CYExpression *CYRubyBlock::Replace(CYContext &context) { - // XXX: this needs to do something much more epic to handle return return call_->AddArgument(context, proc_->Replace(context)); } CYExpression *CYRubyProc::Replace(CYContext &context) { - return CYNonLocalize(context, $ CYFunctionExpression(NULL, parameters_, code_)); + CYFunctionExpression *function($ CYFunctionExpression(NULL, parameters_, code_)); + function = CYNonLocalize(context, function); + function->implicit_ = true; + return function; } CYScope::CYScope(bool transparent, CYContext &context) : @@ -831,6 +859,14 @@ void CYScope::Close(CYContext &context, CYStatement *&statements) { } } +CYElementValue *CYSpan::Replace(CYContext &context) { $T(NULL) + return $ CYElementValue(expression_, $ CYElementValue(string_, next_->Replace(context))); +} + +CYStatement *CYStatement::Return() { + return this; +} + CYString *CYString::Concat(CYContext &context, CYString *rhs) const { size_t size(size_ + rhs->size_); char *value($ char[size + 1]); @@ -855,6 +891,10 @@ CYStatement *CYSwitch::Replace(CYContext &context) { return this; } +CYExpression *CYTemplate::Replace(CYContext &context) { + return $C2($M($M($M($V("String"), $S("prototype")), $S("concat")), $S("apply")), $S(""), $ CYArray($ CYElementValue(string_, spans_->Replace(context)))); +} + CYExpression *CYThis::Replace(CYContext &context) { if (context.this_ != NULL) return $V(context.this_->Identifier(context));