]> git.saurik.com Git - cycript.git/commitdiff
Added CYNoLeader after 'case', implemented a pass-through LetStatement binding (tempo...
authorJay Freeman (saurik) <saurik@saurik.com>
Mon, 19 Oct 2009 18:58:08 +0000 (18:58 +0000)
committerJay Freeman (saurik) <saurik@saurik.com>
Mon, 19 Oct 2009 18:58:08 +0000 (18:58 +0000)
Console.cpp
Cycript.l
Cycript.y
Output.cpp
Parser.hpp

index b3702ca386af74bd734ecf0c8e70566c735b9603..f83c3a25118cf8b8764a77f4d0fbd9dba1d20f9a 100644 (file)
@@ -91,6 +91,17 @@ static void sigint(int) {
     }
 }
 
+#if YYDEBUG
+static bool bison_;
+#endif
+
+void Setup(cy::parser &parser) {
+#if YYDEBUG
+    if (bison_)
+        parser.set_debug_level(1);
+#endif
+}
+
 void Run(int socket, const char *data, size_t size, FILE *fout = NULL, bool expand = false) {
     CYPool pool;
 
@@ -218,7 +229,7 @@ static void Console(int socket) {
         else {
             CYDriver driver("");
             cy::parser parser(driver);
-            //parser.set_debug_level(1);
+            Setup(parser);
 
             driver.data_ = command.c_str();
             driver.size_ = command.size();
@@ -304,7 +315,7 @@ int main(int argc, char *argv[]) {
     pid_t pid(_not(pid_t));
     bool compile(false);
 
-    for (;;) switch (getopt(argc, argv, "cp:")) {
+    for (;;) switch (getopt(argc, argv, "cg:p:")) {
         case -1:
             goto getopt;
         case '?':
@@ -315,6 +326,18 @@ int main(int argc, char *argv[]) {
             compile = true;
         break;
 
+        case 'g':
+            if (false);
+#if YYDEBUG
+            else if (strcmp(optarg, "bison") == 0)
+                bison_ = true;
+#endif
+            else {
+                fprintf(stderr, "invalid name for -g\n");
+                return 1;
+            }
+        break;
+
         case 'p': {
             size_t size(strlen(optarg));
             char *end;
@@ -373,6 +396,7 @@ int main(int argc, char *argv[]) {
     else {
         CYDriver driver(script ?: "<stdin>");
         cy::parser parser(driver);
+        Setup(parser);
 
         char *start, *end;
 
index dd6e2042657bc815afaa56c7ac1e2d8b84344ccf..063e9004fd0fcc584dd053cde11b51423316fa99 100644 (file)
--- a/Cycript.l
+++ b/Cycript.l
@@ -1,9 +1,9 @@
 %{
+#define YYLTYPE cy::location
 #include "Cycript.tab.hh"
 typedef cy::parser::token tk;
 
 #define YY_EXTRA_TYPE CYDriver *
-#define YYLTYPE cy::location
 
 #define T yylval->newline_ = yyextra->state_ == CYNewLine;
 #define C T yyextra->state_ = CYClear;
@@ -188,6 +188,7 @@ Escape   \\[\\'"bfnrtv]|\\0|\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}|\\\n
 "volatile"     L C yylval->word_ = new CYWord("volatile"); return tk::Volatile;
 
 "each"         L C yylval->word_ = new CYIdentifier("each"); return tk::Each;
+"let"          L C yylval->word_ = new CYIdentifier("let"); return tk::Let;
 
 [a-zA-Z$_][a-zA-Z$_0-9]* yylval->identifier_ = new CYIdentifier(apr_pstrmemdup(yyextra->pool_, yytext, yyleng)); L C return tk::Identifier_;
 
index 6a355343f8b538d9b3fc8f3baacf2dbedaf82b06..6a304b3ab9989a25ecc8db857f4d1a8f9df76c89 100644 (file)
--- a/Cycript.y
+++ b/Cycript.y
@@ -107,7 +107,11 @@ int cylex(YYSTYPE *lvalp, cy::location *llocp, void *scanner);
 
 %defines
 
-//%debug
+%glr-parser
+%expect 1
+
+%debug
+
 %error-verbose
 
 %parse-param { CYDriver &driver }
@@ -236,6 +240,7 @@ int cylex(YYSTYPE *lvalp, cy::location *llocp, void *scanner);
 %token <word_> Volatile "volatile"
 
 %token <identifier_> Each "each"
+%token <identifier_> Let "let"
 
 %token <identifier_> Identifier_
 %token <number_> NumericLiteral
@@ -259,6 +264,7 @@ int cylex(YYSTYPE *lvalp, cy::location *llocp, void *scanner);
 %type <expression_> BitwiseANDExpressionNoBF
 %type <expression_> BitwiseANDExpressionNoIn
 %type <statement_> Block
+%type <statement_> Block_
 %type <boolean_> BooleanLiteral
 %type <expression_> BitwiseORExpression
 %type <expression_> BitwiseORExpressionNoBF
@@ -329,6 +335,7 @@ int cylex(YYSTYPE *lvalp, cy::location *llocp, void *scanner);
 %type <statement_> LabelledStatement
 %type <expression_> LeftHandSideExpression
 %type <expression_> LeftHandSideExpressionNoBF
+%type <statement_> LetStatement
 %type <literal_> Literal
 %type <expression_> LogicalANDExpression
 %type <expression_> LogicalANDExpressionNoBF
@@ -435,10 +442,10 @@ Terminator
     | error { if (yychar != 0 && yychar != cy::parser::token::CloseBrace && !yylval.newline_) YYABORT; else { yyerrok; driver.errors_.pop_back(); } }
     ;
 
-CommaOpt
+/*CommaOpt
     : ","
     |
-    ;
+    ;*/
 
 NewLineOpt
     : "\n"
@@ -516,6 +523,7 @@ Word
 Identifier
     : Identifier_ { $$ = $1; }
     | "each" { $$ = $1; }
+    | "let" { $$ = $1; }
     ;
 
 IdentifierOpt
@@ -588,7 +596,7 @@ ObjectLiteral
 
 PropertyNameAndValueList_
     : "," PropertyNameAndValueList { $$ = $2; }
-    | CommaOpt { $$ = NULL; }
+    | { $$ = NULL; }
     ;
 
 PropertyNameAndValueListOpt
@@ -1001,8 +1009,12 @@ Statement
     | TryStatement { $$ = $1; }
     ;
 
+Block_
+    : "{" StatementListOpt "}" { $$ = $2; }
+    ;
+
 Block
-    : "{" StatementListOpt "}" { if ($2) $$ = new(driver.pool_) CYBlock($2); else $$ = new(driver.pool_) CYEmpty(); }
+    : Block_ { if ($1) $$ = new(driver.pool_) CYBlock($1); else $$ = new(driver.pool_) CYEmpty(); }
     ;
 
 StatementList
@@ -1015,7 +1027,7 @@ StatementListOpt
     ;
 
 VariableStatement
-    : "var" VariableDeclarationList Terminator { $$ = $2; }
+    : "var" VariableDeclarationList Terminator { $$ = new(driver.pool_) CYVar($2); }
     ;
 
 VariableDeclarationList_
@@ -1105,7 +1117,6 @@ ForStatementInitialiser
 
 ForInStatement
     : "for" "(" ForInStatementInitialiser "in" Expression ")" Statement { $$ = new(driver.pool_) CYForIn($3, $5, $7); }
-    | "for" "each" "(" ForInStatementInitialiser "in" Expression ")" Statement { $$ = new(driver.pool_) CYForEachIn($4, $6, $8); }
     ;
 
 ForInStatementInitialiser
@@ -1160,16 +1171,16 @@ ThrowStatement
     ;
 
 TryStatement
-    : "try" Block CatchOpt FinallyOpt { $$ = new(driver.pool_) CYTry($2, $3, $4); }
+    : "try" Block_ CatchOpt FinallyOpt { $$ = new(driver.pool_) CYTry($2, $3, $4); }
     ;
 
 CatchOpt
-    : "catch" "(" Identifier ")" Block { $$ = new(driver.pool_) CYCatch($3, $5); }
+    : "catch" "(" Identifier ")" Block_ { $$ = new(driver.pool_) CYCatch($3, $5); }
     | { $$ = NULL; }
     ;
 
 FinallyOpt
-    : "finally" Block { $$ = $2; }
+    : "finally" Block_ { $$ = $2; }
     | { $$ = NULL; }
     ;
 
@@ -1209,7 +1220,7 @@ SourceElement
     | FunctionDeclaration { $$ = $1; }
     ;
 
-/* Objective-C Extensions {{{ */
+/* Cycript: @class Declaration {{{ */
 ClassSuperOpt
     : ":" MemberExpressionNoBF { $$ = $2; }
     | { $$ = NULL; }
@@ -1282,7 +1293,8 @@ Statement
     : ClassDefinition { $$ = $1; }
     | CategoryStatement { $$ = $1; }
     ;
-
+/* }}} */
+/* Cycript: Send Message {{{ */
 VariadicCall
     : "," AssignmentExpression VariadicCall { $$ = new(driver.pool_) CYArgument(NULL, $2, $3); }
     | { $$ = NULL; }
@@ -1325,7 +1337,7 @@ PrimaryExpression_
     | "@selector" "(" SelectorExpression ")" { $$ = new(driver.pool_) CYSelector($3); }
     ;
 /* }}} */
-
+/* Cycript: Pointer Indirection/Addressing {{{ */
 AssigneeExpression_
     : "*" UnaryExpression { $$ = new(driver.pool_) CYIndirect($2); }
     ;
@@ -1337,7 +1349,13 @@ UnaryExpression_
 MemberAccess
     : "->" Identifier { $$ = new(driver.pool_) CYIndirectMember(NULL, new(driver.pool_) CYString($2)); }
     ;
-
+/* }}} */
+/* ECMAScript5: Object Literal Trailing Comma {{{ */
+PropertyNameAndValueList_
+    : "," { $$ = NULL; }
+    ;
+/* }}} */
+/* JavaScript 1.7: Array Comprehensions {{{ */
 IfComprehension
     : "if" "(" Expression ")" { $$ = new(driver.pool_) CYIfComprehension($3); }
     ;
@@ -1360,5 +1378,20 @@ ComprehensionList
 PrimaryExpression_
     : "[" AssignmentExpression ComprehensionList "]" { $$ = new(driver.pool_) CYArrayComprehension($2, $3); }
     ;
+/* }}} */
+/* JavaScript 1.7: for each {{{ */
+ForInStatement
+    : "for" "each" "(" ForInStatementInitialiser "in" Expression ")" Statement { $$ = new(driver.pool_) CYForEachIn($4, $6, $8); }
+    ;
+/* }}} */
+/* JavaScript 1.7: Let Statements {{{ */
+LetStatement
+    : "let" "(" VariableDeclarationList ")" Block_ { $$ = new(driver.pool_) CYLet($3, $5); }
+    ;
+
+Statement
+    : LetStatement
+    ;
+/* }}} */
 
 %%
index 100e25a5f88b0ea0db0595afd9fe20a542e7bbba..75802883eeafa85f0f250cb32963c4b0f0e69feb 100644 (file)
@@ -212,16 +212,21 @@ void CYContinue::Output(std::ostream &out) const {
 void CYClause::Output(std::ostream &out) const {
     if (case_ != NULL) {
         out << "case";
-        case_->Output(out, CYNoFlags);
+        case_->Output(out, CYNoLeader);
     } else
         out << "default";
     out << ':';
     if (code_ != NULL)
         code_->Output(out, false);
-    out << *next_;
+    if (next_ != NULL)
+        out << *next_;
+}
+
+const char *CYDeclaration::ForEachIn() const {
+    return identifier_->Value();
 }
 
-void CYDeclaration::Part(std::ostream &out, CYFlags flags) const {
+void CYDeclaration::ForIn(std::ostream &out, CYFlags flags) const {
     if ((flags & CYNoLeader) != 0)
         out << ' ';
     out << "var ";
@@ -241,11 +246,12 @@ void CYDeclaration::Output(std::ostream &out, CYFlags flags) const {
         out << ' ';
 }
 
-void CYDeclarations::Part(std::ostream &out, CYFlags flags) const {
-    if ((flags & CYNoLeader) != 0)
-        out << ' ';
+void CYDeclarations::For(std::ostream &out) const {
     out << "var ";
+    Output(out, CYNoIn);
+}
 
+void CYDeclarations::Output(std::ostream &out, CYFlags flags) const {
     const CYDeclarations *declaration(this);
   output:
     CYDeclarations *next(declaration->next_);
@@ -259,11 +265,6 @@ void CYDeclarations::Part(std::ostream &out, CYFlags flags) const {
     }
 }
 
-void CYDeclarations::Output(std::ostream &out) const {
-    Part(out, CYNoFlags);
-    out << ';';
-}
-
 void CYDirectMember::Output(std::ostream &out, CYFlags flags) const {
     object_->Output(out, Precedence(), CYLeft(flags));
     if (const char *word = property_->Word())
@@ -313,12 +314,20 @@ void CYExpression::ClassName(std::ostream &out, bool object) const {
     Output(out, CYPA, CYNoFlags);
 }
 
+const char *CYExpression::ForEachIn() const {
+    return NULL;
+}
+
+void CYExpression::For(std::ostream &out) const {
+    Output(out, CYNoIn);
+}
+
 void CYExpression::ForEachIn(std::ostream &out) const {
     // XXX: this should handle LeftHandSideExpression
     Output(out, CYPA, CYNoFlags);
 }
 
-void CYExpression::Part(std::ostream &out, CYFlags flags) const {
+void CYExpression::ForIn(std::ostream &out, CYFlags flags) const {
     // XXX: this should handle LeftHandSideExpression
     Output(out, flags);
 }
@@ -339,7 +348,7 @@ void CYField::Output(std::ostream &out) const {
 void CYFor::Output(std::ostream &out) const {
     out << "for(";
     if (initialiser_ != NULL)
-        initialiser_->Part(out, CYNoFlags);
+        initialiser_->For(out);
     out << ';';
     if (test_ != NULL)
         test_->Output(out, CYNoFlags);
@@ -392,7 +401,7 @@ void CYForEachInComprehension::End_(std::ostream &out) const {
 
 void CYForIn::Output(std::ostream &out) const {
     out << "for(";
-    initialiser_->Part(out, CYNoIn | CYNoTrailer);
+    initialiser_->ForIn(out, CYNoIn | CYNoTrailer);
     out << "in";
     set_->Output(out, CYNoLeader);
     out << ')';
@@ -492,6 +501,15 @@ void CYLambda::Output(std::ostream &out, CYFlags flags) const {
         out << ')';
 }
 
+void CYLet::Output(std::ostream &out) const {
+    out << "let(";
+    declarations_->Output(out, CYNoFlags);
+    out << "){";
+    if (statements_ != NULL)
+        statements_->Show(out);
+    out << "}";
+}
+
 void CYMessage::Output(std::ostream &out, bool replace) const {
     if (next_ != NULL)
         next_->Output(out, replace);
@@ -743,6 +761,12 @@ void CYTry::Output(std::ostream &out) const {
     }
 }
 
+void CYVar::Output(std::ostream &out) const {
+    out << "var ";
+    declarations_->Output(out, CYNoFlags);
+    out << ';';
+}
+
 void CYVariable::Output(std::ostream &out, CYFlags flags) const {
     if ((flags & CYNoLeader) != 0)
         out << ' ';
index ed4037efa9f4e1231c1bcdbb2c2dfef106661fa5..66bd87296fd59ec4c13994345c9521fb5bd365c1 100644 (file)
@@ -222,18 +222,12 @@ enum CYFlags {
     CYNoBF =       (CYNoBrace | CYNoFunction),
 };
 
-struct CYPart {
-    virtual void Part(std::ostream &out, CYFlags flags) const = 0;
+struct CYForInitialiser {
+    virtual void For(std::ostream &out) const = 0;
 };
 
-struct CYForInitialiser :
-    CYPart
-{
-};
-
-struct CYForInInitialiser :
-    CYPart
-{
+struct CYForInInitialiser {
+    virtual void ForIn(std::ostream &out, CYFlags flags) const = 0;
     virtual const char *ForEachIn() const = 0;
     virtual void ForEachIn(std::ostream &out) const = 0;
 };
@@ -245,12 +239,11 @@ struct CYExpression :
     CYClassName
 {
     virtual unsigned Precedence() const = 0;
-    virtual void Part(std::ostream &out, CYFlags flags) const;
 
-    virtual const char *ForEachIn() const {
-        return NULL;
-    }
+    virtual void For(std::ostream &out) const;
+    virtual void ForIn(std::ostream &out, CYFlags flags) const;
 
+    virtual const char *ForEachIn() const;
     virtual void ForEachIn(std::ostream &out) const;
 
     virtual void Output(std::ostream &out, CYFlags flags) const = 0;
@@ -735,31 +728,55 @@ struct CYDeclaration :
     {
     }
 
-    virtual void Part(std::ostream &out, CYFlags flags) const;
-
-    virtual const char *ForEachIn() const {
-        return identifier_->Value();
-    }
+    virtual void ForIn(std::ostream &out, CYFlags flags) const;
 
+    virtual const char *ForEachIn() const;
     virtual void ForEachIn(std::ostream &out) const;
 
     virtual void Output(std::ostream &out, CYFlags flags) const;
 };
 
 struct CYDeclarations :
-    CYStatement,
+    CYNext<CYDeclarations>,
     CYForInitialiser
 {
     CYDeclaration *declaration_;
-    CYDeclarations *next_;
 
     CYDeclarations(CYDeclaration *declaration, CYDeclarations *next) :
-        declaration_(declaration),
-        next_(next)
+        CYNext<CYDeclarations>(next),
+        declaration_(declaration)
+    {
+    }
+
+    virtual void For(std::ostream &out) const;
+    virtual void Output(std::ostream &out, CYFlags flags) const;
+};
+
+struct CYVar :
+    CYStatement
+{
+    CYDeclarations *declarations_;
+
+    CYVar(CYDeclarations *declarations) :
+        declarations_(declarations)
+    {
+    }
+
+    virtual void Output(std::ostream &out) const;
+};
+
+struct CYLet :
+    CYStatement
+{
+    CYDeclarations *declarations_;
+    CYStatement *statements_;
+
+    CYLet(CYDeclarations *declarations, CYStatement *statements) :
+        declarations_(declarations),
+        statements_(statements)
     {
     }
 
-    virtual void Part(std::ostream &out, CYFlags flags) const;
     virtual void Output(std::ostream &out) const;
 };