]> git.saurik.com Git - cycript.git/blobdiff - Replace.cpp
Add syntax akin to Java's anonymous inner classes.
[cycript.git] / Replace.cpp
index 7f5ca53a3ab142b63a836c99a839d7283bc9b3fc..7a99296e95849a93e026b4e524786c5908b8c373 100644 (file)
@@ -101,8 +101,8 @@ CYArgument *CYArgument::Replace(CYContext &context) { $T(NULL)
 }
 
 CYTarget *CYArray::Replace(CYContext &context) {
-    if (elements_ != NULL)
-        elements_->Replace(context);
+    CYForEach (element, elements_)
+        element->Replace(context);
     return this;
 }
 
@@ -347,8 +347,6 @@ void CYElementSpread::Replace(CYContext &context) {
 
 void CYElementValue::Replace(CYContext &context) {
     context.Replace(value_);
-    if (next_ != NULL)
-        next_->Replace(context);
 }
 
 CYForInitializer *CYEmpty::Replace(CYContext &context) {
@@ -383,6 +381,10 @@ CYFunctionParameter *CYExpression::Parameter() const {
     return NULL;
 }
 
+CYTarget *CYExtend::Replace(CYContext &context) {
+    return object_.Replace(context, lhs_);
+}
+
 CYStatement *CYExternal::Replace(CYContext &context) {
     return $E($ CYAssign($V(typed_->identifier_), $C1(typed_->Replace(context), $C2($V("dlsym"), $V("RTLD_DEFAULT"), $S(typed_->identifier_->Word())))));
 }
@@ -734,21 +736,25 @@ CYExpression *CYNumber::PropertyName(CYContext &context) {
     return String(context);
 }
 
-CYTarget *CYObject::Replace(CYContext &context) {
+CYTarget *CYObject::Replace(CYContext &context, CYTarget *seed) {
     CYBuilder builder;
     if (properties_ != NULL)
-        properties_ = properties_->ReplaceAll(context, builder, $ CYThis(), false);
+        properties_ = properties_->ReplaceAll(context, builder, $ CYThis(), seed != this);
 
     if (builder) {
         return $C1($M($ CYFunctionExpression(NULL, builder.bindings_->Parameter(context),
             builder.statements_
                 ->* $ CYReturn($ CYThis())
-        ), $S("call")), this, builder.bindings_->Argument(context));
+        ), $S("call")), seed, builder.bindings_->Argument(context));
     }
 
     CYForEach (property, properties_)
         property->Replace(context);
-    return this;
+    return seed;
+}
+
+CYTarget *CYObject::Replace(CYContext &context) {
+    return Replace(context, this);
 }
 
 CYTarget *CYParenthetical::Replace(CYContext &context) {
@@ -880,6 +886,10 @@ void CYScript::Replace(CYContext &context) {
     }
 }
 
+CYTarget *CYResolveMember::Replace(CYContext &context) {
+    return $M($M(object_, $S("$cyr")), property_);
+}
+
 CYStatement *CYReturn::Replace(CYContext &context) {
     if (context.nonlocal_ != NULL) {
         CYProperty *value(value_ == NULL ? NULL : $ CYPropertyValue($S("$cyv"), value_));
@@ -893,7 +903,7 @@ CYStatement *CYReturn::Replace(CYContext &context) {
 }
 
 CYTarget *CYRubyBlock::Replace(CYContext &context) {
-    return call_->AddArgument(context, proc_->Replace(context));
+    return lhs_->AddArgument(context, proc_->Replace(context));
 }
 
 CYTarget *CYRubyBlock::AddArgument(CYContext &context, CYExpression *value) {
@@ -1090,6 +1100,32 @@ CYString *CYString::String(CYContext &context) {
     return this;
 }
 
+CYStatement *CYStructDefinition::Replace(CYContext &context) {
+    CYTarget *target(tail_->Replace(context));
+    if (name_ != NULL)
+        target = $C1($M(target, $S("withName")), $S(name_->Word()));
+    return $ CYLexical(false, $B1($B($I($pool.strcat(name_->Word(), "$cy", NULL)), target)));
+}
+
+CYTarget *CYStructTail::Replace(CYContext &context) {
+    CYList<CYElementValue> types;
+    CYList<CYElementValue> names;
+
+    CYForEach (field, fields_) {
+        CYTypedIdentifier *typed(field->typed_);
+        types->*$ CYElementValue(typed->Replace(context));
+
+        CYExpression *name;
+        if (typed->identifier_ == NULL)
+            name = NULL;
+        else
+            name = $S(typed->identifier_->Word());
+        names->*$ CYElementValue(name);
+    }
+
+    return $N2($V("Type"), $ CYArray(types), $ CYArray(names));
+}
+
 CYTarget *CYSuperAccess::Replace(CYContext &context) {
     return $C1($M($M($M($V(context.super_), $S("prototype")), property_), $S("bind")), $ CYThis());
 }
@@ -1098,6 +1134,10 @@ CYTarget *CYSuperCall::Replace(CYContext &context) {
     return $C($C1($M($V(context.super_), $S("bind")), $ CYThis()), arguments_);
 }
 
+CYTarget *CYSymbol::Replace(CYContext &context) {
+    return $C1($M($V("Symbol"), $S("for")), $S(name_));
+}
+
 CYStatement *CYSwitch::Replace(CYContext &context) {
     context.Replace(value_);
     clauses_->Replace(context);
@@ -1165,6 +1205,15 @@ CYTarget *CYTypeBlockWith::Replace_(CYContext &context, CYTarget *type) {
     return next_->Replace(context, $ CYCall($ CYDirectMember(type, $ CYString("blockWith")), parameters_->Argument(context)));
 }
 
+CYTarget *CYTypeCharacter::Replace(CYContext &context) {
+    switch (signing_) {
+        case CYTypeNeutral: return $V("char");
+        case CYTypeSigned: return $V("schar");
+        case CYTypeUnsigned: return $V("uchar");
+        default: _assert(false);
+    }
+}
+
 CYTarget *CYTypeConstant::Replace_(CYContext &context, CYTarget *type) {
     return next_->Replace(context, $ CYCall($ CYDirectMember(type, $ CYString("constant"))));
 }
@@ -1184,56 +1233,43 @@ CYTarget *CYTypeExpression::Replace(CYContext &context) {
     return typed_->Replace(context);
 }
 
+CYTarget *CYTypeIntegral::Replace(CYContext &context) {
+    bool u(signing_ == CYTypeUnsigned);
+    switch (length_) {
+        case 0: return $V(u ? "ushort" : "short");
+        case 1: return $V(u ? "uint" : "int");
+        case 2: return $V(u ? "ulong" : "long");
+        case 3: return $V(u ? "ulonglong" : "longlong");
+        default: _assert(false);
+    }
+}
+
 CYTarget *CYTypeModifier::Replace(CYContext &context, CYTarget *type) { $T(type)
     return Replace_(context, type);
 }
 
 CYTarget *CYTypeFunctionWith::Replace_(CYContext &context, CYTarget *type) {
-    return next_->Replace(context, $ CYCall($ CYDirectMember(type, $ CYString("functionWith")), parameters_->Argument(context)));
-}
-
-CYTarget *CYTypeLong::Replace(CYContext &context) {
-    return $ CYCall($ CYDirectMember(specifier_->Replace(context), $ CYString("long")));
+    CYList<CYArgument> arguments(parameters_->Argument(context));
+    if (variadic_)
+        arguments->*$C_($ CYNull());
+    return next_->Replace(context, $ CYCall($ CYDirectMember(type, $ CYString("functionWith")), arguments));
 }
 
 CYTarget *CYTypePointerTo::Replace_(CYContext &context, CYTarget *type) {
     return next_->Replace(context, $ CYCall($ CYDirectMember(type, $ CYString("pointerTo"))));
 }
 
-CYTarget *CYTypeShort::Replace(CYContext &context) {
-    return $ CYCall($ CYDirectMember(specifier_->Replace(context), $ CYString("short")));
-}
-
-CYTarget *CYTypeSigned::Replace(CYContext &context) {
-    return $ CYCall($ CYDirectMember(specifier_->Replace(context), $ CYString("signed")));
+CYTarget *CYTypeReference::Replace(CYContext &context) {
+    return $V($pool.strcat(name_->Word(), "$cy", NULL));
 }
 
 CYTarget *CYTypeStruct::Replace(CYContext &context) {
-    CYList<CYElementValue> types;
-    CYList<CYElementValue> names;
-
-    CYForEach (field, fields_) {
-        CYTypedIdentifier *typed(field->typed_);
-        types->*$ CYElementValue(typed->Replace(context));
-
-        CYExpression *name;
-        if (typed->identifier_ == NULL)
-            name = NULL;
-        else
-            name = $S(typed->identifier_->Word());
-        names->*$ CYElementValue(name);
-    }
-
-    CYTarget *target($N2($V("Type"), $ CYArray(types), $ CYArray(names)));
+    CYTarget *target(tail_->Replace(context));
     if (name_ != NULL)
         target = $C1($M(target, $S("withName")), $S(name_->Word()));
     return target;
 }
 
-CYTarget *CYTypeUnsigned::Replace(CYContext &context) {
-    return $ CYCall($ CYDirectMember(specifier_->Replace(context), $ CYString("unsigned")));
-}
-
 CYTarget *CYTypeVariable::Replace(CYContext &context) {
     return $V(name_);
 }
@@ -1251,15 +1287,15 @@ CYTarget *CYTypedIdentifier::Replace(CYContext &context) {
 }
 
 CYTypeFunctionWith *CYTypedIdentifier::Function() {
-    CYTypeModifier **modifier(&modifier_);
-    if (*modifier == NULL)
+    CYTypeModifier *&modifier(CYGetLast(modifier_));
+    if (modifier == NULL)
         return NULL;
-    while ((*modifier)->next_ != NULL)
-        modifier = &(*modifier)->next_;
-    CYTypeFunctionWith *function((*modifier)->Function());
+
+    CYTypeFunctionWith *function(modifier->Function());
     if (function == NULL)
         return NULL;
-    *modifier = NULL;
+
+    modifier = NULL;
     return function;
 }