]> git.saurik.com Git - cycript.git/commitdiff
Drastically improve syntax support for @encode().
authorJay Freeman (saurik) <saurik@saurik.com>
Thu, 9 Jan 2014 15:50:10 +0000 (07:50 -0800)
committerJay Freeman (saurik) <saurik@saurik.com>
Thu, 9 Jan 2014 15:50:10 +0000 (07:50 -0800)
Cycript.yy.in
Parser.hpp
Replace.cpp

index 3f3fccea8e11d97b10b8f7a06fd5ec6a6f4f765a..c4af37250847f0a1d50ebd0b700f986f716495bf 100644 (file)
@@ -465,6 +465,7 @@ int cylex(YYSTYPE *, cy::location *, void *);
 %type <expression_> Variable
 
 @begin ObjectiveC
+%type <typedIdentifier_> ArrayedType
 %type <expression_> BoxableExpression
 %type <statement_> CategoryStatement
 %type <expression_> ClassExpression
@@ -479,6 +480,7 @@ int cylex(YYSTYPE *, cy::location *, void *);
 %type <protocol_> ClassProtocolListOpt
 %type <protocol_> ClassProtocols
 %type <protocol_> ClassProtocolsOpt
+%type <type_> ConcreteType
 %type <expression_> EncodedType
 %type <expression_> MessageExpression
 %type <messageParameter_> MessageParameter
@@ -486,10 +488,10 @@ int cylex(YYSTYPE *, cy::location *, void *);
 %type <messageParameter_> MessageParameterList
 %type <messageParameter_> MessageParameterListOpt
 %type <bool_> MessageScope
+%type <type_> ModifiedType_
 %type <type_> ModifiedType
 %type <typedIdentifier_> PrefixedType
 %type <expression_> PrimitiveType
-%type <type_> QualifiedType
 %type <argument_> SelectorCall_
 %type <argument_> SelectorCall
 %type <selector_> SelectorExpression_
@@ -499,6 +501,10 @@ int cylex(YYSTYPE *, cy::location *, void *);
 %type <word_> SelectorWordOpt
 %type <typedIdentifier_> SuffixedType
 %type <expression_> TypeOpt
+%type <typedIdentifier_> TypeParenthetical
+%type <type_> TypeQualifierLeft
+%type <type_> TypeQualifierRight
+%type <typedIdentifier_> TypeSignifier
 %type <typedIdentifier_> TypedIdentifier
 %type <typedParameter_> TypedParameterList_
 %type <typedParameter_> TypedParameterList
@@ -1359,42 +1365,67 @@ ProgramBodyOpt
 
 @begin ObjectiveC
 /* Cycript (Objective-C): Type Encoding {{{ */
+TypeParenthetical
+    : "(" PrefixedType ")" { $$ = $2; }
+    ;
+
+TypeSignifier
+    : Identifier { $$ = CYNew CYTypedIdentifier($1); }
+    | TypeParenthetical
+    ;
+
+ArrayedType
+    : ArrayedType "[" NumericLiteral "]" { $$ = $1; CYSetLast($$->type_) = CYNew CYTypeArrayOf($3); }
+    | TypeSignifier { $$ = $1; }
+    | { $$ = CYNew CYTypedIdentifier(NULL); }
+    ;
+
 SuffixedType
-    : IdentifierOpt { $$ = CYNew CYTypedIdentifier($1); }
-    | "(" LexPushInOff PrefixedType ")" LexPopIn { $$ = $3; }
-    | SuffixedType "[" NumericLiteral "]" { CYSetLast($1->type_) = CYNew CYTypeArrayOf($3); $$ = $1; }
+    : ArrayedType { $$ = $1; }
+    | TypeParenthetical "(" LexPushInOff TypedParameterListOpt ")" LexPopIn { $$ = $1; CYSetLast($$->type_) = CYNew CYTypeFunctionWith($4); }
     ;
 
 PrefixedType
-    : SuffixedType { $$ = $1; }
-    | "const" PrefixedType { CYSetLast($2->type_) = CYNew CYTypeConstant(); $$ = $2; }
-    | "*" PrefixedType { CYSetLast($2->type_) = CYNew CYTypePointerTo(); $$ = $2; }
+    : "*" TypeQualifierRight PrefixedType { $$ = $3; CYSetLast($$->type_) = $2; CYSetLast($$->type_) = CYNew CYTypePointerTo(); }
+    | SuffixedType { $$ = $1; }
     ;
 
-PrimitiveType
-    : Variable { $$ = $1; }
-    | "void" { $$  = CYNew cy::Syntax::New(CYNew CYVariable(CYNew CYIdentifier("Type")), CYNew CYArgument(CYNew CYString("v"))); }
+TypeQualifierLeft
+    : "const" TypeQualifierLeft { $$ = CYNew CYTypeConstant(); CYSetLast($$) = $2; }
+    | { $$ = NULL; }
+    ;
+
+TypeQualifierRight
+    : TypeQualifierRight "const" { $$ = CYNew CYTypeConstant($1); }
+    | { $$ = NULL; }
     ;
 
-QualifiedType
-    : PrimitiveType { $$ = CYNew CYTypeVariable($1); }
-    | "const" QualifiedType { $$ = CYNew CYTypeConstant($2); }
+ConcreteType
+    : TypeQualifierLeft PrimitiveType TypeQualifierRight { $$ = $3; CYSetLast($$) = $1; CYSetLast($$) = CYNew CYTypeVariable($2); }
     ;
 
-ModifiedType
-    : QualifiedType { $$ = $1; }
-    | QualifiedType "*" { $$ = CYNew CYTypePointerTo($1); }
-    | QualifiedType "const" { $$ = CYNew CYTypeConstant($1); }
+PrimitiveType
+    : Variable { $$ = $1; }
+    | "void" { $$  = CYNew cy::Syntax::New(CYNew CYVariable(CYNew CYIdentifier("Type")), CYNew CYArgument(CYNew CYString("v"))); }
     ;
 
 TypedIdentifier
-    : QualifiedType PrefixedType { CYSetLast($2->type_) = $1; $$ = $2;}
+    : ConcreteType PrefixedType { $$ = $2; CYSetLast($$->type_) = $1; }
     ;
 
 EncodedType
     : TypedIdentifier { $$ = CYNew CYEncodedType($1->type_); }
     ;
 
+ModifiedType_
+    : TypeQualifierLeft PrimitiveType { $$ = $1; CYSetLast($$) = CYNew CYTypeVariable($2); }
+    | ModifiedType "*" { $$ = CYNew CYTypePointerTo($1); }
+    ;
+
+ModifiedType
+    : ModifiedType_ TypeQualifierRight { $$ = $2; CYSetLast($$) = $1; }
+    ;
+
 PrimaryExpression
     : AtEncode "(" EncodedType ")" { $$ = $3; }
     ;
@@ -1628,7 +1659,7 @@ TypedParameterListOpt
     ;
 
 PrimaryExpression
-    : "[" LexPushInOff LexSetRegExp "&" LexSetRegExp "]" LexPopIn "(" LexPushInOff TypedParameterListOpt ")" LexPopIn "->" ModifiedType BRACE LexPushInOff FunctionBody "}" LexPopIn { $$ = CYNew CYLambda($14, $10, $17); }
+    : "[" LexPushInOff LexSetRegExp "&" LexSetRegExp "]" LexPopIn "(" LexPushInOff TypedParameterListOpt ")" LexPopIn "->" TypedIdentifier BRACE LexPushInOff FunctionBody "}" LexPopIn { $$ = CYNew CYLambda($14->type_, $10, $17); }
     ;
 /* }}} */
 /* Cycript (C): Type Definitions {{{ */
index 110cf0d6205901612ee788142945968cd1ef32a4..be97c0b49d09d91f1abdcd993adc2f4d76f114e7 100644 (file)
@@ -1696,6 +1696,7 @@ struct CYTypedParameter :
     {
     }
 
+    CYArgument *Argument(CYContext &context);
     CYFunctionParameter *Parameters(CYContext &context);
     CYExpression *TypeSignature(CYContext &context, CYExpression *prefix);
 };
@@ -1734,6 +1735,22 @@ struct CYTypeDefinition :
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
 
+struct CYTypeFunctionWith :
+    CYTypeModifier
+{
+    CYTypedParameter *parameters_;
+
+    CYTypeFunctionWith(CYTypedParameter *parameters, CYTypeModifier *next = NULL) :
+        CYTypeModifier(next),
+        parameters_(parameters)
+    {
+    }
+
+    CYPrecedence(2)
+
+    virtual CYExpression *Replace(CYContext &context);
+};
+
 namespace cy {
 namespace Syntax {
 
index a4a31eaac6b286f065311e5a5765d147c92819dd..f1283dec929178d10523a6b132a4ec3942c24c5f 100644 (file)
@@ -877,6 +877,10 @@ CYStatement *CYTypeDefinition::Replace(CYContext &context) {
     return $E($ CYAssign($V(typed_->identifier_), typed_->type_->Replace(context)));
 }
 
+CYExpression *CYTypeFunctionWith::Replace(CYContext &context) {
+    return $ CYCall($ CYDirectMember(next_->Replace(context), $ CYString("functionWith")), parameters_->Argument(context));
+}
+
 CYExpression *CYTypePointerTo::Replace(CYContext &context) {
     return $ CYCall($ CYDirectMember(next_->Replace(context), $ CYString("pointerTo")));
 }
@@ -885,6 +889,10 @@ CYExpression *CYTypeVariable::Replace(CYContext &context) {
     return expression_;
 }
 
+CYArgument *CYTypedParameter::Argument(CYContext &context) { $T(NULL)
+    return $ CYArgument(typed_->type_->Replace(context), next_->Argument(context));
+}
+
 CYFunctionParameter *CYTypedParameter::Parameters(CYContext &context) { $T(NULL)
     return $ CYFunctionParameter($ CYDeclaration(typed_->identifier_ ?: context.Unique()), next_->Parameters(context));
 }