]> git.saurik.com Git - cycript.git/commitdiff
Add ?. syntax, for the object query documentation.
authorJay Freeman (saurik) <saurik@saurik.com>
Sun, 10 Jan 2016 03:50:48 +0000 (19:50 -0800)
committerJay Freeman (saurik) <saurik@saurik.com>
Sun, 10 Jan 2016 03:50:48 +0000 (19:50 -0800)
Output.cpp
Parser.ypp.in
Replace.cpp
Scanner.lpp.in
Syntax.hpp

index 50cc836c822ef5b5ff26a74a687d72f598c0783f..26e49fe69fd729b14cd9b68fb983f4e0de5bc171 100644 (file)
@@ -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_;
index 6e889fa2170aad17f3a7217c9054a9df2dfb4b55..3dbca897318dc2ca64abf86cd3c141fe501c1806 100644 (file)
@@ -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
index 68beb4f47b3ad1127ba94aabb0338c714434b159..d499dbcc92867a39826e83af39bbda3a8308a2b3 100644 (file)
@@ -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<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;
index e16900abb972a81c7b6ed7cfcbb84399c60f9c6d..dc8a3ddd1724493f0b68e990dd19051896bc24e8 100644 (file)
@@ -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);
index c710d8971b2962317d4e735df3122429921a5e50..4b25b30738efa55e30a7122ac22ecc4df31f37f6 100644 (file)
@@ -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
 {