]> git.saurik.com Git - cycript.git/blobdiff - Parser.ypp.in
Do not use corrupt struct to store type reference.
[cycript.git] / Parser.ypp.in
index 5239ff127735be7b3bef4c3ed8f799087d50dae2..c3f23797946eeb9b37675bdb9af5b437b2a7112d 100644 (file)
@@ -55,6 +55,7 @@
 %union { CYClassTail *classTail_; }
 %union { CYComprehension *comprehension_; }
 %union { CYElement *element_; }
+%union { CYEnumConstant *constant_; }
 %union { CYExpression *expression_; }
 %union { CYFalse *false_; }
 %union { CYVariable *variable_; }
@@ -73,6 +74,7 @@
 %union { CYParenthetical *parenthetical_; }
 %union { CYProperty *property_; }
 %union { CYPropertyName *propertyName_; }
+%union { CYTypeSigning signing_; }
 %union { CYSpan *span_; }
 %union { CYStatement *statement_; }
 %union { CYString *string_; }
@@ -226,6 +228,9 @@ type; })
         case CYMarkModule:
             driver.hold_ = yytranslate_(token::MarkModule);
             break;
+        case CYMarkExpression:
+            driver.hold_ = yytranslate_(token::MarkExpression);
+            break;
     }
 };
 
@@ -266,7 +271,6 @@ type; })
 
 @begin E4X ObjectiveC
 %token At "@"
-%token Pound "#"
 @end
 
 %token Ampersand "&"
@@ -316,6 +320,7 @@ type; })
 %token Comma ","
 %token Question "?"
 %token SemiColon ";"
+%token Pound "#"
 %token NewLine "\n"
 %token __ ""
 
@@ -424,6 +429,7 @@ type; })
 %token _goto_ "goto"
 %token _implements_ "implements"
 %token _int_ "int"
+%token ___int128_ "__int128"
 %token _interface_ "interface"
 %token _let_ "let"
 %token _let__ "!let"
@@ -667,9 +673,13 @@ type; })
 %type <expression_> YieldExpression
 
 @begin C
+%type <constant_> EnumConstantListOpt_
+%type <constant_> EnumConstantListOpt
+%type <number_> IntegerNumber
 %type <integral_> IntegerType
 %type <integral_> IntegerTypeOpt
 %type <typedIdentifier_> PrefixedType
+%type <specifier_> PrimitiveReference
 %type <specifier_> PrimitiveType
 %type <structField_> StructFieldListOpt
 %type <typedIdentifier_> SuffixedType
@@ -677,6 +687,7 @@ type; })
 %type <typedIdentifier_> TypeSignifier
 %type <typedIdentifier_> TypeSignifierNone
 %type <typedIdentifier_> TypeSignifierOpt
+%type <signing_> TypeSigning
 %type <modifier_> ParameterTail
 %type <modifier_> TypeQualifierLeft
 %type <modifier_> TypeQualifierLeftOpt
@@ -687,6 +698,7 @@ type; })
 %type <typedIdentifier_> TypedIdentifierField
 %type <typedIdentifier_> TypedIdentifierMaybe
 %type <typedIdentifier_> TypedIdentifierNo
+%type <typedIdentifier_> TypedIdentifierTagged
 %type <typedIdentifier_> TypedIdentifierYes
 %type <typedFormal_> TypedParameterList_
 %type <typedFormal_> TypedParameterList
@@ -759,12 +771,14 @@ type; })
 %start Program
 %token MarkModule
 %token MarkScript
+%token MarkExpression
 
 %%
 
 Program
     : MarkScript Script
     | MarkModule Module
+    | MarkExpression Expression[expression] { driver.context_ = $expression; }
     ;
 
 /* Lexer State {{{ */
@@ -1014,6 +1028,7 @@ IdentifierNoOf
     : IdentifierTypeNoOf
     | "char" { $$ = CYNew CYIdentifier("char"); }
     | "int" { $$ = CYNew CYIdentifier("int"); }
+    | "__int128" { $$ = CYNew CYIdentifier("__int128"); }
     | "long" { $$ = CYNew CYIdentifier("long"); }
     | "__restrict" { $$ = CYNew CYIdentifier("__restrict"); }
     | "restrict" { $$ = CYNew CYIdentifier("restrict"); }
@@ -2105,19 +2120,46 @@ StructFieldListOpt
     | { $$ = NULL; }
     ;
 
+IntegerNumber
+    : NumericLiteral[pass] { $$ = $pass; }
+    | "-" NumericLiteral[positive] { $$ = $positive; $$->value_ = -$$->value_; }
+    ;
+
+EnumConstantListOpt_
+    : "," EnumConstantListOpt[pass] { $$ = $pass; }
+    | { $$ = NULL; }
+    ;
+
+EnumConstantListOpt
+    : IdentifierType[name] "=" IntegerNumber[value] EnumConstantListOpt_[next] { $$ = CYNew CYEnumConstant($name, $value, $next); }
+    | { $$ = NULL; }
+    ;
+
+TypeSigning
+    : { $$ = CYTypeNeutral; }
+    | "signed" { $$ = CYTypeSigned; }
+    | "unsigned" { $$ = CYTypeUnsigned; }
+    ;
+
 PrimitiveType
     : IdentifierType[name] { $$ = CYNew CYTypeVariable($name); }
     | IntegerType[pass] { $$ = $pass; }
-    | "char" { $$ = CYNew CYTypeCharacter(CYTypeNeutral); }
-    | "signed" "char" { $$ = CYNew CYTypeCharacter(CYTypeSigned); }
-    | "unsigned" "char" { $$ = CYNew CYTypeCharacter(CYTypeUnsigned); }
-    | "struct" IdentifierType[name] { $$ = CYNew CYTypeReference($name); }
+    | TypeSigning[signing] "char" { $$ = CYNew CYTypeCharacter($signing); }
+    | TypeSigning[signing] "__int128" { $$ = CYNew CYTypeInt128($signing); }
+    ;
+
+PrimitiveReference
+    : PrimitiveType[pass] { $$ = $pass; }
+    | "struct" IdentifierType[name] { $$ = CYNew CYTypeReference(CYTypeReferenceStruct, $name); }
+    | "enum" IdentifierType[name] { $$ = CYNew CYTypeReference(CYTypeReferenceEnum, $name); }
+    | "struct" AutoComplete { driver.mode_ = CYDriver::AutoStruct; YYACCEPT; }
+    | "enum" AutoComplete { driver.mode_ = CYDriver::AutoEnum; YYACCEPT; }
     ;
 
 TypedIdentifierMaybe
     : 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; }
+    | TypeQualifierLeftOpt[modifier] PrimitiveReference[specifier] TypeQualifierRightOpt[typed] { $$ = $typed; $$->specifier_ = $specifier; CYSetLast($modifier) = $$->modifier_; $$->modifier_ = $modifier; }
     ;
 
 TypedIdentifierYes
@@ -2128,19 +2170,26 @@ TypedIdentifierNo
     : TypedIdentifierMaybe[typed] { if ($typed->identifier_ != NULL) CYERR($typed->location_, "unexpected identifier"); $$ = $typed; }
     ;
 
+TypedIdentifierTagged
+    : TypeQualifierLeftOpt[modifier] "struct" "{" StructFieldListOpt[fields] "}" TypeQualifierRightOpt[typed] { $$ = $typed; $$->specifier_ = CYNew CYTypeStruct(NULL, CYNew CYStructTail($fields)); CYSetLast($modifier) = $$->modifier_; $$->modifier_ = $modifier; }
+    | TypeQualifierLeftOpt[modifier] "enum" ":" PrimitiveType[specifier] "{" EnumConstantListOpt[constants] "}" TypeQualifierRightOpt[typed] { $$ = $typed; $$->specifier_ = CYNew CYTypeEnum(NULL, $specifier, $constants); CYSetLast($modifier) = $$->modifier_; $$->modifier_ = $modifier; }
+    ;
+
 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; }
+    | TypedIdentifierTagged[typed] { if ($typed->identifier_ == NULL) CYERR($typed->location_, "expected identifier"); $$ = $typed; }
     ;
 
 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; }
+    | TypedIdentifierTagged[typed] { if ($typed->identifier_ != NULL) CYERR($typed->location_, "unexpected identifier"); $$ = $typed; }
+    | "void" TypeSignifierNone[typed] { $$ = $typed; $$->specifier_ = CYNew CYTypeVoid(); }
     ;
 
 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; }
+    | "void" TypeSignifier[typed] { $$ = $typed; $$->specifier_ = CYNew CYTypeVoid(); }
     ;
 
 PrimaryExpression
@@ -2397,7 +2446,8 @@ Statement__
     ;
 
 PrimaryExpression
-    : "(" LexOf "struct" NewLineOpt IdentifierType[name] TypeQualifierRightOpt[typed] ")" { $typed->specifier_ = CYNew CYTypeReference($name); $$ = CYNew CYTypeExpression($typed); }
+    : "(" LexOf "struct" NewLineOpt IdentifierType[name] TypeQualifierRightOpt[typed] ")" { $typed->specifier_ = CYNew CYTypeReference(CYTypeReferenceStruct, $name); $$ = CYNew CYTypeExpression($typed); }
+    | "(" LexOf "struct" NewLineOpt AutoComplete { driver.mode_ = CYDriver::AutoStruct; YYACCEPT; }
     ;
 /* }}} */
 /* Cycript (C): Type Definitions {{{ */
@@ -2423,7 +2473,7 @@ IdentifierNoOf
     ;
 
 ExternCStatement
-    : TypedIdentifierField[typed] TerminatorHard { $$ = CYNew CYExternal(CYNew CYString("C"), $typed); }
+    : TypedIdentifierField[typed] TerminatorHard { $$ = CYNew CYExternalDefinition(CYNew CYString("C"), $typed); }
     | TypeDefinition[pass] { $$ = $pass; }
     ;
 
@@ -2437,8 +2487,16 @@ ExternC
     | ExternCStatement[pass] { $$ = $pass; }
     ;
 
+ABI
+    : StringLiteral[abi] { if (strcmp($abi->Value(), "C") != 0) CYERR(@abi, "unknown extern binding"); }
+    ;
+
 Statement__
-    : "extern" NewLineNot StringLiteral[abi] { if (strcmp($abi->Value(), "C") != 0) CYERR(@abi, "unknown extern binding"); } ExternC[pass] { $$ = $pass; }
+    : "extern" NewLineNot ABI[abi] ExternC[pass] { $$ = $pass; }
+    ;
+
+PrimaryExpression
+    : "(" LexOf "extern" NewLineOpt ABI[abi] TypedIdentifierField[typed] ")" { $$ = CYNew CYExternalExpression(CYNew CYString("C"), $typed); }
     ;
 /* }}} */
 @end