]> git.saurik.com Git - cycript.git/blobdiff - Replace.cpp
Limit recompilation of files upon changed grammar.
[cycript.git] / Replace.cpp
index 74f04d9d489f7712d48366cd7837dc44ca35a32e..06b6359fcc2c3ec7a8f42a0095f78d4e692c38aa 100644 (file)
@@ -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<CYIdentifier *, IdentifierUsageLess> 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));