]> git.saurik.com Git - cycript.git/commitdiff
Allow Objective-C blocks as a short Functor syntax.
authorJay Freeman (saurik) <saurik@saurik.com>
Sat, 15 Sep 2012 13:09:57 +0000 (06:09 -0700)
committerJay Freeman (saurik) <saurik@saurik.com>
Sat, 15 Sep 2012 13:09:57 +0000 (06:09 -0700)
Cycript.yy.in
ObjectiveC/Output.mm
ObjectiveC/Replace.cpp
ObjectiveC/Syntax.hpp
todo.txt

index 90588f78237c3aa455e1675fb36f747f63973200..d049537cbd27ff1f4f59eb592a5dd54f6027a06b 100644 (file)
@@ -82,7 +82,8 @@ typedef struct {
         CYThis *this_;
         CYTrue *true_;
         CYTypeModifier *type_;
-        CYTypedIdentifier *typed_;
+        CYTypedIdentifier *typedIdentifier_;
+        CYTypedParameter *typedParameter_;
         CYWord *word_;
 
 @begin ObjectiveC
@@ -479,7 +480,8 @@ int cylex(YYSTYPE *, cy::location *, void *);
 %type <messageParameter_> MessageParameterListOpt
 %type <bool_> MessageScope
 %type <type_> ModifiedType
-%type <typed_> PrefixedType
+%type <typedIdentifier_> PrefixedType
+%type <type_> QualifiedType
 %type <argument_> SelectorCall_
 %type <argument_> SelectorCall
 %type <selector_> SelectorExpression_
@@ -487,9 +489,12 @@ int cylex(YYSTYPE *, cy::location *, void *);
 %type <selector_> SelectorExpressionOpt
 %type <argument_> SelectorList
 %type <word_> SelectorWordOpt
-%type <typed_> SuffixedType
+%type <typedIdentifier_> SuffixedType
 %type <expression_> TypeOpt
-%type <typed_> TypedIdentifier
+%type <typedIdentifier_> TypedIdentifier
+%type <typedParameter_> TypedParameterList_
+%type <typedParameter_> TypedParameterList
+%type <typedParameter_> TypedParameterListOpt
 %type <argument_> VariadicCall
 @end
 
@@ -1342,7 +1347,7 @@ ProgramBodyOpt
 /* Cycript (Objective-C): Type Encoding {{{ */
 SuffixedType
     : IdentifierOpt { $$ = CYNew CYTypedIdentifier($1); }
-    | "(" PrefixedType ")" { $$ = $2; }
+    | "(" LexPushInOff PrefixedType LexPopIn ")" { $$ = $3; }
     | SuffixedType "[" NumericLiteral "]" { CYSetLast($1->type_) = CYNew CYTypeArrayOf($3->Value()); $$ = $1; }
     ;
 
@@ -1352,13 +1357,19 @@ PrefixedType
     | "*" PrefixedType { CYSetLast($2->type_) = CYNew CYTypePointerTo(); $$ = $2; }
     ;
 
-ModifiedType
+QualifiedType
     : Variable { $$ = CYNew CYTypeVariable($1); }
-    | "const" ModifiedType { $$ = CYNew CYTypeConstant($2); }
+    | "const" QualifiedType { $$ = CYNew CYTypeConstant($2); }
+    ;
+
+ModifiedType
+    : QualifiedType { $$ = $1; }
+    | QualifiedType "*" { $$ = CYNew CYTypePointerTo($1); }
+    | QualifiedType "const" { $$ = CYNew CYTypeConstant($1); }
     ;
 
 TypedIdentifier
-    : ModifiedType PrefixedType { CYSetLast($2->type_) = $1; $$ = $2;}
+    : QualifiedType PrefixedType { CYSetLast($2->type_) = $1; $$ = $2;}
     ;
 
 EncodedType
@@ -1391,7 +1402,7 @@ MessageScope
     ;
 
 TypeOpt
-    : "(" EncodedType ")" { $$ = $2; }
+    : "(" LexSetRegExp EncodedType ")" { $$ = $3; }
     | "(" LexSetRegExp "void" ")" { $$ = CYNew CYString("v"); }
     | { $$ = NULL; }
     ;
@@ -1555,6 +1566,25 @@ PrimaryExpression
     : "@" BoxableExpression { $$ = CYNew CYBox($2); }
     ;
 /* }}} */
+/* Cycript (Objective-C): Block Expressions {{{ */
+TypedParameterList_
+    : "," TypedParameterList { $$ = $2; }
+    | { $$ = NULL; }
+    ;
+
+TypedParameterList
+    : TypedIdentifier TypedParameterList_ { $$ = CYNew CYTypedParameter($1, $2); }
+    ;
+
+TypedParameterListOpt
+    : TypedParameterList { $$ = $1; }
+    | { $$ = NULL; }
+    ;
+
+PrimaryExpression
+    : "^" ModifiedType "(" LexPushInOff TypedParameterListOpt LexPopIn ")" BRACE LexPushInOff FunctionBody LexPopIn "}" { $$ = CYNew CYObjCBlock($2, $5, $10); }
+    ;
+/* }}} */
 @end
 
 @begin C
index ecc8d1a4bdc77fc9f39cfb9d5a940c16d486f446..a2d765cbebc03164eacb03175fe22f46246b6388 100644 (file)
@@ -106,6 +106,14 @@ void CYBox::Output(CYOutput &out, CYFlags flags) const {
     value_->Output(out, Precedence(), CYRight(flags));
 }
 
+void CYObjCBlock::Output(CYOutput &out, CYFlags flags) const {
+    // XXX: this is seriously wrong
+    out << "^(";
+    out << ")";
+    out << "{";
+    out << "}";
+}
+
 void CYProtocol::Output(CYOutput &out) const {
     name_->Output(out, CYAssign::Precedence_, CYNoFlags);
     if (next_ != NULL)
index a8515a5ee4555610e35dc11c62add543b45dfb17..96f66630fecea261f3667ea76e45d22fb3b6a39a 100644 (file)
@@ -166,6 +166,10 @@ CYExpression *CYBox::Replace(CYContext &context) {
     return $C1($M($V("Instance"), $S("box")), value_);
 }
 
+CYExpression *CYObjCBlock::Replace(CYContext &context) {
+    return $N2($V("Functor"), $ CYFunctionExpression(NULL, parameters_->Parameters(context), statements_), parameters_->TypeSignature(context, type_->Replace(context)));
+}
+
 CYStatement *CYProtocol::Replace(CYContext &context) const { $T(NULL)
     return $ CYBlock($$->*
         next_->Replace(context)->*
@@ -218,3 +222,11 @@ CYExpression *CYSendDirect::Replace(CYContext &context) {
 CYExpression *CYSendSuper::Replace(CYContext &context) {
     return $ CYSendDirect($V("$cyr"), arguments_);
 }
+
+CYFunctionParameter *CYTypedParameter::Parameters(CYContext &context) { $T(NULL)
+    return $ CYFunctionParameter($ CYDeclaration(typed_->identifier_), next_->Parameters(context));
+}
+
+CYExpression *CYTypedParameter::TypeSignature(CYContext &context, CYExpression *prefix) { $T(prefix)
+    return next_->TypeSignature(context, $ CYAdd(prefix, typed_->type_->Replace(context)));
+}
index e9101541f23c5960f05c55be9f96e5f1a8e93fb1..96e4604ec824c9bb746f35c8199bfe55c13b328b 100644 (file)
@@ -106,6 +106,41 @@ struct CYTypedIdentifier :
     }
 };
 
+struct CYTypedParameter :
+    CYNext<CYTypedParameter>
+{
+    CYTypedIdentifier *typed_;
+
+    CYTypedParameter(CYTypedIdentifier *typed, CYTypedParameter *next) :
+        CYNext<CYTypedParameter>(next),
+        typed_(typed)
+    {
+    }
+
+    CYFunctionParameter *Parameters(CYContext &context);
+    CYExpression *TypeSignature(CYContext &context, CYExpression *prefix);
+};
+
+struct CYObjCBlock :
+    CYExpression
+{
+    CYTypeModifier *type_;
+    CYTypedParameter *parameters_;
+    CYStatement *statements_;
+
+    CYObjCBlock(CYTypeModifier *type, CYTypedParameter *parameters, CYStatement *statements) :
+        type_(type),
+        parameters_(parameters),
+        statements_(statements)
+    {
+    }
+
+    CYPrecedence(1)
+
+    virtual CYExpression *Replace(CYContext &context);
+    virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
 struct CYEncodedType :
     CYExpression
 {
index 4df4d2d28078432522abf51fddf90fded6851c1e..5d73856aca3d80fd82df5dfb7cfbb8c88ff30257 100644 (file)
--- a/todo.txt
+++ b/todo.txt
@@ -113,3 +113,6 @@ http://gcc.gnu.org/onlinedocs/gcc/Type-encoding.html
 http://gcc.gnu.org/onlinedocs/gcc/Legacy-type-encoding.html
 
 using .withName from the grammar is a horrible hack that makes other uses impossible
+
+blocks should be allowed to return blocks/functions: ModifiedType needs to go
+  instead, TypedParameterList should be folded into a TypeModifier with the other types