From beb979b423ffca4eb63aa3ce2de22f9b13d74d4f Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Sat, 9 Jan 2016 19:50:48 -0800 Subject: [PATCH 1/1] Add ?. syntax, for the object query documentation. --- Output.cpp | 8 ++++++++ Parser.ypp.in | 7 +++++++ Replace.cpp | 17 +++++++++++++++++ Scanner.lpp.in | 1 + Syntax.hpp | 14 ++++++++++++++ 5 files changed, 47 insertions(+) diff --git a/Output.cpp b/Output.cpp index 50cc836..26e49fe 100644 --- a/Output.cpp +++ b/Output.cpp @@ -302,6 +302,14 @@ void CYAssignment::Output(CYOutput &out, CYFlags flags) const { 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_; diff --git a/Parser.ypp.in b/Parser.ypp.in index 6e889fa..3dbca89 100644 --- a/Parser.ypp.in +++ b/Parser.ypp.in @@ -305,6 +305,7 @@ type; }) %token Plus "+" %token PlusEqual "+=" %token PlusPlus "++" +%token QuestionPeriod "?." %token Right ">" %token RightEqual ">=" %token RightRight ">>" @@ -2711,6 +2712,12 @@ MemberAccess : "." "[" 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 diff --git a/Replace.cpp b/Replace.cpp index 68beb4f..d499dbc 100644 --- a/Replace.cpp +++ b/Replace.cpp @@ -125,6 +125,14 @@ CYExpression *CYAssignment::Replace(CYContext &context) { 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; @@ -145,6 +153,15 @@ CYStatement *CYBreak::Replace(CYContext &context) { } 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(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; diff --git a/Scanner.lpp.in b/Scanner.lpp.in index e16900a..dc8a3dd 100644 --- a/Scanner.lpp.in +++ b/Scanner.lpp.in @@ -370,6 +370,7 @@ XMLName {XMLNameStart}{XMLNamePart}* "%" 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); diff --git a/Syntax.hpp b/Syntax.hpp index c710d89..4b25b30 100644 --- a/Syntax.hpp +++ b/Syntax.hpp @@ -1481,6 +1481,20 @@ struct CYDirectMember : 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 { -- 2.45.2