]> git.saurik.com Git - cycript.git/commitdiff
Add struct definitions and namespace struct names.
authorJay Freeman (saurik) <saurik@saurik.com>
Tue, 22 Dec 2015 06:48:05 +0000 (22:48 -0800)
committerJay Freeman (saurik) <saurik@saurik.com>
Tue, 22 Dec 2015 06:48:05 +0000 (22:48 -0800)
Decode.cpp
Output.cpp
Parser.ypp.in
Replace.cpp
Syntax.hpp

index e7ea5f9e3acdc834abea915d54d287948de83440..bcf77132ce27976aebdaaa3fa1348827a00b91f2 100644 (file)
@@ -97,7 +97,7 @@ CYTypedIdentifier *Decode_(CYPool &pool, struct sig::Type *type) {
                 fields = $ CYTypeStructField(typed, fields);
             }
             CYIdentifier *name(type->name == NULL ? NULL : $I(type->name));
-            return $ CYTypedIdentifier($ CYTypeStruct(name, fields));
+            return $ CYTypedIdentifier($ CYTypeStruct(name, $ CYStructTail(fields)));
         } break;
     }
 
index 5a2d759493776e306a814852ae0b9404c0f87c38..6096143fdf4cad408ff7e87f130130b24bfda1c4 100644 (file)
@@ -864,6 +864,22 @@ const char *CYString::Word() const {
     return value;
 }
 
+void CYStructDefinition::Output(CYOutput &out, CYFlags flags) const {
+    out << "struct" << ' ' << *name_ << *tail_;
+}
+
+void CYStructTail::Output(CYOutput &out) const {
+    out << ' ' << '{' << '\n';
+    ++out.indent_;
+    CYForEach (field, fields_) {
+        out << '\t' << *field->typed_;
+        out.Terminate();
+        out << '\n';
+    }
+    --out.indent_;
+    out << '}';
+}
+
 void CYSuperAccess::Output(CYOutput &out, CYFlags flags) const {
     out << "super";
     if (const char *word = property_->Word())
@@ -927,24 +943,21 @@ void CYTypeSigned::Output(CYOutput &out) const {
 }
 
 void CYTypeStruct::Output(CYOutput &out) const {
-    out << "struct" << ' ';
+    out << "struct";
     if (name_ != NULL)
-        out << *name_ << ' ';
-    out << '{' << '\n';
-    ++out.indent_;
-    CYForEach (field, fields_) {
-        out << '\t' << *field->typed_;
-        out.Terminate();
-        out << '\n';
-    }
-    --out.indent_;
-    out << '}';
+        out << ' ' << *name_;
+    else
+        out << *tail_;
 }
 
 void CYTypeUnsigned::Output(CYOutput &out) const {
     out << "unsigned" << specifier_;
 }
 
+void CYTypeReference::Output(CYOutput &out) const {
+    out << "struct" << ' ' << *name_;
+}
+
 void CYTypeVariable::Output(CYOutput &out) const {
     out << *name_;
 }
index 3d5aa6d4a31802054043032cdfd85891280e1080..50ee7445701740586b34f581210dd9d6786b4f0c 100644 (file)
@@ -659,11 +659,15 @@ type; })
 %type <typedIdentifier_> SuffixedType
 %type <typedIdentifier_> SuffixedTypeOpt
 %type <typedIdentifier_> TypeSignifier
+%type <typedIdentifier_> TypeSignifierNone
 %type <typedIdentifier_> TypeSignifierOpt
 %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
@@ -988,7 +992,6 @@ IdentifierNoOf
     | "volatile" { $$ = CYNew CYIdentifier("volatile"); }
 @begin C
     | "signed" { $$ = CYNew CYIdentifier("signed"); }
-    | "struct" { $$ = CYNew CYIdentifier("struct"); }
     | "unsigned" { $$ = CYNew CYIdentifier("unsigned"); }
 @end
 @begin ObjectiveC
@@ -1979,9 +1982,13 @@ TypeSignifier
     | "(" "*" TypeQualifierRightOpt[typed] ")" { $$ = $typed; $$->modifier_ = CYNew CYTypePointerTo($$->modifier_); }
     ;
 
+TypeSignifierNone
+    : { $$ = CYNew CYTypedIdentifier(@$); }
+    ;
+
 TypeSignifierOpt
     : TypeSignifier[pass] { $$ = $pass; }
-    | { $$ = CYNew CYTypedIdentifier(@$); }
+    | TypeSignifierNone[pass] { $$ = $pass; }
     ;
 
 SuffixedType
@@ -2036,7 +2043,7 @@ IntegerTypeOpt
     ;
 
 StructFieldListOpt
-    : TypedIdentifierMaybe[typed] ";" StructFieldListOpt[next] { $$ = CYNew CYTypeStructField($typed, $next); }
+    : TypedIdentifierField[typed] ";" StructFieldListOpt[next] { $$ = CYNew CYTypeStructField($typed, $next); }
     | { $$ = NULL; }
     ;
 
@@ -2046,13 +2053,13 @@ PrimitiveType
     | "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); }
+    | "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 +2070,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 +2100,7 @@ ClassSuperOpt
     ;
 
 ImplementationFieldListOpt
-    : TypedIdentifierMaybe[typed] ";" ImplementationFieldListOpt[next] { $$ = CYNew CYImplementationField($typed, $next); }
+    : TypedIdentifierField[typed] ";" ImplementationFieldListOpt[next] { $$ = CYNew CYImplementationField($typed, $next); }
     | { $$ = NULL; }
     ;
 
@@ -2285,7 +2307,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 +2329,7 @@ IdentifierNoOf
     ;
 
 TypeDefinition
-    : "typedef" NewLineNot TypedIdentifierYes[typed] TerminatorHard { $$ = CYNew CYTypeDefinition($typed); }
+    : "typedef" NewLineNot TypedIdentifierDefinition[typed] TerminatorHard { $$ = CYNew CYTypeDefinition($typed); }
     ;
 
 Statement__
@@ -2302,7 +2337,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 +2346,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 +2364,6 @@ Statement__
     : "extern" NewLineNot StringLiteral[abi] { if (strcmp($abi->Value(), "C") != 0) CYERR(@abi, "unknown extern binding"); } ExternC[pass] { $$ = $pass; }
     ;
 /* }}} */
-
 @end
 
 @begin E4X
index 7f5ca53a3ab142b63a836c99a839d7283bc9b3fc..1ae2ef0afccb4c63341a900be7a5b0f9cfdeabde 100644 (file)
@@ -1090,6 +1090,32 @@ CYString *CYString::String(CYContext &context) {
     return this;
 }
 
+CYStatement *CYStructDefinition::Replace(CYContext &context) {
+    CYTarget *target(tail_->Replace(context));
+    if (name_ != NULL)
+        target = $C1($M(target, $S("withName")), $S(name_->Word()));
+    return $ CYLexical(false, $B1($B($I($pool.strcat(name_->Word(), "$cy", NULL)), target)));
+}
+
+CYTarget *CYStructTail::Replace(CYContext &context) {
+    CYList<CYElementValue> types;
+    CYList<CYElementValue> names;
+
+    CYForEach (field, fields_) {
+        CYTypedIdentifier *typed(field->typed_);
+        types->*$ CYElementValue(typed->Replace(context));
+
+        CYExpression *name;
+        if (typed->identifier_ == NULL)
+            name = NULL;
+        else
+            name = $S(typed->identifier_->Word());
+        names->*$ CYElementValue(name);
+    }
+
+    return $N2($V("Type"), $ CYArray(types), $ CYArray(names));
+}
+
 CYTarget *CYSuperAccess::Replace(CYContext &context) {
     return $C1($M($M($M($V(context.super_), $S("prototype")), property_), $S("bind")), $ CYThis());
 }
@@ -1200,6 +1226,10 @@ CYTarget *CYTypePointerTo::Replace_(CYContext &context, CYTarget *type) {
     return next_->Replace(context, $ CYCall($ CYDirectMember(type, $ CYString("pointerTo"))));
 }
 
+CYTarget *CYTypeReference::Replace(CYContext &context) {
+    return $V($pool.strcat(name_->Word(), "$cy", NULL));
+}
+
 CYTarget *CYTypeShort::Replace(CYContext &context) {
     return $ CYCall($ CYDirectMember(specifier_->Replace(context), $ CYString("short")));
 }
@@ -1209,22 +1239,7 @@ CYTarget *CYTypeSigned::Replace(CYContext &context) {
 }
 
 CYTarget *CYTypeStruct::Replace(CYContext &context) {
-    CYList<CYElementValue> types;
-    CYList<CYElementValue> names;
-
-    CYForEach (field, fields_) {
-        CYTypedIdentifier *typed(field->typed_);
-        types->*$ CYElementValue(typed->Replace(context));
-
-        CYExpression *name;
-        if (typed->identifier_ == NULL)
-            name = NULL;
-        else
-            name = $S(typed->identifier_->Word());
-        names->*$ CYElementValue(name);
-    }
-
-    CYTarget *target($N2($V("Type"), $ CYArray(types), $ CYArray(names)));
+    CYTarget *target(tail_->Replace(context));
     if (name_ != NULL)
         target = $C1($M(target, $S("withName")), $S(name_->Word()));
     return target;
index bc1608474bb2c10d0e1b0239730135a3b4cad76f..f34c4120e8c7b8f8c3f4f4940bca8b29d69bb2e6 100644 (file)
@@ -1961,6 +1961,20 @@ struct CYTypeVoid :
     virtual void Output(CYOutput &out) const;
 };
 
+struct CYTypeReference :
+    CYTypeSpecifier
+{
+    CYIdentifier *name_;
+
+    CYTypeReference(CYIdentifier *name) :
+        name_(name)
+    {
+    }
+
+    virtual CYTarget *Replace(CYContext &context);
+    virtual void Output(CYOutput &out) const;
+};
+
 struct CYTypeVariable :
     CYTypeSpecifier
 {
@@ -2369,15 +2383,29 @@ struct CYTypeStructField :
     }
 };
 
+struct CYStructTail :
+    CYThing
+{
+    CYTypeStructField *fields_;
+
+    CYStructTail(CYTypeStructField *fields) :
+        fields_(fields)
+    {
+    }
+
+    CYTarget *Replace(CYContext &context);
+    virtual void Output(CYOutput &out) const;
+};
+
 struct CYTypeStruct :
     CYTypeSpecifier
 {
     CYIdentifier *name_;
-    CYTypeStructField *fields_;
+    CYStructTail *tail_;
 
-    CYTypeStruct(CYIdentifier *name, CYTypeStructField *fields) :
+    CYTypeStruct(CYIdentifier *name, CYStructTail *tail) :
         name_(name),
-        fields_(fields)
+        tail_(tail)
     {
     }
 
@@ -2385,6 +2413,24 @@ struct CYTypeStruct :
     virtual void Output(CYOutput &out) const;
 };
 
+struct CYStructDefinition :
+    CYStatement
+{
+    CYIdentifier *name_;
+    CYStructTail *tail_;
+
+    CYStructDefinition(CYIdentifier *name, CYStructTail *tail) :
+        name_(name),
+        tail_(tail)
+    {
+    }
+
+    CYCompact(None)
+
+    virtual CYStatement *Replace(CYContext &context);
+    virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
 namespace cy {
 namespace Syntax {