From 56e02e5b879e679302c8d9a20654b8a193791a3a Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Sat, 15 Sep 2012 06:09:57 -0700 Subject: [PATCH] Allow Objective-C blocks as a short Functor syntax. --- Cycript.yy.in | 48 ++++++++++++++++++++++++++++++++++-------- ObjectiveC/Output.mm | 8 +++++++ ObjectiveC/Replace.cpp | 12 +++++++++++ ObjectiveC/Syntax.hpp | 35 ++++++++++++++++++++++++++++++ todo.txt | 3 +++ 5 files changed, 97 insertions(+), 9 deletions(-) diff --git a/Cycript.yy.in b/Cycript.yy.in index 90588f7..d049537 100644 --- a/Cycript.yy.in +++ b/Cycript.yy.in @@ -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 MessageParameterListOpt %type MessageScope %type ModifiedType -%type PrefixedType +%type PrefixedType +%type QualifiedType %type SelectorCall_ %type SelectorCall %type SelectorExpression_ @@ -487,9 +489,12 @@ int cylex(YYSTYPE *, cy::location *, void *); %type SelectorExpressionOpt %type SelectorList %type SelectorWordOpt -%type SuffixedType +%type SuffixedType %type TypeOpt -%type TypedIdentifier +%type TypedIdentifier +%type TypedParameterList_ +%type TypedParameterList +%type TypedParameterListOpt %type 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 diff --git a/ObjectiveC/Output.mm b/ObjectiveC/Output.mm index ecc8d1a..a2d765c 100644 --- a/ObjectiveC/Output.mm +++ b/ObjectiveC/Output.mm @@ -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) diff --git a/ObjectiveC/Replace.cpp b/ObjectiveC/Replace.cpp index a8515a5..96f6663 100644 --- a/ObjectiveC/Replace.cpp +++ b/ObjectiveC/Replace.cpp @@ -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))); +} diff --git a/ObjectiveC/Syntax.hpp b/ObjectiveC/Syntax.hpp index e910154..96e4604 100644 --- a/ObjectiveC/Syntax.hpp +++ b/ObjectiveC/Syntax.hpp @@ -106,6 +106,41 @@ struct CYTypedIdentifier : } }; +struct CYTypedParameter : + CYNext +{ + CYTypedIdentifier *typed_; + + CYTypedParameter(CYTypedIdentifier *typed, CYTypedParameter *next) : + CYNext(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 { diff --git a/todo.txt b/todo.txt index 4df4d2d..5d73856 100644 --- 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 -- 2.45.2