%option reentrant
Exponent [eE][+-]?[0-9]+
-Escape \\[\\'"bfnrtv]|\\0|\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}
+Escape \\[\\'"bfnrtv]|\\0|\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}|\\\n
%%
if (yytext[i] == '\\')
switch (next = yytext[++i]) {
+ case '\n': continue;
case '\\': next = '\\'; break;
case '\'': next = '\''; break;
case '"': next = '"'; break;
%type <clause_> CaseClause
%type <clause_> CaseClausesOpt
%type <catch_> CatchOpt
-%type <source_> ClassDeclaration
+%type <statement_> CategoryStatement
+%type <expression_> ClassExpression
%type <message_> ClassMessageDeclaration
%type <message_> ClassMessageDeclarationListOpt
%type <className_> ClassName
+%type <className_> ClassNameOpt
%type <expression_> ClassSuperOpt
%type <field_> ClassFieldList
%type <expression_> ConditionalExpression
| "(" AssignmentExpression ")" { $$ = $2; }
;
-ClassDeclaration
- : "@class" Identifier ClassSuperOpt ClassFieldList ClassMessageDeclarationListOpt "@end" { $$ = new CYClass($2, $3, $4, $5); }
- | "@class" ClassName ClassMessageDeclarationListOpt "@end" { $$ = new CYCategory($2, $3); }
+ClassNameOpt
+ : ClassName { $$ = $1; }
+ | { $$ = NULL; }
;
-SourceElement
- : ClassDeclaration { $$ = $1; }
+ClassExpression
+ : "@class" ClassNameOpt ClassSuperOpt ClassFieldList ClassMessageDeclarationListOpt "@end" { $$ = new CYClass($2, $3, $4, $5); }
+ ;
+
+CategoryStatement
+ : "@class" ClassName ClassMessageDeclarationListOpt "@end" { $$ = new CYCategory($2, $3); }
+ ;
+
+PrimaryExpression_
+ : ClassExpression { $$ = $1; }
+ ;
+
+Statement
+ : CategoryStatement
;
VariadicCall
: "->" Identifier { $$ = new(driver.pool_) CYIndirectMember(NULL, new(driver.pool_) CYString($2)); }
;
+/*
+
+IfComprehension
+ : "if" "(" Expression ")"
+ ;
+
+ForComprehension
+ : "for" "(" ForInStatementInitialiser "in" Expression ")"
+ ;
+
+ComprehensionListOpt
+ : ComprehensionList
+ | IfComprehension
+ |
+ ;
+
+ComprehensionList
+ : ForComprehension ComprehensionListOpt
+ ;
+
+PrimaryExpression_
+ : "[" AssignmentExpression ComprehensionList "]"
+ ;
+
+*/
+
%%
return CYCallFunction(pool, context, 2, setup, count, arguments, initialize, exception, &signature, &cif, function);
}
+static size_t Nonce_(0);
+
+static JSValueRef $cyq(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
+ char name[16];
+ sprintf(name, "%s%zu", CYCastCString(context, arguments[0]), Nonce_++);
+ return CYCastJSValue(context, name);
+}
+
static JSValueRef $objc_msgSend(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
CYPool pool;
CYSetProperty(context, global, CYJSString("objc_registerClassPair"), JSObjectMakeFunctionWithCallback(context, CYJSString("objc_registerClassPair"), &objc_registerClassPair_));
CYSetProperty(context, global, CYJSString("objc_msgSend"), JSObjectMakeFunctionWithCallback(context, CYJSString("objc_msgSend"), &$objc_msgSend));
+ CYSetProperty(context, global, CYJSString("$cyq"), JSObjectMakeFunctionWithCallback(context, CYJSString("$cyq"), &$cyq));
System_ = JSObjectMake(context, NULL, NULL);
CYSetProperty(context, global, CYJSString("system"), System_);
if (messages_ != NULL)
messages_->Output(out, true);
out << "})(";
- name_->ClassName(out);
+ name_->ClassName(out, true);
out << ");";
}
-void CYClass::Output(std::ostream &out) const {
+void CYClass::Output(std::ostream &out, CYFlags flags) const {
+ // XXX: I don't necc. need the ()s
out << "(function($cys,$cyp,$cyc,$cyn,$cyt,$cym){";
out << "$cyp=object_getClass($cys);";
- out << "$cyc=objc_allocateClassPair($cys,\"" << *name_ << "\",0);";
+ out << "$cyc=objc_allocateClassPair($cys,";
+ if (name_ != NULL)
+ name_->ClassName(out, false);
+ else
+ out << "$cyq(\"CY$\")";
+ out << ",0);";
out << "$cym=object_getClass($cyc);";
if (fields_ != NULL)
fields_->Output(out);
if (messages_ != NULL)
messages_->Output(out, false);
out << "objc_registerClassPair($cyc);";
- out << "})(";
+ out << "return $cyc;";
+ out << "}(";
if (super_ != NULL)
super_->Output(out, CYPA, CYNoFlags);
else
out << "null";
- out << ");";
+ out << "))";
}
void CYCompound::Output(std::ostream &out, CYFlags flags) const {
out << ';';
}
-void CYExpression::ClassName(std::ostream &out) const {
+void CYExpression::ClassName(std::ostream &out, bool object) const {
Output(out, CYPA, CYNoFlags);
}
code_->Output(out, false);
}
-void CYWord::ClassName(std::ostream &out) const {
- out << "objc_getClass(\"" << Value() << "\")";
+void CYWord::ClassName(std::ostream &out, bool object) const {
+ if (object)
+ out << "objc_getClass(";
+ out << '"' << Value() << '"';
+ if (object)
+ out << ')';
}
void CYWord::Output(std::ostream &out) const {
};
struct CYClassName {
- virtual void ClassName(std::ostream &out) const = 0;
+ virtual void ClassName(std::ostream &out, bool object) const = 0;
};
struct CYWord :
virtual void Output(std::ostream &out) const;
- virtual void ClassName(std::ostream &out) const;
+ virtual void ClassName(std::ostream &out, bool object) const;
virtual void PropertyName(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 void ClassName(std::ostream &out, bool object) const;
virtual const char *Word() const {
return NULL;
};
struct CYClass :
- CYSource
+ CYExpression
{
- CYIdentifier *name_;
+ CYClassName *name_;
CYExpression *super_;
CYField *fields_;
CYMessage *messages_;
- CYClass(CYIdentifier *name, CYExpression *super, CYField *fields, CYMessage *messages) :
+ CYClass(CYClassName *name, CYExpression *super, CYField *fields, CYMessage *messages) :
name_(name),
super_(super),
fields_(fields),
{
}
- virtual void Output(std::ostream &out) const;
+ CYPrecedence(0)
+
+ virtual void Output(std::ostream &out, CYFlags flags) const;
};
struct CYCategory :
- CYSource
+ CYStatement
{
CYClassName *name_;
CYMessage *messages_;
unicode identifier support (native and \u)
object literal compilation should use numerify strings
support unions (right now 0-1 fields parsed as struct)
+\\\n escapes in strings aren't handled in the console