%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