CYBoolean *boolean_;
CYClause *clause_;
CYCatch *catch_;
+ CYClassName *className_;
CYCompound *compound_;
CYDeclaration *declaration_;
CYDeclarations *declarations_;
CYLiteral *literal_;
CYMessage *message_;
CYMessageParameter *messageParameter_;
- CYName *name_;
CYNull *null_;
CYNumber *number_;
CYProperty *property_;
+ CYPropertyName *propertyName_;
CYSelectorPart *selector_;
CYSource *source_;
CYStatement *statement_;
%type <source_> ClassDeclaration
%type <message_> ClassMessageDeclaration
%type <message_> ClassMessageDeclarationListOpt
+%type <className_> ClassName
%type <expression_> ClassSuperOpt
%type <field_> ClassFieldList
%type <expression_> ConditionalExpression
%type <expression_> PrimaryExpression_
%type <expression_> PrimaryExpressionNoBF
%type <source_> Program
-%type <name_> PropertyName
+%type <propertyName_> PropertyName
%type <property_> PropertyNameAndValueList
%type <property_> PropertyNameAndValueList_
%type <property_> PropertyNameAndValueListOpt
| { $$ = NULL; }
;
+ClassName
+ : Identifier { $$ = $1; }
+ | "(" AssignmentExpression ")" { $$ = $2; }
+ ;
+
ClassDeclaration
: "@class" Identifier ClassSuperOpt ClassFieldList ClassMessageDeclarationListOpt "@end" { $$ = new CYClass($2, $3, $4, $5); }
+ | "@class" ClassName ClassMessageDeclarationListOpt "@end" { $$ = new CYCategory($2, $3); }
;
SourceElement
if (count > 1)
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"incorrect number of arguments to type cast function" userInfo:nil];
Type_privateData *internal(reinterpret_cast<Type_privateData *>(JSObjectGetPrivate(object)));
+ size_t size(count == 0 ? 0 : CYCastDouble(context, arguments[0]));
// XXX: alignment?
- void *value(malloc(internal->GetFFI()->size));
+ void *value(malloc(internal->GetFFI()->size * size));
return CYMakePointer(context, value, internal->type_, NULL);
} CYCatch
}
static JSValueRef Selector_callAsFunction_toCYON(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
CYTry {
- Selector_privateData *data(reinterpret_cast<Selector_privateData *>(JSObjectGetPrivate(_this)));
- const char *name(sel_getName(data->GetValue()));
+ Selector_privateData *internal(reinterpret_cast<Selector_privateData *>(JSObjectGetPrivate(_this)));
+ const char *name(sel_getName(internal->GetValue()));
CYPoolTry {
return CYCastJSValue(context, CYJSString([NSString stringWithFormat:@"@selector(%s)", name]));
} CYPoolCatch(NULL)
static JSValueRef Selector_callAsFunction_type(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
CYTry {
- if (count != 2)
+ if (count != 1)
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"incorrect number of arguments to Selector.type" userInfo:nil];
CYPool pool;
- Selector_privateData *data(reinterpret_cast<Selector_privateData *>(JSObjectGetPrivate(_this)));
+ Selector_privateData *internal(reinterpret_cast<Selector_privateData *>(JSObjectGetPrivate(_this)));
Class _class(CYCastNSObject(pool, context, arguments[0]));
- bool instance(CYCastBool(context, arguments[1]));
- SEL sel(data->GetValue());
- if (Method method = (*(instance ? &class_getInstanceMethod : class_getClassMethod))(_class, sel))
+ SEL sel(internal->GetValue());
+ if (Method method = class_getInstanceMethod(_class, sel))
return CYCastJSValue(context, method_getTypeEncoding(method));
else if (NSString *type = [[Bridge_ objectAtIndex:1] objectForKey:CYCastNSString(pool, sel_getName(sel))])
return CYCastJSValue(context, CYJSString(type));
} CYCatch
}
+static JSValueRef Type_callAsFunction_toString(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_));
+ CYPoolTry {
+ return CYCastJSValue(context, CYJSString(type));
+ } CYPoolCatch(NULL)
+ } CYCatch
+}
+
+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_));
+ CYPoolTry {
+ return CYCastJSValue(context, CYJSString([NSString stringWithFormat:@"new Type(%@)", [[NSString stringWithUTF8String:type] cy$toCYON]]));
+ } CYPoolCatch(NULL)
+ } CYCatch
+}
+
+static JSValueRef Type_callAsFunction_toJSON(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
+ return Type_callAsFunction_toString(context, object, _this, count, arguments, exception);
+}
+
static JSStaticValue CYValue_staticValues[2] = {
{"value", &CYValue_getProperty_value, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete},
{NULL, NULL, NULL, 0}
{NULL, NULL, 0}
};
+static JSStaticFunction Type_staticFunctions[5] = {
+ {"toCYON", &Type_callAsFunction_toCYON, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
+ {"toJSON", &Type_callAsFunction_toJSON, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
+ {"toString", &Type_callAsFunction_toString, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
+ {NULL, NULL, 0}
+};
+
CYDriver::CYDriver(const std::string &filename) :
state_(CYClear),
data_(NULL),
- (void) execute:(NSValue *)value {
CYExecute_ *execute(reinterpret_cast<CYExecute_ *>([value pointerValue]));
- NSLog(@"b:%p", execute->data_);
- NSLog(@"s:%s", execute->data_);
execute->data_ = CYExecute(execute->pool_, execute->data_);
- NSLog(@"a:%p", execute->data_);
}
@end
definition = kJSClassDefinitionEmpty;
definition.className = "Type";
+ definition.staticFunctions = Type_staticFunctions;
definition.callAsFunction = &Type_callAsFunction;
definition.callAsConstructor = &Type_callAsConstructor;
definition.finalize = &CYData::Finalize;
code_->Output(out, true);
}
+void CYCategory::Output(std::ostream &out) const {
+ out << "(function($cys,$cyp,$cyc,$cyn,$cyt){";
+ out << "$cyp=object_getClass($cys);";
+ out << "$cyc=$cys;";
+ if (messages_ != NULL)
+ messages_->Output(out, true);
+ out << "})(";
+ name_->ClassName(out);
+ out << ");";
+}
+
void CYClass::Output(std::ostream &out) const {
- out << "(function($cys,$cyc,$cym,$cyn,$cyt){";
+ out << "(function($cys,$cyp,$cyc,$cyn,$cyt,$cym){";
+ out << "$cyp=object_getClass($cys);";
out << "$cyc=objc_allocateClassPair($cys,\"" << *name_ << "\",0);";
out << "$cym=object_getClass($cyc);";
if (fields_ != NULL)
fields_->Output(out);
if (messages_ != NULL)
- messages_->Output(out);
+ messages_->Output(out, false);
out << "objc_registerClassPair($cyc);";
out << "})(";
if (super_ != NULL)
out << ");";
}
+void CYCompound::Output(std::ostream &out, CYFlags flags) const {
+ if (CYExpression *expression = expressions_)
+ if (CYExpression *next = expression->next_) {
+ expression->Output(out, CYLeft(flags));
+ CYFlags center(CYCenter(flags));
+ while (next != NULL) {
+ expression = next;
+ out << ',';
+ next = expression->next_;
+ CYFlags right(next != NULL ? center : CYRight(flags));
+ expression->Output(out, right);
+ }
+ } else
+ expression->Output(out, flags);
+}
+
void CYCondition::Output(std::ostream &out, CYFlags flags) const {
test_->Output(out, Precedence() - 1, CYLeft(flags));
out << '?';
out << ';';
}
+void CYExpression::ClassName(std::ostream &out) const {
+ Output(out, CYPA, CYNoFlags);
+}
+
void CYExpression::Part(std::ostream &out) const {
// XXX: this should handle LeftHandSideExpression
Output(out, CYNoIn);
}
-void CYCompound::Output(std::ostream &out, CYFlags flags) const {
- if (CYExpression *expression = expressions_)
- if (CYExpression *next = expression->next_) {
- expression->Output(out, CYLeft(flags));
- CYFlags center(CYCenter(flags));
- while (next != NULL) {
- expression = next;
- out << ',';
- next = expression->next_;
- CYFlags right(next != NULL ? center : CYRight(flags));
- expression->Output(out, right);
- }
- } else
- expression->Output(out, flags);
-}
-
void CYExpression::Output(std::ostream &out, unsigned precedence, CYFlags flags) const {
if (precedence < Precedence()) {
out << '(';
}
}
-void CYMessage::Output(std::ostream &out) const {
+void CYMessage::Output(std::ostream &out, bool replace) const {
if (next_ != NULL)
- next_->Output(out);
+ next_->Output(out, replace);
out << "$cyn=new Selector(\"";
for (CYMessageParameter *parameter(parameter_); parameter != NULL; parameter = parameter->next_)
if (parameter->tag_ != NULL) {
out << ':';
}
out << "\");";
- out << "$cyt=$cyn.type($cys," << (instance_ ? "true" : "false") << ");";
- out << "class_addMethod($cy" << (instance_ ? 'c' : 'm') << ",$cyn,";
+ out << "$cyt=$cyn.type($cy" << (instance_ ? 's' : 'p') << ");";
+ out << "class_" << (replace ? "replace" : "add") << "Method($cy" << (instance_ ? 'c' : 'm') << ",$cyn,";
out << "new Functor(function(self,_cmd";
for (CYMessageParameter *parameter(parameter_); parameter != NULL; parameter = parameter->next_)
if (parameter->name_ != NULL)
out << ' ';
}
+void CYNumber::PropertyName(std::ostream &out) const {
+ Output(out);
+}
+
void CYObject::Output(std::ostream &out, CYFlags flags) const {
bool protect((flags & CYNoBrace) != 0);
if (protect)
}
void CYProperty::Output(std::ostream &out) const {
- out << *name_;
+ name_->PropertyName(out);
out << ':';
value_->Output(out, CYPA, CYNoFlags);
if (next_ != NULL) {
out << (single ? '\'' : '"');
}
+void CYString::PropertyName(std::ostream &out) const {
+ if (const char *word = Word())
+ out << word;
+ else
+ Output(out);
+}
+
void CYSwitch::Output(std::ostream &out) const {
out << "switch(";
value_->Output(out, CYNoFlags);
code_->Output(out, false);
}
+void CYWord::ClassName(std::ostream &out) const {
+ out << "objc_getClass(\"" << Value() << "\")";
+}
+
void CYWord::Output(std::ostream &out) const {
out << Value();
}
+
+void CYWord::PropertyName(std::ostream &out) const {
+ Output(out);
+}
virtual void Output(std::ostream &out, bool block) const;
};
-struct CYName :
- CYThing
-{
- virtual const char *Name() const = 0;
+struct CYPropertyName {
+ virtual void PropertyName(std::ostream &out) const = 0;
+};
+
+struct CYClassName {
+ virtual void ClassName(std::ostream &out) const = 0;
};
struct CYWord :
- CYName
+ CYThing,
+ CYPropertyName,
+ CYClassName
{
const char *word_;
return word_;
}
- virtual const char *Name() const {
- return Value();
- }
-
virtual void Output(std::ostream &out) const;
+
+ virtual void ClassName(std::ostream &out) const;
+ virtual void PropertyName(std::ostream &out) const;
};
struct CYIdentifier :
struct CYExpression :
CYNext<CYExpression>,
CYForInitialiser,
- CYForInInitialiser
+ CYForInInitialiser,
+ CYClassName
{
virtual unsigned Precedence() const = 0;
virtual void Part(std::ostream &out) const;
virtual void Output(std::ostream &out, CYFlags flags) const = 0;
void Output(std::ostream &out, unsigned precedence, CYFlags flags) const;
+ virtual void ClassName(std::ostream &out) const;
+
virtual const char *Word() const {
return NULL;
}
struct CYString :
CYLiteral,
- CYName
+ CYPropertyName
{
const char *value_;
size_t size_;
return value_;
}
- virtual const char *Name() const {
- return Value();
- }
-
virtual const char *Word() const {
if (size_ == 0 || !WordStartRange_[value_[0]])
return NULL;
}
virtual void Output(std::ostream &out, CYFlags flags) const;
+ virtual void PropertyName(std::ostream &out) const;
};
struct CYNumber :
CYLiteral,
- CYName
+ CYPropertyName
{
double value_;
return value_;
}
- virtual const char *Name() const {
- throw;
- }
-
virtual void Output(std::ostream &out) const {
return Output(out, CYNoFlags);
}
virtual void Output(std::ostream &out, CYFlags flags) const;
+ virtual void PropertyName(std::ostream &out) const;
};
struct CYNull :
};
struct CYMessage :
- CYSource
+ CYNext<CYMessage>
{
bool instance_;
CYExpression *type_;
{
}
- virtual void Output(std::ostream &out) const;
+ virtual void Output(std::ostream &out, bool replace) const;
};
struct CYClass :
virtual void Output(std::ostream &out) const;
};
+struct CYCategory :
+ CYSource
+{
+ CYClassName *name_;
+ CYMessage *messages_;
+
+ CYCategory(CYClassName *name, CYMessage *messages) :
+ name_(name),
+ messages_(messages)
+ {
+ }
+
+ virtual void Output(std::ostream &out) const;
+};
+
struct CYFunctionParameter :
CYNext<CYFunctionParameter>,
CYThing
struct CYProperty :
CYNext<CYProperty>
{
- CYName *name_;
+ CYPropertyName *name_;
CYExpression *value_;
- CYProperty(CYName *name, CYExpression *value, CYProperty *next) :
+ CYProperty(CYPropertyName *name, CYExpression *value, CYProperty *next) :
CYNext<CYProperty>(next),
name_(name),
value_(value)