From: Jay Freeman (saurik) Date: Tue, 22 Dec 2015 06:48:05 +0000 (-0800) Subject: Add struct definitions and namespace struct names. X-Git-Tag: v0.9.590~158 X-Git-Url: https://git.saurik.com/cycript.git/commitdiff_plain/d83803733e0994c59ed12d7b6b4acf2ea55a5f10 Add struct definitions and namespace struct names. --- diff --git a/Decode.cpp b/Decode.cpp index e7ea5f9..bcf7713 100644 --- a/Decode.cpp +++ b/Decode.cpp @@ -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; } diff --git a/Output.cpp b/Output.cpp index 5a2d759..6096143 100644 --- a/Output.cpp +++ b/Output.cpp @@ -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_; } diff --git a/Parser.ypp.in b/Parser.ypp.in index 3d5aa6d..50ee744 100644 --- a/Parser.ypp.in +++ b/Parser.ypp.in @@ -659,11 +659,15 @@ type; }) %type SuffixedType %type SuffixedTypeOpt %type TypeSignifier +%type TypeSignifierNone %type TypeSignifierOpt %type TypeQualifierLeft %type TypeQualifierLeftOpt %type TypeQualifierRight %type TypeQualifierRightOpt +%type TypedIdentifierDefinition +%type TypedIdentifierEncoding +%type TypedIdentifierField %type TypedIdentifierMaybe %type TypedIdentifierNo %type 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 diff --git a/Replace.cpp b/Replace.cpp index 7f5ca53..1ae2ef0 100644 --- a/Replace.cpp +++ b/Replace.cpp @@ -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 types; + CYList 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 types; - CYList 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; diff --git a/Syntax.hpp b/Syntax.hpp index bc16084..f34c412 100644 --- a/Syntax.hpp +++ b/Syntax.hpp @@ -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 {