]> git.saurik.com Git - cycript.git/commitdiff
Add @encode() support and use its grammar for types.
authorJay Freeman (saurik) <saurik@saurik.com>
Sat, 15 Sep 2012 08:28:25 +0000 (01:28 -0700)
committerJay Freeman (saurik) <saurik@saurik.com>
Sat, 15 Sep 2012 08:30:37 +0000 (01:30 -0700)
Cycript.l.in
Cycript.yy.in
ObjectiveC/Output.mm
ObjectiveC/Replace.cpp
ObjectiveC/Syntax.hpp

index 58ed9fd7573d50e0310ad33d7c2ff08e6bded105..c946c89c12084d66f53928f46adab28789b0ff5e 100644 (file)
@@ -254,6 +254,7 @@ XMLName {XMLNameStart}{XMLNamePart}*
 @end
 
 @begin ObjectiveC
+"@encode"         L C F(tk::AtEncode, hi::Meta);
 "@end"            L C F(tk::AtEnd, hi::Meta);
 "@implementation" L C F(yyextra->no_.AtImplementation ? tk::AtImplementation_ : tk::AtImplementation, hi::Meta);
 "@import"         L C F(tk::AtImport, hi::Meta);
index 3f240e40651a809119b939539255d9c3afb573ed..92d57f68bdfc733727ca99cf000e23778b03d8ea 100644 (file)
@@ -73,6 +73,7 @@ typedef struct {
         CYMember *member_;
         CYNull *null_;
         CYNumber *number_;
+        CYEncodedPart *part_;
         CYProgram *program_;
         CYProperty *property_;
         CYPropertyName *propertyName_;
@@ -81,6 +82,7 @@ typedef struct {
         CYString *string_;
         CYThis *this_;
         CYTrue *true_;
+        CYEncodedType *type_;
         CYWord *word_;
 
 @begin ObjectiveC
@@ -228,6 +230,7 @@ int cylex(YYSTYPE *, cy::location *, void *);
 %token AtImplementation "@implementation"
 %token AtImplementation_ ";@implementation"
 %token AtImport "@import"
+%token AtEncode "@encode"
 %token AtEnd "@end"
 %token AtSelector "@selector"
 @end
@@ -451,6 +454,7 @@ int cylex(YYSTYPE *, cy::location *, void *);
 %type <statement_> WithStatement
 %type <word_> Word
 %type <word_> WordOpt
+%type <expression_> Variable
 
 @begin ObjectiveC
 %type <expression_> BoxableExpression
@@ -473,6 +477,8 @@ int cylex(YYSTYPE *, cy::location *, void *);
 %type <messageParameter_> MessageParameterList
 %type <messageParameter_> MessageParameterListOpt
 %type <bool_> MessageScope
+%type <type_> ModifiedType
+%type <part_> PrefixedType
 %type <argument_> SelectorCall_
 %type <argument_> SelectorCall
 %type <selector_> SelectorExpression_
@@ -480,7 +486,9 @@ int cylex(YYSTYPE *, cy::location *, void *);
 %type <selector_> SelectorExpressionOpt
 %type <argument_> SelectorList
 %type <word_> SelectorWordOpt
+%type <part_> SuffixedType
 %type <expression_> TypeOpt
+%type <type_> TypedIdentifier
 %type <argument_> VariadicCall
 @end
 
@@ -716,9 +724,13 @@ ParentheticalOpt
     | { $$ = NULL; }
     ;
 
+Variable
+    : Identifier { $$ = CYNew CYVariable($1); }
+    ;
+
 PrimaryExpression
     : "this" { $$ = $1; }
-    | Identifier { $$ = CYNew CYVariable($1); }
+    | Variable { $$ = $1; }
     | Literal { $$ = $1; }
     | ArrayLiteral { $$ = $1; }
     | ObjectLiteral { $$ = $1; }
@@ -1326,6 +1338,31 @@ ProgramBodyOpt
 /* }}} */
 
 @begin ObjectiveC
+/* Cycript (Objective-C): Type Encoding {{{ */
+SuffixedType
+    : { $$ = NULL; }
+    | "(" PrefixedType ")" { $$ = $2; }
+    | SuffixedType "[" NumericLiteral "]" { $$ = CYNew CYEncodedPart($1, "arrayOf", CYNew CYArgument($3)); }
+    ;
+
+PrefixedType
+    : SuffixedType { $$ = $1; }
+    | "*" PrefixedType { $$ = CYNew CYEncodedPart($2, "pointerTo"); }
+    ;
+
+ModifiedType
+    : Variable { $$ = CYNew CYEncodedType($1); }
+    | "const" ModifiedType { $2->base_ = CYNew CYCall(CYNew CYDirectMember($2->base_, CYNew CYString("constant"))); $$ = $2; }
+    ;
+
+TypedIdentifier
+    : ModifiedType PrefixedType { $1->parts_ = $2; $$ = $1;}
+    ;
+
+PrimaryExpression
+    : AtEncode "(" TypedIdentifier ")" { $$ = $3; }
+    ;
+/* }}} */
 /* Cycript (Objective-C): @class Declaration {{{ */
 ClassSuperOpt
     /* XXX: why the hell did I choose MemberExpression? */
@@ -1348,7 +1385,7 @@ MessageScope
     ;
 
 TypeOpt
-    : "(" Expression ")" { $$ = $2; }
+    : "(" TypedIdentifier ")" { $$ = $2; }
     | "(" LexSetRegExp "void" ")" { $$ = CYNew CYString("v"); }
     | { $$ = NULL; }
     ;
index 43172e25e7cf56729da38d11d1945db339f4def5..c90418d5a393f82474bd2bb57258703402dcc8b7 100644 (file)
@@ -75,6 +75,10 @@ void CYClassStatement::Output(CYOutput &out, CYFlags flags) const {
     CYClass::Output(out, flags);
 }
 
+void CYEncodedType::Output(CYOutput &out, CYFlags flags) const {
+    // XXX: this is seriously wrong
+}
+
 void CYField::Output(CYOutput &out) const {
 }
 
index 7f4e20663ad271d8a61ca7d8c2cda8985984d237..f6e98f1d060b568d060eb1e6d56582c174472f8c 100644 (file)
@@ -78,6 +78,14 @@ CYStatement *CYClassStatement::Replace(CYContext &context) {
     return $E(Replace_(context));
 }
 
+CYExpression *CYEncodedPart::Replace(CYContext &context, CYExpression *base) { $T(base)
+    return next_->Replace(context, $ CYCall($ CYDirectMember(base, $ CYString(name_)), arguments_));
+}
+
+CYExpression *CYEncodedType::Replace(CYContext &context) {
+    return parts_->Replace(context, base_);
+}
+
 CYStatement *CYField::Replace(CYContext &context) const { $T(NULL)
     CYVariable *cyn($V("$cyn"));
     CYVariable *cyt($V("$cyt"));
index 580ea3adbaddbdf7a468be134c6724d1257c0994..0caaad469544d96d81d18bf5ddb547a8ef9bba84 100644 (file)
 
 #include "Parser.hpp"
 
+struct CYEncodedPart :
+    CYNext<CYEncodedPart>
+{
+    const char *name_;
+    CYArgument *arguments_;
+
+    CYEncodedPart(CYEncodedPart *next, const char *name, CYArgument *arguments = NULL) :
+        CYNext<CYEncodedPart>(next),
+        name_(name),
+        arguments_(arguments)
+    {
+    }
+
+    CYExpression *Replace(CYContext &context, CYExpression *base);
+};
+
+struct CYEncodedType :
+    CYExpression
+{
+    CYExpression *base_;
+    CYEncodedPart *parts_;
+
+    CYEncodedType(CYExpression *base, CYEncodedPart *parts = NULL) :
+        base_(base),
+        parts_(parts)
+    {
+    }
+
+    CYPrecedence(1)
+
+    virtual CYExpression *Replace(CYContext &context);
+    virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
 struct CYBox :
     CYExpression
 {