]> git.saurik.com Git - cycript.git/commitdiff
Started work on array comprehensions, implemented multi-line string literals (not...
authorJay Freeman (saurik) <saurik@saurik.com>
Sun, 18 Oct 2009 10:32:51 +0000 (10:32 +0000)
committerJay Freeman (saurik) <saurik@saurik.com>
Sun, 18 Oct 2009 10:32:51 +0000 (10:32 +0000)
Cycript.l
Cycript.y
Library.mm
Output.cpp
Parser.hpp
todo.txt

index 2ab8f0c6dd3ee092d1978655e32a08051c07b3b5..66f38cee04f54c703194d62ee62d4c2eb6bf6277 100644 (file)
--- a/Cycript.l
+++ b/Cycript.l
@@ -61,7 +61,7 @@ int H(char c) {
 %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
 
 %%
 
@@ -204,6 +204,7 @@ Escape   \\[\\'"bfnrtv]|\\0|\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}
 
         if (yytext[i] == '\\')
             switch (next = yytext[++i]) {
+                case '\n': continue;
                 case '\\': next = '\\'; break;
                 case '\'': next = '\''; break;
                 case '"': next = '"'; break;
index 2572473b7e9cb70dcc480c424ae7ae5de66aeff1..dd0ea51da91105c8c09b1438853205e0aaa20d7f 100644 (file)
--- a/Cycript.y
+++ b/Cycript.y
@@ -269,10 +269,12 @@ int cylex(YYSTYPE *lvalp, cy::location *llocp, void *scanner);
 %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
@@ -1244,13 +1246,25 @@ ClassName
     | "(" 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
@@ -1308,4 +1322,30 @@ MemberAccess
     : "->" 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 "]"
+    ;
+
+*/
+
 %%
index 92e43ede52a8eb337f1c73ab84db7c7882c26f7d..89ed137b34913cfdb6c472c5bd2fcc663eff4ef8 100644 (file)
@@ -2710,6 +2710,14 @@ JSValueRef CYSendMessage(apr_pool_t *pool, JSContextRef context, id self, SEL _c
     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;
 
@@ -3468,6 +3476,7 @@ JSGlobalContextRef CYGetJSContext() {
 
         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_);
index f15b90d6324c9a399c5a093c84f2fb864bb0e0c0..3fc3355417ddfda231625f47f25f541d893be8ec 100644 (file)
@@ -119,26 +119,33 @@ void CYCategory::Output(std::ostream &out) const {
     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 {
@@ -264,7 +271,7 @@ void CYExpress::Output(std::ostream &out) const {
     out << ';';
 }
 
-void CYExpression::ClassName(std::ostream &out) const {
+void CYExpression::ClassName(std::ostream &out, bool object) const {
     Output(out, CYPA, CYNoFlags);
 }
 
@@ -663,8 +670,12 @@ void CYWith::Output(std::ostream &out) const {
     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 {
index fc5abf185ad3dee0fee8fcceda820dc53feaa96c..2e872a9d0bc36d7e832003b3a7fa4e46dbb2c194 100644 (file)
@@ -93,7 +93,7 @@ struct CYPropertyName {
 };
 
 struct CYClassName {
-    virtual void ClassName(std::ostream &out) const = 0;
+    virtual void ClassName(std::ostream &out, bool object) const = 0;
 };
 
 struct CYWord :
@@ -114,7 +114,7 @@ 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;
 };
 
@@ -246,7 +246,7 @@ struct CYExpression :
     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;
@@ -703,14 +703,14 @@ struct CYMessage :
 };
 
 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),
@@ -718,11 +718,13 @@ struct CYClass :
     {
     }
 
-    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_;
index d903383b529b8ab75578b0e23a591832b1994994..e8c3584ca0177301720f54792f3eebba8ef8abca 100644 (file)
--- a/todo.txt
+++ b/todo.txt
@@ -3,3 +3,4 @@ blocks and empty statements are poorly factored
 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