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 CYRubyBlock::Output(CYOutput &out, CYFlags flags) const {
- call_->Output(out, CYLeft(flags));
+ lhs_->Output(out, CYLeft(flags));
out << ' ';
proc_->Output(out, CYRight(flags));
}
%union { CYBinding *binding_; }
%union { CYBindings *bindings_; }
%union { CYBoolean *boolean_; }
+%union { CYBraced *braced_; }
%union { CYClause *clause_; }
%union { cy::Syntax::Catch *catch_; }
%union { CYClassTail *classTail_; }
%union { CYParenthetical *parenthetical_; }
%union { CYProperty *property_; }
%union { CYPropertyName *propertyName_; }
-%union { CYRubyProc *rubyProc_; }
%union { CYSpan *span_; }
%union { CYStatement *statement_; }
%union { CYString *string_; }
%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 <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
;
LeftHandSideExpression
- : RubyBlockExpression[pass] { $$ = $pass; }
+ : BracedExpression[pass] { $$ = $pass; }
| 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); }
;
;
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; }
;
/* }}} */
+/* JavaScript FTW: Java "Anonymous Inner Classes" {{{ */
+BracedParameter
+ : "{" PropertyDefinitionListOpt[properties] "}" { $$ = CYNew CYExtend(NULL, $properties); }
+ ;
+/* }}} */
+
/* JavaScript FTW: Ruby Blocks {{{ */
RubyProcParameterList_
: "," RubyProcParameterList[parameters] { $$ = $parameters; }
| { $$ = 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); }
;
-RubyBlockExpression_
+BracedExpression_
: 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 {{{ */
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())))));
}
return String(context);
}
-CYTarget *CYObject::Replace(CYContext &context) {
+CYTarget *CYObject::Replace(CYContext &context, CYTarget *seed) {
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())
- ), $S("call")), this, builder.bindings_->Argument(context));
+ ), $S("call")), seed, builder.bindings_->Argument(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 *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) {
return false;
}
+ virtual bool IsNew() const {
+ return false;
+ }
+
virtual CYStatement *Initialize(CYContext &context, CYExpression *value);
virtual CYTarget *Replace(CYContext &context) = 0;
{
}
+ CYTarget *Replace(CYContext &context, CYTarget *seed);
+
virtual CYTarget *Replace(CYContext &context);
void Output(CYOutput &out, CYFlags flags) const;
};
return arguments_ == NULL ? 2 : 1;
}
+ virtual bool IsNew() const {
+ return true;
+ }
virtual CYTarget *Replace(CYContext &context);
virtual void Output(CYOutput &out, CYFlags flags) const;
struct CYRubyProc;
-struct CYRubyBlock :
+struct CYBraced :
CYTarget
{
- CYExpression *call_;
- CYRubyProc *proc_;
+ CYTarget *lhs_;
- CYRubyBlock(CYExpression *call, CYRubyProc *proc) :
- call_(call),
- proc_(proc)
+ CYBraced(CYTarget *lhs = NULL) :
+ lhs_(lhs)
{
}
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);
};
+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
{