CYMessageParameter *messageParameter_;
CYProtocol *protocol_;
CYSelectorPart *selector_;
- CYTypeModifier *type_;
+ CYTypeModifier *modifier_;
CYTypedIdentifier *typedIdentifier_;
CYTypedParameter *typedParameter_;
@end
%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_
%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_
@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
;
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
;
/* }}} */
/* 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); }
;
;
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 {{{ */
--- /dev/null
+/* 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;
+}
--- /dev/null
+/* 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
#include "Parser.hpp"
+#include "Decode.hpp"
#include "Error.hpp"
#include "JavaScript.hpp"
#include "String.hpp"
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);
}
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"))));
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");
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 {
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) {
{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},
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);
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)
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 \
@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) \
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)
@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@
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] = {
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 {
}
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"));
}
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)
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)
{
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
{
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
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 {
CYClassName,
CYThing
{
- virtual unsigned Precedence() const = 0;
+ virtual int Precedence() const = 0;
virtual bool RightHand() const {
return true;
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;
}
#define CYPrecedence(value) \
- static const unsigned Precedence_ = value; \
- virtual unsigned Precedence() const { \
+ static const int Precedence_ = value; \
+ virtual int Precedence() const { \
return Precedence_; \
}
{
}
- virtual unsigned Precedence() const {
+ virtual int Precedence() const {
return arguments_ == NULL ? 2 : 1;
}
{
}
- 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 :
{
}
- 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 :
{
}
- 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 :
{
}
- 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 :
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_;
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)
{
{
}
- 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 {
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_));
}
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) {
} }
-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)
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);
#include <cstdio>
#include <cstdlib>
#include <cstring>
+#include <sstream>
namespace sig {
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 "*";
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";
namespace sig {
enum Primitive {
+ function_P = '\0',
typename_P = '#',
union_P = '(',
string_P = '*',