]> git.saurik.com Git - cycript.git/commitdiff
Add syntax akin to Java's anonymous inner classes.
authorJay Freeman (saurik) <saurik@saurik.com>
Thu, 31 Dec 2015 21:38:55 +0000 (13:38 -0800)
committerJay Freeman (saurik) <saurik@saurik.com>
Thu, 31 Dec 2015 21:38:55 +0000 (13:38 -0800)
Output.cpp
Parser.ypp.in
Replace.cpp
Syntax.hpp

index c436b3ca1e184a7b93df08b84b4159347137cf6f..e8ae4aeb7071890a4bf7af8f41df49759b0b1743 100644 (file)
@@ -452,6 +452,11 @@ void CYExpression::Output(CYOutput &out, int precedence, CYFlags flags) const {
         Output(out, flags);
 }
 
         Output(out, flags);
 }
 
+void CYExtend::Output(CYOutput &out, CYFlags flags) const {
+    lhs_->Output(out, CYLeft(flags));
+    out << ' ' << object_;
+}
+
 void CYExternal::Output(CYOutput &out, CYFlags flags) const {
     out << "extern" << abi_ << typed_;
     out.Terminate();
 void CYExternal::Output(CYOutput &out, CYFlags flags) const {
     out << "extern" << abi_ << typed_;
     out.Terminate();
@@ -872,7 +877,7 @@ void CYReturn::Output(CYOutput &out, CYFlags flags) const {
 }
 
 void CYRubyBlock::Output(CYOutput &out, CYFlags flags) const {
 }
 
 void CYRubyBlock::Output(CYOutput &out, CYFlags flags) const {
-    call_->Output(out, CYLeft(flags));
+    lhs_->Output(out, CYLeft(flags));
     out << ' ';
     proc_->Output(out, CYRight(flags));
 }
     out << ' ';
     proc_->Output(out, CYRight(flags));
 }
index c2927f2b4fcb6c44dab7c7fb51cb3f87acb517e3..ffa42cc32e9e114dfa2ceb562fe06f544a359d4f 100644 (file)
@@ -48,6 +48,7 @@
 %union { CYBinding *binding_; }
 %union { CYBindings *bindings_; }
 %union { CYBoolean *boolean_; }
 %union { CYBinding *binding_; }
 %union { CYBindings *bindings_; }
 %union { CYBoolean *boolean_; }
+%union { CYBraced *braced_; }
 %union { CYClause *clause_; }
 %union { cy::Syntax::Catch *catch_; }
 %union { CYClassTail *classTail_; }
 %union { CYClause *clause_; }
 %union { cy::Syntax::Catch *catch_; }
 %union { CYClassTail *classTail_; }
@@ -71,7 +72,6 @@
 %union { CYParenthetical *parenthetical_; }
 %union { CYProperty *property_; }
 %union { CYPropertyName *propertyName_; }
 %union { CYParenthetical *parenthetical_; }
 %union { CYProperty *property_; }
 %union { CYPropertyName *propertyName_; }
-%union { CYRubyProc *rubyProc_; }
 %union { CYSpan *span_; }
 %union { CYStatement *statement_; }
 %union { CYString *string_; }
 %union { CYSpan *span_; }
 %union { CYStatement *statement_; }
 %union { CYString *string_; }
@@ -503,6 +503,8 @@ type; })
 %type <binding_> BindingElement
 %type <expression_> BitwiseORExpression
 %type <expression_> BitwiseXORExpression
 %type <binding_> BindingElement
 %type <expression_> BitwiseORExpression
 %type <expression_> BitwiseXORExpression
+%type <target_> BracedExpression_
+%type <target_> BracedExpression
 %type <statement_> BreakStatement
 %type <statement_> BreakableStatement
 %type <expression_> CallExpression_
 %type <statement_> BreakStatement
 %type <statement_> BreakableStatement
 %type <expression_> CallExpression_
@@ -623,9 +625,7 @@ type; })
 %type <bool_> RegularExpressionSlash
 %type <expression_> RelationalExpression
 %type <statement_> ReturnStatement
 %type <bool_> RegularExpressionSlash
 %type <expression_> RelationalExpression
 %type <statement_> ReturnStatement
-%type <target_> RubyBlockExpression_
-%type <target_> RubyBlockExpression
-%type <rubyProc_> RubyProcExpression
+%type <braced_> BracedParameter
 %type <functionParameter_> RubyProcParameterList_
 %type <functionParameter_> RubyProcParameterList
 %type <functionParameter_> RubyProcParameters
 %type <functionParameter_> RubyProcParameterList_
 %type <functionParameter_> RubyProcParameterList
 %type <functionParameter_> RubyProcParameters
@@ -1233,13 +1233,13 @@ AccessExpression
     ;
 
 LeftHandSideExpression
     ;
 
 LeftHandSideExpression
-    : RubyBlockExpression[pass] { $$ = $pass; }
+    : BracedExpression[pass] { $$ = $pass; }
     | IndirectExpression[pass] { $$ = $pass; }
     ;
 /* }}} */
 /* 12.4 Postfix Expressions {{{ */
 PostfixExpression
     | IndirectExpression[pass] { $$ = $pass; }
     ;
 /* }}} */
 /* 12.4 Postfix Expressions {{{ */
 PostfixExpression
-    : RubyBlockExpression[pass] { $$ = $pass; }
+    : BracedExpression[pass] { $$ = $pass; }
     | AccessExpression[lhs] LexNewLineOrOpt "++" { $$ = CYNew CYPostIncrement($lhs); }
     | AccessExpression[lhs] LexNewLineOrOpt "--" { $$ = CYNew CYPostDecrement($lhs); }
     ;
     | AccessExpression[lhs] LexNewLineOrOpt "++" { $$ = CYNew CYPostIncrement($lhs); }
     | AccessExpression[lhs] LexNewLineOrOpt "--" { $$ = CYNew CYPostDecrement($lhs); }
     ;
@@ -1622,7 +1622,7 @@ ForStatementInitializer
     ;
 
 ForInStatementInitializer
     ;
 
 ForInStatementInitializer
-    : LexLet LexOf RubyBlockExpression[pass] { $$ = $pass; }
+    : LexLet LexOf BracedExpression[pass] { $$ = $pass; }
     | LexLet LexOf IndirectExpression[pass] { $$ = $pass; }
     | LexLet LexOf Var_ LexBind ForBinding[binding] { $$ = CYNew CYForVariable($binding); }
     | ForDeclaration[pass] { $$ = $pass; }
     | LexLet LexOf IndirectExpression[pass] { $$ = $pass; }
     | LexLet LexOf Var_ LexBind ForBinding[binding] { $$ = CYNew CYForVariable($binding); }
     | ForDeclaration[pass] { $$ = $pass; }
@@ -2665,6 +2665,12 @@ ArgumentList
     ;
 /* }}} */
 
     ;
 /* }}} */
 
+/* JavaScript FTW: Java "Anonymous Inner Classes" {{{ */
+BracedParameter
+    : "{" PropertyDefinitionListOpt[properties] "}" { $$ = CYNew CYExtend(NULL, $properties); }
+    ;
+/* }}} */
+
 /* JavaScript FTW: Ruby Blocks {{{ */
 RubyProcParameterList_
     : "," RubyProcParameterList[parameters] { $$ = $parameters; }
 /* JavaScript FTW: Ruby Blocks {{{ */
 RubyProcParameterList_
     : "," RubyProcParameterList[parameters] { $$ = $parameters; }
@@ -2686,22 +2692,22 @@ RubyProcParametersOpt
     | { $$ = NULL; }
     ;
 
     | { $$ = NULL; }
     ;
 
-RubyProcExpression
-    : "{" RubyProcParametersOpt[parameters] StatementListOpt[code] "}" { $$ = CYNew CYRubyProc($parameters, $code); }
+BracedParameter
+    : ";{" RubyProcParametersOpt[parameters] StatementListOpt[code] "}" { $$ = CYNew CYRubyBlock(NULL, CYNew CYRubyProc($parameters, $code)); }
     ;
 
 PrimaryExpression
     : "{" RubyProcParameters[parameters] StatementListOpt[code] "}" { $$ = CYNew CYRubyProc($parameters, $code); }
     ;
 
     ;
 
 PrimaryExpression
     : "{" RubyProcParameters[parameters] StatementListOpt[code] "}" { $$ = CYNew CYRubyProc($parameters, $code); }
     ;
 
-RubyBlockExpression_
+BracedExpression_
     : AccessExpression[pass] LexNewLineOrOpt { $$ = $pass; }
     : AccessExpression[pass] LexNewLineOrOpt { $$ = $pass; }
-    | RubyBlockExpression_[lhs] RubyProcExpression[rhs] LexNewLineOrOpt { $$ = CYNew CYRubyBlock($lhs, $rhs); }
+    | BracedExpression_[lhs] { if (!$lhs->IsNew()) CYMAP(OpenBrace_, OpenBrace); } BracedParameter[rhs] LexNewLineOrOpt { $rhs->SetLeft($lhs); $$ = $rhs; }
     ;
 
     ;
 
-RubyBlockExpression
-    : RubyBlockExpression_[pass] "\n" { $$ = $pass; }
-    | RubyBlockExpression_[pass] { $$ = $pass; }
+BracedExpression
+    : BracedExpression_[pass] "\n" { $$ = $pass; }
+    | BracedExpression_[pass] { $$ = $pass; }
     ;
 /* }}} */
 /* JavaScript FTW: Ruby Scopes {{{ */
     ;
 /* }}} */
 /* JavaScript FTW: Ruby Scopes {{{ */
index ed486f7d96e6794d08b8dff80fa2c7643e90b459..7a99296e95849a93e026b4e524786c5908b8c373 100644 (file)
@@ -381,6 +381,10 @@ CYFunctionParameter *CYExpression::Parameter() const {
     return NULL;
 }
 
     return NULL;
 }
 
+CYTarget *CYExtend::Replace(CYContext &context) {
+    return object_.Replace(context, lhs_);
+}
+
 CYStatement *CYExternal::Replace(CYContext &context) {
     return $E($ CYAssign($V(typed_->identifier_), $C1(typed_->Replace(context), $C2($V("dlsym"), $V("RTLD_DEFAULT"), $S(typed_->identifier_->Word())))));
 }
 CYStatement *CYExternal::Replace(CYContext &context) {
     return $E($ CYAssign($V(typed_->identifier_), $C1(typed_->Replace(context), $C2($V("dlsym"), $V("RTLD_DEFAULT"), $S(typed_->identifier_->Word())))));
 }
@@ -732,21 +736,25 @@ CYExpression *CYNumber::PropertyName(CYContext &context) {
     return String(context);
 }
 
     return String(context);
 }
 
-CYTarget *CYObject::Replace(CYContext &context) {
+CYTarget *CYObject::Replace(CYContext &context, CYTarget *seed) {
     CYBuilder builder;
     if (properties_ != NULL)
     CYBuilder builder;
     if (properties_ != NULL)
-        properties_ = properties_->ReplaceAll(context, builder, $ CYThis(), false);
+        properties_ = properties_->ReplaceAll(context, builder, $ CYThis(), seed != this);
 
     if (builder) {
         return $C1($M($ CYFunctionExpression(NULL, builder.bindings_->Parameter(context),
             builder.statements_
                 ->* $ CYReturn($ CYThis())
 
     if (builder) {
         return $C1($M($ CYFunctionExpression(NULL, builder.bindings_->Parameter(context),
             builder.statements_
                 ->* $ CYReturn($ CYThis())
-        ), $S("call")), this, builder.bindings_->Argument(context));
+        ), $S("call")), seed, builder.bindings_->Argument(context));
     }
 
     CYForEach (property, properties_)
         property->Replace(context);
     }
 
     CYForEach (property, properties_)
         property->Replace(context);
-    return this;
+    return seed;
+}
+
+CYTarget *CYObject::Replace(CYContext &context) {
+    return Replace(context, this);
 }
 
 CYTarget *CYParenthetical::Replace(CYContext &context) {
 }
 
 CYTarget *CYParenthetical::Replace(CYContext &context) {
@@ -895,7 +903,7 @@ CYStatement *CYReturn::Replace(CYContext &context) {
 }
 
 CYTarget *CYRubyBlock::Replace(CYContext &context) {
 }
 
 CYTarget *CYRubyBlock::Replace(CYContext &context) {
-    return call_->AddArgument(context, proc_->Replace(context));
+    return lhs_->AddArgument(context, proc_->Replace(context));
 }
 
 CYTarget *CYRubyBlock::AddArgument(CYContext &context, CYExpression *value) {
 }
 
 CYTarget *CYRubyBlock::AddArgument(CYContext &context, CYExpression *value) {
index a3f03fab47eaca021196368cdc7cd29e965986ed..4a93e0320d191ec3f8d0885079261e9e48e544ed 100644 (file)
@@ -535,6 +535,10 @@ struct CYTarget :
         return false;
     }
 
         return false;
     }
 
+    virtual bool IsNew() const {
+        return false;
+    }
+
     virtual CYStatement *Initialize(CYContext &context, CYExpression *value);
 
     virtual CYTarget *Replace(CYContext &context) = 0;
     virtual CYStatement *Initialize(CYContext &context, CYExpression *value);
 
     virtual CYTarget *Replace(CYContext &context) = 0;
@@ -1416,6 +1420,8 @@ struct CYObject :
     {
     }
 
     {
     }
 
+    CYTarget *Replace(CYContext &context, CYTarget *seed);
+
     virtual CYTarget *Replace(CYContext &context);
     void Output(CYOutput &out, CYFlags flags) const;
 };
     virtual CYTarget *Replace(CYContext &context);
     void Output(CYOutput &out, CYFlags flags) const;
 };
@@ -1498,6 +1504,9 @@ struct New :
         return arguments_ == NULL ? 2 : 1;
     }
 
         return arguments_ == NULL ? 2 : 1;
     }
 
+    virtual bool IsNew() const {
+        return true;
+    }
 
     virtual CYTarget *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 
     virtual CYTarget *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
@@ -1551,26 +1560,55 @@ struct CYEval :
 
 struct CYRubyProc;
 
 
 struct CYRubyProc;
 
-struct CYRubyBlock :
+struct CYBraced :
     CYTarget
 {
     CYTarget
 {
-    CYExpression *call_;
-    CYRubyProc *proc_;
+    CYTarget *lhs_;
 
 
-    CYRubyBlock(CYExpression *call, CYRubyProc *proc) :
-        call_(call),
-        proc_(proc)
+    CYBraced(CYTarget *lhs = NULL) :
+        lhs_(lhs)
     {
     }
 
     CYPrecedence(1)
 
     {
     }
 
     CYPrecedence(1)
 
+    void SetLeft(CYTarget *lhs) {
+        lhs_ = lhs;
+    }
+};
+
+struct CYRubyBlock :
+    CYBraced
+{
+    CYRubyProc *proc_;
+
+    CYRubyBlock(CYTarget *lhs, CYRubyProc *proc) :
+        CYBraced(lhs),
+        proc_(proc)
+    {
+    }
+
     virtual CYTarget *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 
     virtual CYTarget *AddArgument(CYContext &context, CYExpression *value);
 };
 
     virtual CYTarget *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 
     virtual CYTarget *AddArgument(CYContext &context, CYExpression *value);
 };
 
+struct CYExtend :
+    CYBraced
+{
+    CYObject object_;
+
+    CYExtend(CYTarget *lhs, CYProperty *properties = NULL) :
+        CYBraced(lhs),
+        object_(properties)
+    {
+    }
+
+    virtual CYTarget *Replace(CYContext &context);
+    virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
 struct CYIf :
     CYStatement
 {
 struct CYIf :
     CYStatement
 {