CYProgram *program_;
CYProperty *property_;
CYPropertyName *propertyName_;
+ CYProtocol *protocol_;
CYStatement *statement_;
CYString *string_;
CYThis *this_;
%type <message_> ClassMessageDeclarationListOpt
%type <className_> ClassName
%type <className_> ClassNameOpt
+%type <protocol_> ClassProtocolListOpt
+%type <protocol_> ClassProtocols
+%type <protocol_> ClassProtocolsOpt
%type <expression_> MessageExpression
%type <messageParameter_> MessageParameter
%type <messageParameter_> MessageParameters
| { $$ = NULL; }
;
+// XXX: this should be AssignmentExpressionNoRight
+ClassProtocols
+ : ShiftExpression ClassProtocolsOpt { $$ = new(driver.pool_) CYProtocol($1, $2); }
+ ;
+
+ClassProtocolsOpt
+ : "," ClassProtocols { $$ = $2; }
+ | { $$ = NULL; }
+ ;
+
+ClassProtocolListOpt
+ : "<" ClassProtocols ">" { $$ = $2; }
+ | { $$ = NULL; }
+ ;
+
ClassExpression
- : "@class" ClassNameOpt ClassSuperOpt ClassFieldList ClassMessageDeclarationListOpt "@end" { $$ = new(driver.pool_) CYClassExpression($2, $3, $4, $5); }
+ : "@class" ClassNameOpt ClassSuperOpt ClassProtocolListOpt ClassFieldList ClassMessageDeclarationListOpt "@end" { $$ = new(driver.pool_) CYClassExpression($2, $3, $4, $5, $6); }
;
ClassStatement
- : "@class" ClassName ClassSuperOpt ClassFieldList ClassMessageDeclarationListOpt "@end" { $$ = new(driver.pool_) CYClassStatement($2, $3, $4, $5); }
+ : "@class" ClassName ClassSuperOpt ClassProtocolListOpt ClassFieldList ClassMessageDeclarationListOpt "@end" { $$ = new(driver.pool_) CYClassStatement($2, $3, $4, $5, $6); }
;
CategoryStatement
return Instance::Make(context, nil);
if (Class _class = objc_getClass(name.data))
return CYMakeInstance(context, _class, true);
+ if (Protocol *protocol = objc_getProtocol(name.data))
+ return CYMakeInstance(context, protocol, true);
return NULL;
} CYPoolCatch(NULL) return /*XXX*/ NULL; }
fields_->Output(out);
if (messages_ != NULL)
messages_->Output(out, false);
+ if (protocols_ != NULL) {
+ out << '<';
+ out << *protocols_;
+ out << '>';
+ }
out << "objc_registerClassPair($cyc);";
out << "return $cyc;";
out << "}(";
out << code_;
}
+void CYProtocol::Output(CYOutput &out) const {
+ name_->Output(out, CYPA, CYNoFlags);
+ if (next_ != NULL)
+ out << ',' << ' ' << *next_;
+}
+
void CYSelector::Output(CYOutput &out, CYFlags flags) const {
out << "@selector" << '(' << name_ << ')';
}
$E($ CYAssign($V("$cyp"), $C1($V("object_getClass"), cys)))->*
$E($ CYAssign(cyc, $C3($V("objc_allocateClassPair"), cys, name, $D(0))))->*
$E($ CYAssign($V("$cym"), $C1($V("object_getClass"), cyc)))->*
+ protocols_->Replace(context)->*
fields_->Replace(context)->*
messages_->Replace(context, false)->*
$E($C1($V("objc_registerClassPair"), cyc))->*
return tag_ == NULL ? next : $ CYSelectorPart(tag_, name_ != NULL, next);
}
+CYStatement *CYProtocol::Replace(CYContext &context) const { $T(NULL)
+ return $ CYBlock($$->*
+ next_->Replace(context)->*
+ $E($C2($V("class_addProtocol"),
+ $V("$cyc"), name_
+ ))
+ );
+}
+
CYExpression *CYSelector::Replace(CYContext &context) {
return $N1($V("Selector"), name_->Replace(context));
}
void Output(CYOutput &out, bool replace) const;
};
+struct CYProtocol :
+ CYNext<CYProtocol>,
+ CYThing
+{
+ CYExpression *name_;
+
+ CYProtocol(CYExpression *name, CYProtocol *next = NULL) :
+ CYNext<CYProtocol>(next),
+ name_(name)
+ {
+ }
+
+ CYStatement *Replace(CYContext &context) const;
+ void Output(CYOutput &out) const;
+};
+
struct CYClass {
CYClassName *name_;
CYExpression *super_;
+ CYProtocol *protocols_;
CYField *fields_;
CYMessage *messages_;
- CYClass(CYClassName *name, CYExpression *super, CYField *fields, CYMessage *messages) :
+ CYClass(CYClassName *name, CYExpression *super, CYProtocol *protocols, CYField *fields, CYMessage *messages) :
name_(name),
super_(super),
+ protocols_(protocols),
fields_(fields),
messages_(messages)
{
CYClass,
CYExpression
{
- CYClassExpression(CYClassName *name, CYExpression *super, CYField *fields, CYMessage *messages) :
- CYClass(name, super, fields, messages)
+ CYClassExpression(CYClassName *name, CYExpression *super, CYProtocol *protocols, CYField *fields, CYMessage *messages) :
+ CYClass(name, super, protocols, fields, messages)
{
}
CYClass,
CYStatement
{
- CYClassStatement(CYClassName *name, CYExpression *super, CYField *fields, CYMessage *messages) :
- CYClass(name, super, fields, messages)
+ CYClassStatement(CYClassName *name, CYExpression *super, CYProtocol *protocols, CYField *fields, CYMessage *messages) :
+ CYClass(name, super, protocols, fields, messages)
{
}