From 663c538f2306bb586edeb3e7ff501863acf8e89b Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Thu, 9 Jan 2014 07:50:10 -0800 Subject: [PATCH] Drastically improve syntax support for @encode(). --- Cycript.yy.in | 69 +++++++++++++++++++++++++++++++++++++-------------- Parser.hpp | 17 +++++++++++++ Replace.cpp | 8 ++++++ 3 files changed, 75 insertions(+), 19 deletions(-) diff --git a/Cycript.yy.in b/Cycript.yy.in index 3f3fcce..c4af372 100644 --- a/Cycript.yy.in +++ b/Cycript.yy.in @@ -465,6 +465,7 @@ int cylex(YYSTYPE *, cy::location *, void *); %type Variable @begin ObjectiveC +%type ArrayedType %type BoxableExpression %type CategoryStatement %type ClassExpression @@ -479,6 +480,7 @@ int cylex(YYSTYPE *, cy::location *, void *); %type ClassProtocolListOpt %type ClassProtocols %type ClassProtocolsOpt +%type ConcreteType %type EncodedType %type MessageExpression %type MessageParameter @@ -486,10 +488,10 @@ int cylex(YYSTYPE *, cy::location *, void *); %type MessageParameterList %type MessageParameterListOpt %type MessageScope +%type ModifiedType_ %type ModifiedType %type PrefixedType %type PrimitiveType -%type QualifiedType %type SelectorCall_ %type SelectorCall %type SelectorExpression_ @@ -499,6 +501,10 @@ int cylex(YYSTYPE *, cy::location *, void *); %type SelectorWordOpt %type SuffixedType %type TypeOpt +%type TypeParenthetical +%type TypeQualifierLeft +%type TypeQualifierRight +%type TypeSignifier %type TypedIdentifier %type TypedParameterList_ %type 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 {{{ */ diff --git a/Parser.hpp b/Parser.hpp index 110cf0d..be97c0b 100644 --- a/Parser.hpp +++ b/Parser.hpp @@ -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 { diff --git a/Replace.cpp b/Replace.cpp index a4a31ea..f1283de 100644 --- a/Replace.cpp +++ b/Replace.cpp @@ -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)); } -- 2.45.2