rhs_->Output(out, Precedence(), CYRight(flags));
}
+void CYAttemptMember::Output(CYOutput &out, CYFlags flags) const {
+ object_->Output(out, Precedence(), CYLeft(flags) | CYNoInteger);
+ if (const char *word = property_->Word())
+ out << "?." << word;
+ else
+ _assert(false);
+}
+
void CYBlock::Output(CYOutput &out, CYFlags flags) const {
out << '{' << '\n';
++out.indent_;
%token Plus "+"
%token PlusEqual "+="
%token PlusPlus "++"
+%token QuestionPeriod "?."
%token Right ">"
%token RightEqual ">="
%token RightRight ">>"
: "." "[" AssignmentExpression[property] "]" { $$ = CYNew CYSubscriptMember(NULL, $property); }
;
/* }}} */
+/* JavaScript FTW: Undefined Monad {{{ */
+MemberAccess
+ : "?." IdentifierName[property] { $$ = CYNew CYAttemptMember(NULL, CYNew CYString($property)); }
+ | "?." AutoComplete { driver.mode_ = CYDriver::AutoDirect; YYACCEPT; }
+ ;
+/* }}} */
/* JavaScript FTW: Java "Anonymous Inner Classes" {{{ */
BracedParameter
return this;
}
+CYTarget *CYAttemptMember::Replace(CYContext &context) {
+ CYIdentifier *value(context.Unique());
+
+ return $C1($F(NULL, $P1($B(value)), $$
+ ->* $ CYReturn($ CYCondition($V(value), $M($V(value), property_), $V(value)))
+ ), object_);
+}
+
CYStatement *CYBlock::Return() {
CYImplicitReturn(code_);
return this;
}
CYTarget *CYCall::Replace(CYContext &context) {
+ // XXX: this also is a horrible hack but I'm still a month over schedule :(
+ if (CYAttemptMember *member = dynamic_cast<CYAttemptMember *>(function_)) {
+ CYIdentifier *value(context.Unique());
+
+ return $C1($F(NULL, $P1($B(value)), $$
+ ->* $ CYReturn($ CYCondition($V(value), $C($M($V(value), member->property_), arguments_), $V(value)))
+ ), member->object_);
+ }
+
context.Replace(function_);
arguments_->Replace(context);
return this;
"%" L F(tk::Percent, hi::Operator);
"%=" L F(tk::PercentEqual, hi::Operator);
"." L F(tk::Period, hi::Operator);
+"?." L F(tk::QuestionPeriod, hi::Operator);
"|" L F(tk::Pipe, hi::Operator);
"|=" L F(tk::PipeEqual, hi::Operator);
"||" L F(tk::PipePipe, hi::Operator);
virtual void Output(CYOutput &out, CYFlags flags) const;
};
+struct CYAttemptMember :
+ CYMember
+{
+ CYAttemptMember(CYExpression *object, CYExpression *property) :
+ CYMember(object, property)
+ {
+ }
+
+ CYPrecedence(1)
+
+ virtual CYTarget *Replace(CYContext &context);
+ virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
struct CYIndirectMember :
CYMember
{