]> git.saurik.com Git - cycript.git/commitdiff
{Functor,Selector}.type should return @encode().
authorJay Freeman (saurik) <saurik@saurik.com>
Sun, 12 Jan 2014 04:59:09 +0000 (20:59 -0800)
committerJay Freeman (saurik) <saurik@saurik.com>
Sun, 12 Jan 2014 05:22:16 +0000 (21:22 -0800)
17 files changed:
Cycript.yy.in
Decode.cpp [new file with mode: 0644]
Decode.hpp [new file with mode: 0644]
Execute.cpp
JavaScript.hpp
Makefile.am
Makefile.in
ObjectiveC/Library.mm
ObjectiveC/Output.cpp
ObjectiveC/Replace.cpp
ObjectiveC/Syntax.hpp
Output.cpp
Parser.hpp
Replace.cpp
sig/copy.cpp
sig/parse.cpp
sig/types.hpp

index 94d804bea62ffddd5677b9ee721a66b0bd46b608..8593f2613080664cdffe89e398cc10e993a15a33 100644 (file)
@@ -91,7 +91,7 @@ typedef struct {
         CYMessageParameter *messageParameter_;
         CYProtocol *protocol_;
         CYSelectorPart *selector_;
-        CYTypeModifier *type_;
+        CYTypeModifier *modifier_;
         CYTypedIdentifier *typedIdentifier_;
         CYTypedParameter *typedParameter_;
 @end
@@ -482,16 +482,15 @@ int cylex(YYSTYPE *, cy::location *, void *);
 %type <protocol_> ClassProtocolListOpt
 %type <protocol_> ClassProtocols
 %type <protocol_> ClassProtocolsOpt
-%type <type_> ConcreteType
 %type <expression_> EncodedType
+%type <modifier_> FunctionedType
 %type <expression_> MessageExpression
 %type <messageParameter_> MessageParameter
 %type <messageParameter_> MessageParameters
 %type <messageParameter_> MessageParameterList
 %type <messageParameter_> MessageParameterListOpt
 %type <bool_> MessageScope
-%type <type_> ModifiedType_
-%type <type_> ModifiedType
+%type <typedIdentifier_> ModifiedType
 %type <typedIdentifier_> PrefixedType
 %type <expression_> PrimitiveType
 %type <argument_> SelectorCall_
@@ -504,8 +503,8 @@ int cylex(YYSTYPE *, cy::location *, void *);
 %type <typedIdentifier_> SuffixedType
 %type <expression_> TypeOpt
 %type <typedIdentifier_> TypeParenthetical
-%type <type_> TypeQualifierLeft
-%type <type_> TypeQualifierRight
+%type <modifier_> TypeQualifierLeft
+%type <typedIdentifier_> TypeQualifierRight
 %type <typedIdentifier_> TypeSignifier
 %type <typedIdentifier_> TypedIdentifier
 %type <typedParameter_> TypedParameterList_
@@ -1370,42 +1369,44 @@ ProgramBodyOpt
 @begin ObjectiveC
 /* Cycript (Objective-C): Type Encoding {{{ */
 TypeParenthetical
-    : "(" PrefixedType ")" { $$ = $2; }
+    : "(" LexPushInOff PrefixedType ")" LexPopIn { $$ = $3; }
     ;
 
 TypeSignifier
     : Identifier { $$ = CYNew CYTypedIdentifier($1); }
-    | TypeParenthetical
+    | TypeParenthetical { $$ = $1; }
     ;
 
 ArrayedType
-    : ArrayedType "[" NumericLiteral "]" { $$ = $1; CYSetLast($$->type_) = CYNew CYTypeArrayOf($3); }
+    : ArrayedType "[" NumericLiteral "]" { $$ = $1; $$->modifier_ = CYNew CYTypeArrayOf($3, $$->modifier_); }
     | TypeSignifier { $$ = $1; }
-    | { $$ = CYNew CYTypedIdentifier(NULL); }
+    | { $$ = CYNew CYTypedIdentifier(); }
+    ;
+
+FunctionedType
+    : "(" LexPushInOff TypedParameterListOpt ")" LexPopIn { $$ = CYNew CYTypeFunctionWith($3); }
     ;
 
 SuffixedType
     : ArrayedType { $$ = $1; }
-    | TypeParenthetical "(" LexPushInOff TypedParameterListOpt ")" LexPopIn { $$ = $1; CYSetLast($$->type_) = CYNew CYTypeFunctionWith($4); }
+    | TypeParenthetical FunctionedType { $$ = $1; CYSetLast($2) = $$->modifier_; $$->modifier_ = $2; }
+    | FunctionedType { $$ = CYNew CYTypedIdentifier(); CYSetLast($1) = $$->modifier_; $$->modifier_ = $1; }
     ;
 
 PrefixedType
-    : "*" TypeQualifierRight PrefixedType { $$ = $3; CYSetLast($$->type_) = $2; CYSetLast($$->type_) = CYNew CYTypePointerTo(); }
-    | SuffixedType { $$ = $1; }
+    : "*" TypeQualifierRight { $$ = $2; $$->modifier_ = CYNew CYTypePointerTo($$->modifier_); }
     ;
 
 TypeQualifierLeft
-    : "const" TypeQualifierLeft { $$ = CYNew CYTypeConstant(); CYSetLast($$) = $2; }
+    : "const" TypeQualifierLeft { $$ = $2; CYSetLast($$) = CYNew CYTypeConstant(); }
+    /* XXX: | "volatile" TypeQualifierLeft { $$ = $2; CYSetLast($$) = CYNew CYTypeVolatile(); } */
     | { $$ = NULL; }
     ;
 
 TypeQualifierRight
-    : TypeQualifierRight "const" { $$ = CYNew CYTypeConstant($1); }
-    | { $$ = NULL; }
-    ;
-
-ConcreteType
-    : TypeQualifierLeft PrimitiveType TypeQualifierRight { $$ = $3; CYSetLast($$) = $1; CYSetLast($$) = CYNew CYTypeVariable($2); }
+    : "const" TypeQualifierRight { $$ = $2; $$->modifier_ = CYNew CYTypeConstant($$->modifier_); }
+    | PrefixedType { $$ = $1; }
+    | SuffixedType { $$ = $1; }
     ;
 
 PrimitiveType
@@ -1414,20 +1415,11 @@ PrimitiveType
     ;
 
 TypedIdentifier
-    : ConcreteType PrefixedType { $$ = $2; CYSetLast($$->type_) = $1; }
+    : TypeQualifierLeft PrimitiveType TypeQualifierRight { $$ = $3; $$->type_ = $2; CYSetLast($1) = $$->modifier_; $$->modifier_ = $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; }
+    : TypedIdentifier { $$ = CYNew CYEncodedType($1); }
     ;
 
 PrimaryExpression
@@ -1622,6 +1614,11 @@ PrimaryExpression
     ;
 /* }}} */
 /* Cycript (Objective-C): Block Expressions {{{ */
+ModifiedType
+    : TypeQualifierLeft PrimitiveType { $$ = CYNew CYTypedIdentifier(); $$->type_ = $2; $$->modifier_ = $1; }
+    | ModifiedType "*" { $$ = $1; $$->modifier_ = CYNew CYTypePointerTo($$->modifier_); }
+    ;
+
 PrimaryExpression
     : "^" ModifiedType "(" LexPushInOff TypedParameterListOpt ")" LexPopIn BRACE LexPushInOff FunctionBody "}" LexPopIn { $$ = CYNew CYObjCBlock($2, $5, $10); }
     ;
@@ -1665,7 +1662,7 @@ TypedParameterListOpt
     ;
 
 PrimaryExpression
-    : "[" LexPushInOff LexSetRegExp "&" LexSetRegExp "]" LexPopIn "(" LexPushInOff TypedParameterListOpt ")" LexPopIn "->" TypedIdentifier BRACE LexPushInOff FunctionBody "}" LexPopIn { $$ = CYNew CYLambda($14->type_, $10, $17); }
+    : "[" LexPushInOff LexSetRegExp "&" LexSetRegExp "]" LexPopIn "(" LexPushInOff TypedParameterListOpt ")" LexPopIn "->" TypedIdentifier BRACE LexPushInOff FunctionBody "}" LexPopIn { $$ = CYNew CYLambda($14, $10, $17); }
     ;
 /* }}} */
 /* Cycript (C): Type Definitions {{{ */
diff --git a/Decode.cpp b/Decode.cpp
new file mode 100644 (file)
index 0000000..7901515
--- /dev/null
@@ -0,0 +1,95 @@
+/* Cycript - Optimizing JavaScript Compiler/Runtime
+ * Copyright (C) 2009-2013  Jay Freeman (saurik)
+*/
+
+/* GNU General Public License, Version 3 {{{ */
+/*
+ * Cycript is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation, either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * Cycript is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Cycript.  If not, see <http://www.gnu.org/licenses/>.
+**/
+/* }}} */
+
+#include <sstream>
+
+#include "Decode.hpp"
+#include "Replace.hpp"
+
+CYTypedIdentifier *Decode_(CYPool &pool, struct sig::Type *type) {
+    switch (type->primitive) {
+        case sig::function_P: {
+            _assert(type->data.signature.count != 0);
+            CYTypedParameter *parameter(NULL);
+            for (size_t i(type->data.signature.count - 1); i != 0; --i)
+                parameter = $ CYTypedParameter(Decode(pool, type->data.signature.elements[i].type), parameter);
+            return Decode(pool, type->data.signature.elements[0].type)->Modify($ CYTypeFunctionWith(parameter));
+        } break;
+
+        case sig::typename_P: return $ CYTypedIdentifier($V("Class"));
+        case sig::union_P: _assert(false); break;
+        case sig::string_P: return $ CYTypedIdentifier($V("char"), $ CYTypeConstant($ CYTypePointerTo()));
+        case sig::selector_P: return $ CYTypedIdentifier($V("SEL"));
+        case sig::block_P: _assert(false); break;
+
+        case sig::object_P: {
+            if (type->name == NULL)
+                return $ CYTypedIdentifier($V("id"));
+            else
+                return $ CYTypedIdentifier($V(type->name), $ CYTypePointerTo());
+        } break;
+
+        case sig::boolean_P: return $ CYTypedIdentifier($V("bool"));
+        case sig::uchar_P: return $ CYTypedIdentifier($V("uchar"));
+        case sig::uint_P: return $ CYTypedIdentifier($V("uint"));
+        case sig::ulong_P: return $ CYTypedIdentifier($V("ulong"));
+        case sig::ulonglong_P: return $ CYTypedIdentifier($V("ulonglong"));
+        case sig::ushort_P: return $ CYTypedIdentifier($V("ushort"));
+        case sig::array_P: return Decode(pool, type->data.data.type)->Modify($ CYTypeArrayOf($D(type->data.data.size)));
+
+        // XXX: once again, the issue of void here is incorrect
+        case sig::pointer_P: {
+            CYTypedIdentifier *typed;
+            if (type->data.data.type == NULL)
+                typed = $ CYTypedIdentifier($V("void"));
+            else
+                typed = Decode(pool, type->data.data.type);
+            return typed->Modify($ CYTypePointerTo());
+        } break;
+
+        case sig::bit_P: _assert(false); break;
+        case sig::char_P: return $ CYTypedIdentifier($V("char"));
+        case sig::double_P: return $ CYTypedIdentifier($V("double"));
+        case sig::float_P: return $ CYTypedIdentifier($V("float"));
+        case sig::int_P: return $ CYTypedIdentifier($V("int"));
+        case sig::long_P: return $ CYTypedIdentifier($V("long"));
+        case sig::longlong_P: return $ CYTypedIdentifier($V("longlong"));
+        case sig::short_P: return $ CYTypedIdentifier($V("short"));
+
+        // XXX: this happens to work, but is totally wrong
+        case sig::void_P: return $ CYTypedIdentifier($V("void"));
+
+        case sig::struct_P: {
+            _assert(type->name != NULL);
+            return $ CYTypedIdentifier($V(type->name));
+        } break;
+    }
+
+    _assert(false);
+    return NULL;
+}
+
+CYTypedIdentifier *Decode(CYPool &pool, struct sig::Type *type) {
+    CYTypedIdentifier *typed(Decode_(pool, type));
+    if ((type->flags & JOC_TYPE_CONST) != 0)
+        typed = typed->Modify($ CYTypeConstant());
+    return typed;
+}
diff --git a/Decode.hpp b/Decode.hpp
new file mode 100644 (file)
index 0000000..5aff706
--- /dev/null
@@ -0,0 +1,31 @@
+/* Cycript - Optimizing JavaScript Compiler/Runtime
+ * Copyright (C) 2009-2013  Jay Freeman (saurik)
+*/
+
+/* GNU General Public License, Version 3 {{{ */
+/*
+ * Cycript is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation, either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * Cycript is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Cycript.  If not, see <http://www.gnu.org/licenses/>.
+**/
+/* }}} */
+
+#ifndef DECODE_HPP
+#define DECODE_HPP
+
+#include <sig/types.hpp>
+
+#include "Parser.hpp"
+
+CYTypedIdentifier *Decode(CYPool &pool, struct sig::Type *type);
+
+#endif//DECODE_HPP
index 7641df789d2e7b62eec9bdac6cc04a1d510c2458..4282965048dc39457253f8d35b627c6d9cd994fe 100644 (file)
@@ -46,6 +46,7 @@
 
 #include "Parser.hpp"
 
+#include "Decode.hpp"
 #include "Error.hpp"
 #include "JavaScript.hpp"
 #include "String.hpp"
@@ -958,8 +959,8 @@ static JSValueRef Functor_callAsFunction(JSContextRef context, JSObjectRef objec
     return CYCallFunction(pool, context, 0, NULL, count, arguments, false, &internal->signature_, &internal->cif_, internal->GetValue());
 } CYCatch(NULL) }
 
-JSObjectRef CYMakeType(JSContextRef context, const char *type) {
-    Type_privateData *internal(new Type_privateData(type));
+JSObjectRef CYMakeType(JSContextRef context, const char *encoding) {
+    Type_privateData *internal(new Type_privateData(encoding));
     return JSObjectMake(context, Type_privateData::Class_, internal);
 }
 
@@ -968,6 +969,19 @@ JSObjectRef CYMakeType(JSContextRef context, sig::Type *type) {
     return JSObjectMake(context, Type_privateData::Class_, internal);
 }
 
+JSObjectRef CYMakeType(JSContextRef context, sig::Signature *signature) {
+    CYPool pool;
+
+    sig::Type type;
+    type.name = NULL;
+    type.flags = 0;
+
+    type.primitive = sig::function_P;
+    sig::Copy(pool, type.data.signature, *signature);
+
+    return CYMakeType(context, &type);
+}
+
 static JSValueRef All_getProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry {
     JSObjectRef global(CYGetGlobalObject(context));
     JSObjectRef cycript(CYCastJSObject(context, CYGetProperty(context, global, CYJSString("Cycript"))));
@@ -1086,6 +1100,38 @@ static JSValueRef Type_callAsFunction_constant(JSContextRef context, JSObjectRef
     return CYMakeType(context, &type);
 } CYCatch(NULL) }
 
+static JSValueRef Type_callAsFunction_functionWith(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
+    Type_privateData *internal(reinterpret_cast<Type_privateData *>(JSObjectGetPrivate(_this)));
+
+    CYPool pool;
+
+    sig::Type type;
+    type.name = NULL;
+    type.flags = 0;
+
+    type.primitive = sig::function_P;
+    type.data.signature.elements = new(pool) sig::Element[1 + count];
+    type.data.signature.count = 1 + count;
+
+    type.data.signature.elements[0].name = NULL;
+    type.data.signature.elements[0].type = internal->type_;
+    type.data.signature.elements[0].offset = _not(size_t);
+
+    for (size_t i(0); i != count; ++i) {
+        sig::Element &element(type.data.signature.elements[i + 1]);
+        element.name = NULL;
+        element.offset = _not(size_t);
+
+        JSObjectRef object(CYCastJSObject(context, arguments[i]));
+        _assert(JSValueIsObjectOfClass(context, object, Type_privateData::Class_));
+        Type_privateData *internal(reinterpret_cast<Type_privateData *>(JSObjectGetPrivate(object)));
+
+        element.type = internal->type_;
+    }
+
+    return CYMakeType(context, &type);
+} CYCatch(NULL) }
+
 static JSValueRef Type_callAsFunction_pointerTo(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
     if (count != 0)
         throw CYJSError(context, "incorrect number of arguments to Type.pointerTo");
@@ -1187,8 +1233,7 @@ static JSValueRef Pointer_callAsFunction_toCYON(JSContextRef context, JSObjectRe
 
 static JSValueRef Functor_getProperty_type(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry {
     cy::Functor *internal(reinterpret_cast<cy::Functor *>(JSObjectGetPrivate(object)));
-    CYPool pool;
-    return CYCastJSValue(context, Unparse(pool, &internal->signature_));
+    return CYMakeType(context, &internal->signature_);
 } CYCatch(NULL) }
 
 static JSValueRef Type_getProperty_alignment(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry {
@@ -1215,12 +1260,12 @@ static JSValueRef Type_callAsFunction_toString(JSContextRef context, JSObjectRef
 
 static JSValueRef Type_callAsFunction_toCYON(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
     Type_privateData *internal(reinterpret_cast<Type_privateData *>(JSObjectGetPrivate(_this)));
-    CYPool pool;
-    const char *type(sig::Unparse(pool, internal->type_));
-    std::ostringstream str;
-    CYStringify(str, type, strlen(type));
-    char *cyon(pool.strcat("new Type(", str.str().c_str(), ")", NULL));
-    return CYCastJSValue(context, CYJSString(cyon));
+    CYLocalPool pool;
+    std::ostringstream out;
+    CYOptions options;
+    CYOutput output(out, options);
+    (new(pool) CYEncodedType(Decode(pool, internal->type_)))->Output(output, CYNoFlags);
+    return CYCastJSValue(context, CYJSString(out.str().c_str()));
 } CYCatch(NULL) }
 
 static JSValueRef Type_callAsFunction_toJSON(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
@@ -1262,9 +1307,10 @@ static JSStaticValue Type_staticValues[4] = {
     {NULL, NULL, NULL, 0}
 };
 
-static JSStaticFunction Type_staticFunctions[8] = {
+static JSStaticFunction Type_staticFunctions[9] = {
     {"arrayOf", &Type_callAsFunction_arrayOf, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
     {"constant", &Type_callAsFunction_constant, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
+    {"functionWith", &Type_callAsFunction_functionWith, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
     {"pointerTo", &Type_callAsFunction_pointerTo, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
     {"withName", &Type_callAsFunction_withName, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
     {"toCYON", &Type_callAsFunction_toCYON, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
index 1ede3642d65e7b3b09446944a9b479567c74833f..70887c49b42bd683dc4c332a6594afef113231e5 100644 (file)
@@ -125,6 +125,10 @@ extern struct CYHooks *hooks_;
 
 JSObjectRef CYMakePointer(JSContextRef context, void *pointer, size_t length, sig::Type *type, ffi_type *ffi, JSObjectRef owner);
 
+JSObjectRef CYMakeType(JSContextRef context, const char *encoding);
+JSObjectRef CYMakeType(JSContextRef context, sig::Type *type);
+JSObjectRef CYMakeType(JSContextRef context, sig::Signature *signature);
+
 void CYFinalize(JSObjectRef object);
 
 size_t CYArrayLength(JSContextRef context, JSObjectRef array);
index d92adb509e02c2d526017a5c4d17052eb7da9386..757ca29e145b178cfd1f499e08a4da2d686e1398 100644 (file)
@@ -43,7 +43,7 @@ lib_LTLIBRARIES += libcycript.la
 libcycript_la_LDFLAGS = $(CY_LDFLAGS)
 libcycript_la_LIBADD = $(LTLIBFFI) $(LTLIBGCC) -ldl
 
-libcycript_la_SOURCES = ConvertUTF.c Driver.cpp Highlight.cpp Library.cpp Network.cpp Output.cpp Parser.cpp Replace.cpp
+libcycript_la_SOURCES = ConvertUTF.c Decode.cpp Driver.cpp Highlight.cpp Library.cpp Network.cpp Output.cpp Parser.cpp Replace.cpp
 libcycript_la_SOURCES += Cycript.tab.cc lex.cy.cpp
 
 filters = $(CY_FILTERS)
index fe3ef22b0b20b21626481b40b3e4c99a506a5844..f9df08bcb50df79517f4fcbefd186e2eba7c9d02 100644 (file)
@@ -184,12 +184,12 @@ am__DEPENDENCIES_1 =
 libcycript_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
        $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
        $(am__DEPENDENCIES_3)
-am__libcycript_la_SOURCES_DIST = ConvertUTF.c Driver.cpp Highlight.cpp \
-       Library.cpp Network.cpp Output.cpp Parser.cpp Replace.cpp \
-       Cycript.tab.cc lex.cy.cpp sig/ffi_type.cpp sig/parse.cpp \
-       sig/copy.cpp Bridge.cpp Execute.cpp JavaScriptCore.cpp \
-       ObjectiveC/Output.cpp ObjectiveC/Replace.cpp \
-       ObjectiveC/Library.mm Handler.mm
+am__libcycript_la_SOURCES_DIST = ConvertUTF.c Decode.cpp Driver.cpp \
+       Highlight.cpp Library.cpp Network.cpp Output.cpp Parser.cpp \
+       Replace.cpp Cycript.tab.cc lex.cy.cpp sig/ffi_type.cpp \
+       sig/parse.cpp sig/copy.cpp Bridge.cpp Execute.cpp \
+       JavaScriptCore.cpp ObjectiveC/Output.cpp \
+       ObjectiveC/Replace.cpp ObjectiveC/Library.mm Handler.mm
 am__dirstamp = $(am__leading_dot)dirstamp
 @CY_EXECUTE_TRUE@am__objects_1 = sig/ffi_type.lo sig/parse.lo \
 @CY_EXECUTE_TRUE@      sig/copy.lo Bridge.lo Execute.lo \
@@ -198,10 +198,10 @@ am__dirstamp = $(am__leading_dot)dirstamp
 @CY_OBJECTIVEC_TRUE@   ObjectiveC/Replace.lo \
 @CY_OBJECTIVEC_TRUE@   ObjectiveC/Library.lo
 @CY_MACH_TRUE@am__objects_3 = Handler.lo
-am_libcycript_la_OBJECTS = ConvertUTF.lo Driver.lo Highlight.lo \
-       Library.lo Network.lo Output.lo Parser.lo Replace.lo \
-       Cycript.tab.lo lex.cy.lo $(am__objects_1) $(am__objects_2) \
-       $(am__objects_3)
+am_libcycript_la_OBJECTS = ConvertUTF.lo Decode.lo Driver.lo \
+       Highlight.lo Library.lo Network.lo Output.lo Parser.lo \
+       Replace.lo Cycript.tab.lo lex.cy.lo $(am__objects_1) \
+       $(am__objects_2) $(am__objects_3)
 libcycript_la_OBJECTS = $(am_libcycript_la_OBJECTS)
 libcycript_la_LINK = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(OBJCXXLD) $(AM_OBJCXXFLAGS) \
@@ -549,10 +549,10 @@ lib_LTLIBRARIES = $(am__append_1) libcycript.la
 libcycript_la_LDFLAGS = $(CY_LDFLAGS)
 libcycript_la_LIBADD = $(LTLIBFFI) $(LTLIBGCC) -ldl $(am__append_3) \
        $(am__append_9)
-libcycript_la_SOURCES = ConvertUTF.c Driver.cpp Highlight.cpp \
-       Library.cpp Network.cpp Output.cpp Parser.cpp Replace.cpp \
-       Cycript.tab.cc lex.cy.cpp $(am__append_2) $(am__append_8) \
-       $(am__append_10)
+libcycript_la_SOURCES = ConvertUTF.c Decode.cpp Driver.cpp \
+       Highlight.cpp Library.cpp Network.cpp Output.cpp Parser.cpp \
+       Replace.cpp Cycript.tab.cc lex.cy.cpp $(am__append_2) \
+       $(am__append_8) $(am__append_10)
 filters = $(CY_FILTERS) $(am__append_5) $(am__append_7)
 @CY_CONSOLE_TRUE@cycript_SOURCES = Console.cpp Display.cpp \
 @CY_CONSOLE_TRUE@      $(am__append_11)
@@ -752,6 +752,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Console.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ConvertUTF.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Cycript.tab.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Decode.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Display.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Driver.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Execute.Plo@am__quote@
index 7b0785ad6b4de079eef39b38282f06db85f8d2f8..bb62fc4a70997f41794b7e1616512c97818be226 100644 (file)
@@ -2647,10 +2647,13 @@ static JSValueRef Selector_callAsFunction_type(JSContextRef context, JSObjectRef
     else
         method = NULL;
 
-    if (const char *type = CYPoolTypeEncoding(pool, context, sel, method))
-        return CYCastJSValue(context, CYJSString(type));
+    const char *encoding(CYPoolTypeEncoding(pool, context, sel, method));
+    if (encoding == NULL)
+        return CYJSNull(context);
 
-    return CYJSNull(context);
+    sig::Signature signature;
+    sig::Parse(pool, &signature, encoding, &Structor_);
+    return CYMakeType(context, &signature);
 } CYCatch(NULL) }
 
 static JSStaticValue Selector_staticValues[2] = {
index 658a8f51ebc2f2c74faad66460353c2280023584..fd2a8d81747e824285e8d60b4903c76d0584dadf 100644 (file)
@@ -74,12 +74,6 @@ void CYClassStatement::Output(CYOutput &out, CYFlags flags) const {
     CYClass::Output(out, flags);
 }
 
-void CYEncodedType::Output(CYOutput &out, CYFlags flags) const {
-    out << "@encode(";
-    // XXX: this is seriously wrong
-    out << ")";
-}
-
 void CYField::Output(CYOutput &out) const {
 }
 
index 7c47eea4d76a1e3cdf114074cdaae7c9027cfc2b..e7d687f7c70cbaf15b30f8b586998e3ae8f3ffed 100644 (file)
@@ -78,10 +78,6 @@ CYStatement *CYClassStatement::Replace(CYContext &context) {
     return $E(Replace_(context));
 }
 
-CYExpression *CYEncodedType::Replace(CYContext &context) {
-    return type_->Replace(context);
-}
-
 CYStatement *CYField::Replace(CYContext &context) const { $T(NULL)
     CYVariable *cyn($V("$cyn"));
     CYVariable *cyt($V("$cyt"));
@@ -151,7 +147,7 @@ CYExpression *CYBox::Replace(CYContext &context) {
 }
 
 CYExpression *CYObjCBlock::Replace(CYContext &context) {
-    return $N2($V("Functor"), $ CYFunctionExpression(NULL, $ CYFunctionParameter($ CYDeclaration($ CYIdentifier("$cyt")), parameters_->Parameters(context)), statements_), parameters_->TypeSignature(context, $ CYAdd(type_->Replace(context), $ CYString("@"))));
+    return $N2($V("Functor"), $ CYFunctionExpression(NULL, $ CYFunctionParameter($ CYDeclaration($ CYIdentifier("$cyt")), parameters_->Parameters(context)), statements_), parameters_->TypeSignature(context, $ CYAdd(typed_->Replace(context), $ CYString("@"))));
 }
 
 CYStatement *CYProtocol::Replace(CYContext &context) const { $T(NULL)
index 343cb37e903886be871bfdfcf90f39283b5b4ff2..618a25e87659e9bf7e574eb228449e9b2ac99b13 100644 (file)
 struct CYObjCBlock :
     CYExpression
 {
-    CYTypeModifier *type_;
+    CYTypedIdentifier *typed_;
     CYTypedParameter *parameters_;
     CYStatement *statements_;
 
-    CYObjCBlock(CYTypeModifier *type, CYTypedParameter *parameters, CYStatement *statements) :
-        type_(type),
+    CYObjCBlock(CYTypedIdentifier *typed, CYTypedParameter *parameters, CYStatement *statements) :
+        typed_(typed),
         parameters_(parameters),
         statements_(statements)
     {
@@ -44,22 +44,6 @@ struct CYObjCBlock :
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
 
-struct CYEncodedType :
-    CYExpression
-{
-    CYTypeModifier *type_;
-
-    CYEncodedType(CYTypeModifier *type) :
-        type_(type)
-    {
-    }
-
-    CYPrecedence(1)
-
-    virtual CYExpression *Replace(CYContext &context);
-    virtual void Output(CYOutput &out, CYFlags flags) const;
-};
-
 struct CYBox :
     CYExpression
 {
index 3bf157f0e0df4ab8b605488abccca1118d05447d..17f7bde19345cf9d50cbb11e20488ecf6ee330e4 100644 (file)
@@ -329,7 +329,7 @@ void CYExpression::Output(CYOutput &out) const {
     Output(out, CYNoFlags);
 }
 
-void CYExpression::Output(CYOutput &out, unsigned precedence, CYFlags flags) const {
+void CYExpression::Output(CYOutput &out, int precedence, CYFlags flags) const {
     if (precedence < Precedence() || (flags & CYNoRightHand) != 0 && RightHand())
         out << '(' << *this << ')';
     else
@@ -474,9 +474,61 @@ void CYLabel::Output(CYOutput &out, CYFlags flags) const {
     statement_->Single(out, CYRight(flags));
 }
 
+void CYTypeArrayOf::Output(CYOutput &out, CYIdentifier *identifier) const {
+    next_->Output(out, Precedence(), identifier);
+    out << '[';
+    out << size_;
+    out << ']';
+}
+
+void CYTypeConstant::Output(CYOutput &out, CYIdentifier *identifier) const {
+    out << "const";
+    next_->Output(out, Precedence(), identifier);
+}
+
+void CYTypeFunctionWith::Output(CYOutput &out, CYIdentifier *identifier) const {
+    next_->Output(out, Precedence(), identifier);
+    out << '(' << parameters_ << ')';
+}
+
+void CYTypePointerTo::Output(CYOutput &out, CYIdentifier *identifier) const {
+    out << '*';
+    next_->Output(out, Precedence(), identifier);
+}
+
+void CYTypeVolatile::Output(CYOutput &out, CYIdentifier *identifier) const {
+    out << "volatile";
+    next_->Output(out, Precedence(), identifier);
+}
+
+void CYTypeModifier::Output(CYOutput &out, int precedence, CYIdentifier *identifier) const {
+    if (this == NULL) {
+        out << identifier;
+        return;
+    }
+
+    bool protect(precedence > Precedence());
+
+    if (protect)
+        out << '(';
+    Output(out, identifier);
+    if (protect)
+        out << ')';
+}
+
 void CYTypedIdentifier::Output(CYOutput &out) const {
-    // XXX: this is clearly wrong
-    out << "XXX";
+    type_->Output(out, 0, CYNoFlags);
+    modifier_->Output(out, 0, identifier_);
+}
+
+void CYEncodedType::Output(CYOutput &out, CYFlags flags) const {
+    out << "@encode(" << typed_ << ")";
+}
+
+void CYTypedParameter::Output(CYOutput &out) const {
+    out << typed_;
+    if (next_ != NULL)
+        out << ',' << ' ' << next_;
 }
 
 void CYLambda::Output(CYOutput &out, CYFlags flags) const {
index be97c0b49d09d91f1abdcd993adc2f4d76f114e7..e68cf1a57b7ea4b1eb84bb375cd095c3ba964232 100644 (file)
@@ -512,7 +512,7 @@ struct CYExpression :
     CYClassName,
     CYThing
 {
-    virtual unsigned Precedence() const = 0;
+    virtual int Precedence() const = 0;
 
     virtual bool RightHand() const {
         return true;
@@ -525,7 +525,7 @@ struct CYExpression :
 
     virtual void Output(CYOutput &out) const;
     virtual void Output(CYOutput &out, CYFlags flags) const = 0;
-    void Output(CYOutput &out, unsigned precedence, CYFlags flags) const;
+    void Output(CYOutput &out, int precedence, CYFlags flags) const;
 
     virtual CYExpression *ClassName(CYContext &context, bool object);
     virtual void ClassName(CYOutput &out, bool object) const;
@@ -556,8 +556,8 @@ struct CYExpression :
     }
 
 #define CYPrecedence(value) \
-    static const unsigned Precedence_ = value; \
-    virtual unsigned Precedence() const { \
+    static const int Precedence_ = value; \
+    virtual int Precedence() const { \
         return Precedence_; \
     }
 
@@ -1329,7 +1329,7 @@ struct New :
     {
     }
 
-    virtual unsigned Precedence() const {
+    virtual int Precedence() const {
         return arguments_ == NULL ? 2 : 1;
     }
 
@@ -1608,7 +1608,13 @@ struct CYTypeModifier :
     {
     }
 
-    virtual CYExpression *Replace(CYContext &context) = 0;
+    virtual int Precedence() const = 0;
+
+    virtual CYExpression *Replace_(CYContext &context, CYExpression *type) = 0;
+    CYExpression *Replace(CYContext &context, CYExpression *type);
+
+    virtual void Output(CYOutput &out, CYIdentifier *identifier) const = 0;
+    void Output(CYOutput &out, int precedence, CYIdentifier *identifier) const;
 };
 
 struct CYTypeArrayOf :
@@ -1622,9 +1628,10 @@ struct CYTypeArrayOf :
     {
     }
 
-    CYPrecedence(2)
+    CYPrecedence(1)
 
-    virtual CYExpression *Replace(CYContext &context);
+    virtual CYExpression *Replace_(CYContext &context, CYExpression *type);
+    virtual void Output(CYOutput &out, CYIdentifier *identifier) const;
 };
 
 struct CYTypeConstant :
@@ -1635,9 +1642,10 @@ struct CYTypeConstant :
     {
     }
 
-    CYPrecedence(3)
+    CYPrecedence(0)
 
-    virtual CYExpression *Replace(CYContext &context);
+    virtual CYExpression *Replace_(CYContext &context, CYExpression *type);
+    virtual void Output(CYOutput &out, CYIdentifier *identifier) const;
 };
 
 struct CYTypePointerTo :
@@ -1648,25 +1656,24 @@ struct CYTypePointerTo :
     {
     }
 
-    CYPrecedence(3)
+    CYPrecedence(0)
 
-    virtual CYExpression *Replace(CYContext &context);
+    virtual CYExpression *Replace_(CYContext &context, CYExpression *type);
+    virtual void Output(CYOutput &out, CYIdentifier *identifier) const;
 };
 
-struct CYTypeVariable :
+struct CYTypeVolatile :
     CYTypeModifier
 {
-    CYExpression *expression_;
-
-    CYTypeVariable(CYExpression *expression) :
-        CYTypeModifier(NULL),
-        expression_(expression)
+    CYTypeVolatile(CYTypeModifier *next = NULL) :
+        CYTypeModifier(next)
     {
     }
 
-    CYPrecedence(1)
+    CYPrecedence(0)
 
-    virtual CYExpression *Replace(CYContext &context);
+    virtual CYExpression *Replace_(CYContext &context, CYExpression *type);
+    virtual void Output(CYOutput &out, CYIdentifier *identifier) const;
 };
 
 struct CYTypedIdentifier :
@@ -1674,19 +1681,51 @@ struct CYTypedIdentifier :
     CYThing
 {
     CYIdentifier *identifier_;
-    CYTypeModifier *type_;
+    CYExpression *type_;
+    CYTypeModifier *modifier_;
 
-    CYTypedIdentifier(CYIdentifier *identifier) :
+    CYTypedIdentifier(CYIdentifier *identifier = NULL) :
         identifier_(identifier),
-        type_(NULL)
+        type_(NULL),
+        modifier_(NULL)
     {
     }
 
+    CYTypedIdentifier(CYExpression *type, CYTypeModifier *modifier = NULL) :
+        identifier_(NULL),
+        type_(type),
+        modifier_(modifier)
+    {
+    }
+
+    inline CYTypedIdentifier *Modify(CYTypeModifier *modifier) {
+        CYSetLast(modifier_) = modifier;
+        return this;
+    }
+
+    virtual CYExpression *Replace(CYContext &context);
     virtual void Output(CYOutput &out) const;
 };
 
+struct CYEncodedType :
+    CYExpression
+{
+    CYTypedIdentifier *typed_;
+
+    CYEncodedType(CYTypedIdentifier *typed) :
+        typed_(typed)
+    {
+    }
+
+    CYPrecedence(1)
+
+    virtual CYExpression *Replace(CYContext &context);
+    virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
 struct CYTypedParameter :
-    CYNext<CYTypedParameter>
+    CYNext<CYTypedParameter>,
+    CYThing
 {
     CYTypedIdentifier *typed_;
 
@@ -1699,17 +1738,19 @@ struct CYTypedParameter :
     CYArgument *Argument(CYContext &context);
     CYFunctionParameter *Parameters(CYContext &context);
     CYExpression *TypeSignature(CYContext &context, CYExpression *prefix);
+
+    virtual void Output(CYOutput &out) const;
 };
 
 struct CYLambda :
     CYExpression
 {
-    CYTypeModifier *type_;
+    CYTypedIdentifier *typed_;
     CYTypedParameter *parameters_;
     CYStatement *statements_;
 
-    CYLambda(CYTypeModifier *type, CYTypedParameter *parameters, CYStatement *statements) :
-        type_(type),
+    CYLambda(CYTypedIdentifier *typed, CYTypedParameter *parameters, CYStatement *statements) :
+        typed_(typed),
         parameters_(parameters),
         statements_(statements)
     {
@@ -1746,9 +1787,10 @@ struct CYTypeFunctionWith :
     {
     }
 
-    CYPrecedence(2)
+    CYPrecedence(1)
 
-    virtual CYExpression *Replace(CYContext &context);
+    virtual CYExpression *Replace_(CYContext &context, CYExpression *type);
+    virtual void Output(CYOutput &out, CYIdentifier *identifier) const;
 };
 
 namespace cy {
index f1283dec929178d10523a6b132a4ec3942c24c5f..3f02fa0a38a1b22b886a6375cb34b25f76a62a8e 100644 (file)
@@ -289,6 +289,10 @@ CYStatement *CYEmpty::Replace(CYContext &context) {
     return NULL;
 }
 
+CYExpression *CYEncodedType::Replace(CYContext &context) {
+    return typed_->Replace(context);
+}
+
 CYStatement *CYExpress::Replace(CYContext &context) {
     while (CYExpress *express = dynamic_cast<CYExpress *>(next_)) {
         CYCompound *compound(dynamic_cast<CYCompound *>(express->expression_));
@@ -522,7 +526,7 @@ CYStatement *CYLabel::Replace(CYContext &context) {
 }
 
 CYExpression *CYLambda::Replace(CYContext &context) {
-    return $N2($V("Functor"), $ CYFunctionExpression(NULL, parameters_->Parameters(context), statements_), parameters_->TypeSignature(context, type_->Replace(context)));
+    return $N2($V("Functor"), $ CYFunctionExpression(NULL, parameters_->Parameters(context), statements_), parameters_->TypeSignature(context, typed_->Replace(context)));
 }
 
 CYStatement *CYLetStatement::Replace(CYContext &context) {
@@ -865,32 +869,40 @@ CYStatement *Try::Replace(CYContext &context) {
 
 } }
 
-CYExpression *CYTypeArrayOf::Replace(CYContext &context) {
-    return $ CYCall($ CYDirectMember(next_->Replace(context), $ CYString("arrayOf")), $ CYArgument(size_));
+CYExpression *CYTypeArrayOf::Replace_(CYContext &context, CYExpression *type) {
+    return next_->Replace(context, $ CYCall($ CYDirectMember(type, $ CYString("arrayOf")), $ CYArgument(size_)));
 }
 
-CYExpression *CYTypeConstant::Replace(CYContext &context) {
-    return $ CYCall($ CYDirectMember(next_->Replace(context), $ CYString("constant")));
+CYExpression *CYTypeConstant::Replace_(CYContext &context, CYExpression *type) {
+    return next_->Replace(context, $ CYCall($ CYDirectMember(type, $ CYString("constant"))));
 }
 
 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 *CYTypeModifier::Replace(CYContext &context, CYExpression *type) { $T(type)
+    return Replace_(context, type);
+}
+
+CYExpression *CYTypeFunctionWith::Replace_(CYContext &context, CYExpression *type) {
+    return next_->Replace(context, $ CYCall($ CYDirectMember(type, $ CYString("functionWith")), parameters_->Argument(context)));
+}
+
+CYExpression *CYTypePointerTo::Replace_(CYContext &context, CYExpression *type) {
+    return next_->Replace(context, $ CYCall($ CYDirectMember(type, $ CYString("pointerTo"))));
 }
 
-CYExpression *CYTypePointerTo::Replace(CYContext &context) {
-    return $ CYCall($ CYDirectMember(next_->Replace(context), $ CYString("pointerTo")));
+CYExpression *CYTypeVolatile::Replace_(CYContext &context, CYExpression *type) {
+    return next_->Replace(context, $ CYCall($ CYDirectMember(type, $ CYString("volatile"))));
 }
 
-CYExpression *CYTypeVariable::Replace(CYContext &context) {
-    return expression_;
+CYExpression *CYTypedIdentifier::Replace(CYContext &context) {
+    return modifier_->Replace(context, type_);
 }
 
 CYArgument *CYTypedParameter::Argument(CYContext &context) { $T(NULL)
-    return $ CYArgument(typed_->type_->Replace(context), next_->Argument(context));
+    return $ CYArgument(typed_->Replace(context), next_->Argument(context));
 }
 
 CYFunctionParameter *CYTypedParameter::Parameters(CYContext &context) { $T(NULL)
index b38405e032f812fe27996ee3fa8eb0f7cbdd89e3..b85640c1e1555598787dff2fc4cca2864fae3735 100644 (file)
@@ -58,7 +58,7 @@ void Copy(CYPool &pool, Type &lhs, Type &rhs) {
     lhs.name = pool.strdup(rhs.name);
     lhs.flags = rhs.flags;
 
-    if (sig::IsAggregate(rhs.primitive))
+    if (rhs.primitive == '\0' || sig::IsAggregate(rhs.primitive))
         Copy(pool, lhs.data.signature, rhs.data.signature);
     else {
         sig::Type *&lht(lhs.data.data.type);
index 436e3cda9947d30a38cd9614374c3460a6697d0c..da590a8431226dff0076b264503681ddbf879cb1 100644 (file)
@@ -25,6 +25,7 @@
 #include <cstdio>
 #include <cstdlib>
 #include <cstring>
+#include <sstream>
 
 namespace sig {
 
@@ -247,6 +248,19 @@ const char *Unparse(CYPool &pool, struct Signature *signature) {
 
 const char *Unparse_(CYPool &pool, struct Type *type) {
     switch (type->primitive) {
+        case function_P: {
+            if (type->data.signature.count == 0)
+                return "?";
+            std::ostringstream out;
+            for (size_t i(0); i != type->data.signature.count; ++i) {
+                Element &element(type->data.signature.elements[i]);
+                out << Unparse(pool, element.type);
+                if (element.offset != _not(size_t))
+                    out << pool.itoa(element.offset);
+            }
+            return pool.strdup(out.str().c_str());
+        } break;
+
         case typename_P: return "#";
         case union_P: return pool.strcat("(", Unparse(pool, &type->data.signature), ")", NULL);
         case string_P: return "*";
@@ -265,7 +279,15 @@ const char *Unparse_(CYPool &pool, struct Type *type) {
             return pool.strcat("[", pool.itoa(type->data.data.size), value, "]", NULL);
         } break;
 
-        case pointer_P: return pool.strcat("^", type->data.data.type == NULL ? "v" : Unparse(pool, type->data.data.type), NULL);
+        case pointer_P: {
+            if (type->data.data.type == NULL)
+                return "^v";
+            else if (type->data.data.type->primitive == function_P)
+                return "^?";
+            else
+                return pool.strcat("^", Unparse(pool, type->data.data.type), NULL);
+        } break;
+
         case bit_P: return pool.strcat("b", pool.itoa(type->data.data.size), NULL);
         case char_P: return "c";
         case double_P: return "d";
index d2367af92be5e21c4db0e824ad6a61cb3b6611d2..e66e0c3e69aa4574bb49b72485eb19b7f701c9c6 100644 (file)
@@ -30,6 +30,7 @@
 namespace sig {
 
 enum Primitive {
+    function_P = '\0',
     typename_P = '#',
     union_P = '(',
     string_P = '*',