]> git.saurik.com Git - cycript.git/blobdiff - Parser.ypp.in
Attach FFI closure deallocation to Functor's pool.
[cycript.git] / Parser.ypp.in
index 3d5aa6d4a31802054043032cdfd85891280e1080..acda20a719a51fdbd1d724d57d2d0647d986c3e8 100644 (file)
@@ -81,6 +81,7 @@
 %union { CYWord *word_; }
 
 @begin C
+%union { CYTypeIntegral *integral_; }
 %union { CYTypeStructField *structField_; }
 %union { CYTypeModifier *modifier_; }
 %union { CYTypeSpecifier *specifier_; }
@@ -89,6 +90,7 @@
 @end
 
 @begin ObjectiveC
+%union { CYObjCKeyValue *keyValue_; }
 %union { CYImplementationField *implementationField_; }
 %union { CYMessage *message_; }
 %union { CYMessageParameter *messageParameter_; }
@@ -424,6 +426,8 @@ type; })
 %token ___proto___ "__proto__"
 %token _prototype_ "prototype"
 %token _public_ "public"
+%token ___restrict_ "__restrict"
+%token _restrict_ "restrict"
 %token _set_ "set"
 %token _short_ "short"
 %token _static_ "static"
@@ -474,11 +478,11 @@ type; })
 %type <argument_> ArgumentListOpt
 %type <argument_> Arguments
 %type <target_> ArrayComprehension
+%type <element_> ArrayElement
 %type <literal_> ArrayLiteral
 %type <expression_> ArrowFunction
 %type <functionParameter_> ArrowParameters
 %type <expression_> AssignmentExpression
-%type <expression_> AssignmentExpressionOpt
 %type <identifier_> BindingIdentifier
 %type <identifier_> BindingIdentifierOpt
 %type <bindings_> BindingList_
@@ -517,6 +521,7 @@ type; })
 %type <statement_> Declaration_
 %type <statement_> Declaration
 %type <clause_> DefaultClause
+%type <element_> ElementList_
 %type <element_> ElementList
 %type <element_> ElementListOpt
 %type <statement_> ElseStatementOpt
@@ -651,19 +656,24 @@ type; })
 %type <expression_> YieldExpression
 
 @begin C
-%type <specifier_> IntegerType
-%type <specifier_> IntegerTypeOpt
+%type <integral_> IntegerType
+%type <integral_> IntegerTypeOpt
 %type <typedIdentifier_> PrefixedType
 %type <specifier_> PrimitiveType
 %type <structField_> StructFieldListOpt
 %type <typedIdentifier_> SuffixedType
 %type <typedIdentifier_> SuffixedTypeOpt
 %type <typedIdentifier_> TypeSignifier
+%type <typedIdentifier_> TypeSignifierNone
 %type <typedIdentifier_> TypeSignifierOpt
+%type <modifier_> ParameterTail
 %type <modifier_> TypeQualifierLeft
 %type <modifier_> TypeQualifierLeftOpt
 %type <typedIdentifier_> TypeQualifierRight
 %type <typedIdentifier_> TypeQualifierRightOpt
+%type <typedIdentifier_> TypedIdentifierDefinition
+%type <typedIdentifier_> TypedIdentifierEncoding
+%type <typedIdentifier_> TypedIdentifierField
 %type <typedIdentifier_> TypedIdentifierMaybe
 %type <typedIdentifier_> TypedIdentifierNo
 %type <typedIdentifier_> TypedIdentifierYes
@@ -685,6 +695,9 @@ type; })
 %type <protocol_> ClassProtocolsOpt
 %type <implementationField_> ImplementationFieldListOpt
 %type <statement_> ImplementationStatement
+%type <keyValue_> KeyValuePairList_
+%type <keyValue_> KeyValuePairList
+%type <keyValue_> KeyValuePairListOpt
 %type <target_> MessageExpression
 %type <messageParameter_> MessageParameter
 %type <messageParameter_> MessageParameters
@@ -983,12 +996,13 @@ IdentifierNoOf
     | "char" { $$ = CYNew CYIdentifier("char"); }
     | "int" { $$ = CYNew CYIdentifier("int"); }
     | "long" { $$ = CYNew CYIdentifier("long"); }
+    | "__restrict" { $$ = CYNew CYIdentifier("__restrict"); }
+    | "restrict" { $$ = CYNew CYIdentifier("restrict"); }
     | "short" { $$ = CYNew CYIdentifier("short"); }
     | "static" { $$ = CYNew CYIdentifier("static"); }
     | "volatile" { $$ = CYNew CYIdentifier("volatile"); }
 @begin C
     | "signed" { $$ = CYNew CYIdentifier("signed"); }
-    | "struct" { $$ = CYNew CYIdentifier("struct"); }
     | "unsigned" { $$ = CYNew CYIdentifier("unsigned"); }
 @end
 @begin ObjectiveC
@@ -1041,10 +1055,19 @@ ArrayLiteral
     : "[" ElementListOpt[elements] "]" { $$ = CYNew CYArray($elements); }
     ;
 
-ElementList
-    : AssignmentExpressionOpt[value] "," ElementListOpt[next] { $$ = CYNew CYElementValue($value, $next); }
+ArrayElement
+    : AssignmentExpression[value] { $$ = CYNew CYElementValue($value); }
     | LexOf "..." AssignmentExpression[values] { $$ = CYNew CYElementSpread($values); }
-    | AssignmentExpression[value] { $$ = CYNew CYElementValue($value, NULL); }
+    ;
+
+ElementList_
+    : "," ElementListOpt[elements] { $$ = $elements; } 
+    | { $$ = NULL; }
+    ;
+
+ElementList
+    : ArrayElement[element] ElementList_[next] { $$ = $element; $$->SetNext($next); }
+    | LexOf "," ElementListOpt[next] { $$ = CYNew CYElementValue(NULL, $next); }
     ;
 
 ElementListOpt
@@ -1333,11 +1356,6 @@ AssignmentExpression
     | ArrowFunction[pass] { $$ = $pass; }
     | LexOf LeftHandSideAssignment[assignment] AssignmentExpression[rhs] { $assignment->SetRight($rhs); $$ = $assignment; }
     ;
-
-AssignmentExpressionOpt
-    : AssignmentExpression[pass] { $$ = $pass; }
-    | LexOf { $$ = NULL; }
-    ;
 /* }}} */
 /* 12.15 Comma Operator ( , ) {{{ */
 Expression
@@ -1979,16 +1997,43 @@ TypeSignifier
     | "(" "*" TypeQualifierRightOpt[typed] ")" { $$ = $typed; $$->modifier_ = CYNew CYTypePointerTo($$->modifier_); }
     ;
 
+TypeSignifierNone
+    : { $$ = CYNew CYTypedIdentifier(@$); }
+    ;
+
 TypeSignifierOpt
     : TypeSignifier[pass] { $$ = $pass; }
-    | { $$ = CYNew CYTypedIdentifier(@$); }
+    | TypeSignifierNone[pass] { $$ = $pass; }
+    ;
+
+Restrict
+    : "__restrict"
+    | "restrict"
+    ;
+
+RestrictOpt
+    : Restrict
+    |
+    ;
+
+ParameterModifier
+    : "throw" "(" ")"
+    ;
+
+ParameterModifierOpt
+    : ParameterModifier
+    |
+    ;
+
+ParameterTail
+    : TypedParameterListOpt[parameters] ")" ParameterModifierOpt { $$ = CYNew CYTypeFunctionWith($parameters); }
     ;
 
 SuffixedType
-    : SuffixedTypeOpt[typed] "[" NumericLiteral[size] "]" { $$ = $typed; $$->modifier_ = CYNew CYTypeArrayOf($size, $$->modifier_); }
+    : SuffixedTypeOpt[typed] "[" RestrictOpt NumericLiteral[size] "]" { $$ = $typed; $$->modifier_ = CYNew CYTypeArrayOf($size, $$->modifier_); }
     | "(" "^" TypeQualifierRightOpt[typed] ")" "(" TypedParameterListOpt[parameters] ")" { $$ = $typed; $$->modifier_ = CYNew CYTypeBlockWith($parameters, $$->modifier_); }
-    | TypeSignifier[typed] "(" TypedParameterListOpt[parameters] ")" { $$ = $typed; $$->modifier_ = CYNew CYTypeFunctionWith($parameters, $$->modifier_); }
-    | "("[parenthesis] TypedParameterListOpt[parameters] ")" { $$ = CYNew CYTypedIdentifier(@parenthesis); $$->modifier_ = CYNew CYTypeFunctionWith($parameters, $$->modifier_); }
+    | TypeSignifier[typed] "(" ParameterTail[modifier] { $$ = $typed; CYSetLast($modifier) = $$->modifier_; $$->modifier_ = $modifier; }
+    | "("[parenthesis] ParameterTail[modifier] { $$ = CYNew CYTypedIdentifier(@parenthesis); CYSetLast($modifier) = $$->modifier_; $$->modifier_ = $modifier; }
     ;
 
 SuffixedTypeOpt
@@ -2015,6 +2060,7 @@ TypeQualifierRight
     | PrefixedType[pass] { $$ = $pass; }
     | "const" TypeQualifierRightOpt[typed] { $$ = $typed; $$->modifier_ = CYNew CYTypeConstant($$->modifier_); }
     | "volatile" TypeQualifierRightOpt[typed] { $$ = $typed; $$->modifier_ = CYNew CYTypeVolatile($$->modifier_); }
+    | Restrict TypeQualifierRightOpt[typed] { $$ = $typed; }
     ;
 
 TypeQualifierRightOpt
@@ -2023,36 +2069,36 @@ TypeQualifierRightOpt
     ;
 
 IntegerType
-    : "int" { $$ = CYNew CYTypeVariable("int"); }
-    | "unsigned" IntegerTypeOpt[specifier] { $$ = CYNew CYTypeUnsigned($specifier); }
-    | "signed" IntegerTypeOpt[specifier] { $$ = CYNew CYTypeSigned($specifier); }
-    | "long" IntegerTypeOpt[specifier] { $$ = CYNew CYTypeLong($specifier); }
-    | "short" IntegerTypeOpt[specifier] { $$ = CYNew CYTypeShort($specifier); }
+    : "int" { $$ = CYNew CYTypeIntegral(CYTypeNeutral); }
+    | "unsigned" IntegerTypeOpt[integral] { $$ = $integral->Unsigned(); if ($$ == NULL) CYERR(@1, "incompatible unsigned"); }
+    | "signed" IntegerTypeOpt[integral] { $$ = $integral->Signed(); if ($$ == NULL) CYERR(@1, "incompatible signed"); }
+    | "long" IntegerTypeOpt[integral] { $$ = $integral->Long(); if ($$ == NULL) CYERR(@1, "incompatible long"); }
+    | "short" IntegerTypeOpt[integral] { $$ = $integral->Short(); if ($$ == NULL) CYERR(@1, "incompatible short"); }
     ;
 
 IntegerTypeOpt
     : IntegerType[pass] { $$ = $pass; }
-    | { $$ = CYNew CYTypeVariable("int"); }
+    | { $$ = CYNew CYTypeIntegral(CYTypeNeutral); }
     ;
 
 StructFieldListOpt
-    : TypedIdentifierMaybe[typed] ";" StructFieldListOpt[next] { $$ = CYNew CYTypeStructField($typed, $next); }
+    : TypedIdentifierField[typed] ";" StructFieldListOpt[next] { $$ = CYNew CYTypeStructField($typed, $next); }
     | { $$ = NULL; }
     ;
 
 PrimitiveType
     : IdentifierType[name] { $$ = CYNew CYTypeVariable($name); }
     | IntegerType[pass] { $$ = $pass; }
-    | "char" { $$ = CYNew CYTypeVariable("char"); }
-    | "signed" "char" { $$ = CYNew CYTypeSigned(CYNew CYTypeVariable("char")); }
-    | "unsigned" "char" { $$ = CYNew CYTypeUnsigned(CYNew CYTypeVariable("char")); }
-    | "struct" IdentifierTypeOpt[name] "{" StructFieldListOpt[fields] "}" { $$ = CYNew CYTypeStruct($name, $fields); }
+    | "char" { $$ = CYNew CYTypeCharacter(CYTypeNeutral); }
+    | "signed" "char" { $$ = CYNew CYTypeCharacter(CYTypeSigned); }
+    | "unsigned" "char" { $$ = CYNew CYTypeCharacter(CYTypeUnsigned); }
+    | "struct" IdentifierType[name] { $$ = CYNew CYTypeReference($name); }
     ;
 
 TypedIdentifierMaybe
-    : TypeQualifierLeftOpt[modifier] PrimitiveType[specifier] TypeQualifierRightOpt[typed] { $$ = $typed; $$->specifier_ = $specifier; CYSetLast($modifier) = $$->modifier_; $$->modifier_ = $modifier; }
-    | TypeQualifierLeft[modifier] "void" TypeQualifierRight[typed] { $$ = $typed; $$->specifier_ = CYNew CYTypeVoid(); CYSetLast($modifier) = $$->modifier_; $$->modifier_ = $modifier; }
+    : TypeQualifierLeft[modifier] "void" TypeQualifierRight[typed] { $$ = $typed; $$->specifier_ = CYNew CYTypeVoid(); CYSetLast($modifier) = $$->modifier_; $$->modifier_ = $modifier; }
     | "void" TypeQualifierRight[typed] { $$ = $typed; $$->specifier_ = CYNew CYTypeVoid(); }
+    | TypeQualifierLeftOpt[modifier] PrimitiveType[specifier] TypeQualifierRightOpt[typed] { $$ = $typed; $$->specifier_ = $specifier; CYSetLast($modifier) = $$->modifier_; $$->modifier_ = $modifier; }
     ;
 
 TypedIdentifierYes
@@ -2063,8 +2109,23 @@ TypedIdentifierNo
     : TypedIdentifierMaybe[typed] { if ($typed->identifier_ != NULL) CYERR($typed->location_, "unexpected identifier"); $$ = $typed; }
     ;
 
+TypedIdentifierField
+    : TypedIdentifierYes[pass] { $$ = $pass; }
+    | TypeQualifierLeftOpt[modifier] "struct" "{" StructFieldListOpt[fields] "}" TypeQualifierRightOpt[typed] { if ($typed->identifier_ == NULL) CYERR($typed->location_, "expected identifier"); $$ = $typed; $$->specifier_ = CYNew CYTypeStruct(NULL, CYNew CYStructTail($fields)); CYSetLast($modifier) = $$->modifier_; $$->modifier_ = $modifier; }
+    ;
+
+TypedIdentifierEncoding
+    : TypedIdentifierNo[pass] { $$ = $pass; }
+    | TypeQualifierLeftOpt[modifier] "struct" "{" StructFieldListOpt[fields] "}" TypeQualifierRightOpt[typed] { if ($typed->identifier_ != NULL) CYERR($typed->location_, "unexpected identifier"); $$ = $typed; $$->specifier_ = CYNew CYTypeStruct(NULL, CYNew CYStructTail($fields)); CYSetLast($modifier) = $$->modifier_; $$->modifier_ = $modifier; }
+    ;
+
+TypedIdentifierDefinition
+    : TypedIdentifierYes[pass] { $$ = $pass; }
+    | TypeQualifierLeftOpt[modifier] "struct" IdentifierTypeOpt[name] "{" StructFieldListOpt[fields] "}" TypeQualifierRightOpt[typed] { if ($typed->identifier_ == NULL) CYERR($typed->location_, "expected identifier"); $$ = $typed; $$->specifier_ = CYNew CYTypeStruct($name, CYNew CYStructTail($fields)); CYSetLast($modifier) = $$->modifier_; $$->modifier_ = $modifier; }
+    ;
+
 PrimaryExpression
-    : "@encode" "(" TypedIdentifierMaybe[typed] ")" { $$ = CYNew CYEncodedType($typed); }
+    : "@encode" "(" TypedIdentifierEncoding[typed] ")" { $$ = CYNew CYEncodedType($typed); }
     ;
 /* }}} */
 @end
@@ -2078,7 +2139,7 @@ ClassSuperOpt
     ;
 
 ImplementationFieldListOpt
-    : TypedIdentifierMaybe[typed] ";" ImplementationFieldListOpt[next] { $$ = CYNew CYImplementationField($typed, $next); }
+    : TypedIdentifierField[typed] ";" ImplementationFieldListOpt[next] { $$ = CYNew CYImplementationField($typed, $next); }
     | { $$ = NULL; }
     ;
 
@@ -2220,15 +2281,29 @@ BoxableExpression
     | BooleanLiteral[pass] { $$ = $pass; }
     | NumericLiteral[pass] { $$ = $pass; }
     | StringLiteral[pass] { $$ = $pass; }
-    | ArrayLiteral[pass] { $$ = $pass; }
-    | ObjectLiteral[pass] { $$ = $pass; }
     | CoverParenthesizedExpressionAndArrowParameterList[pass] { $$ = $pass; }
     | "YES" { $$ = CYNew CYTrue(); }
     | "NO" { $$ = CYNew CYFalse(); }
     ;
 
+KeyValuePairList_
+    : "," KeyValuePairListOpt[next] { $$ = $next; }
+    | { $$ = NULL; }
+
+KeyValuePairList
+    : AssignmentExpression[key] ":" AssignmentExpression[value] KeyValuePairList_[next] { $$ = CYNew CYObjCKeyValue($key, $value, $next); }
+    ;
+
+KeyValuePairListOpt
+    : KeyValuePairList[pass] { $$ = $pass; }
+    | LexOf { $$ = NULL; }
+    ;
+
 PrimaryExpression
     : "@" BoxableExpression[expression] { $$ = CYNew CYBox($expression); }
+    | "@" "[" ElementListOpt[elements] "]" { $$ = CYNew CYObjCArray($elements); }
+    | "@" "{" KeyValuePairListOpt[pairs] "}" { $$ = CYNew CYObjCDictionary($pairs); }
+
     | "@YES" { $$ = CYNew CYBox(CYNew CYTrue()); }
     | "@NO" { $$ = CYNew CYBox(CYNew CYFalse()); }
     | "@true" { $$ = CYNew CYBox(CYNew CYTrue()); }
@@ -2285,7 +2360,20 @@ TypedParameterListOpt
     ;
 
 PrimaryExpression
-    : "[" LexOf "&" "]" "(" TypedParameterListOpt[parameters] ")" "->" TypedIdentifierMaybe[type] "{" FunctionBody[code] "}" { $$ = CYNew CYLambda($type, $parameters, $code); }
+    : "[" LexOf "&" "]" "(" TypedParameterListOpt[parameters] ")" "->" TypedIdentifierNo[type] "{" FunctionBody[code] "}" { $$ = CYNew CYLambda($type, $parameters, $code); }
+    ;
+/* }}} */
+/* Cycript (C): Structure Definitions {{{ */
+IdentifierNoOf
+    : "struct" NewLineOpt { $$ = CYNew CYIdentifier("struct"); }
+    ;
+
+Statement__
+    : "struct" NewLineNot IdentifierType[name] "{" StructFieldListOpt[fields] "}" { $$ = CYNew CYStructDefinition($name, CYNew CYStructTail($fields)); }
+    ;
+
+PrimaryExpression
+    : "(" LexOf "struct" NewLineOpt IdentifierType[name] TypeQualifierRightOpt[typed] ")" { $typed->specifier_ = CYNew CYTypeReference($name); $$ = CYNew CYTypeExpression($typed); }
     ;
 /* }}} */
 /* Cycript (C): Type Definitions {{{ */
@@ -2294,7 +2382,7 @@ IdentifierNoOf
     ;
 
 TypeDefinition
-    : "typedef" NewLineNot TypedIdentifierYes[typed] TerminatorHard { $$ = CYNew CYTypeDefinition($typed); }
+    : "typedef" NewLineNot TypedIdentifierDefinition[typed] TerminatorHard { $$ = CYNew CYTypeDefinition($typed); }
     ;
 
 Statement__
@@ -2302,7 +2390,7 @@ Statement__
     ;
 
 PrimaryExpression
-    : "(" LexOf "typedef" NewLineOpt TypedIdentifierNo[typed] ")" { $$ = CYNew CYTypeExpression($typed); }
+    : "(" LexOf "typedef" NewLineOpt TypedIdentifierEncoding[typed] ")" { $$ = CYNew CYTypeExpression($typed); }
     ;
 /* }}} */
 /* Cycript (C): extern "C" {{{ */
@@ -2311,7 +2399,7 @@ IdentifierNoOf
     ;
 
 ExternCStatement
-    : TypedIdentifierYes[typed] TerminatorHard { $$ = CYNew CYExternal(CYNew CYString("C"), $typed); }
+    : TypedIdentifierField[typed] TerminatorHard { $$ = CYNew CYExternal(CYNew CYString("C"), $typed); }
     | TypeDefinition[pass] { $$ = $pass; }
     ;
 
@@ -2329,7 +2417,6 @@ Statement__
     : "extern" NewLineNot StringLiteral[abi] { if (strcmp($abi->Value(), "C") != 0) CYERR(@abi, "unknown extern binding"); } ExternC[pass] { $$ = $pass; }
     ;
 /* }}} */
-
 @end
 
 @begin E4X