]> git.saurik.com Git - cycript.git/blobdiff - Output.cpp
Make Functor/struct output fancy type definitions.
[cycript.git] / Output.cpp
index e7b1b2ca8fdc76d7d46317d0ce18544cf35b71ce..0bc11727f29c47ed99bc86ce772bc51c2357d1b7 100644 (file)
@@ -1,5 +1,5 @@
-/* Cycript - Optimizing JavaScript Compiler/Runtime
- * Copyright (C) 2009-2015  Jay Freeman (saurik)
+/* Cycript - The Truly Universal Scripting Language
+ * Copyright (C) 2009-2016  Jay Freeman (saurik)
 */
 
 /* GNU Affero General Public License, Version 3 {{{ */
@@ -326,7 +326,7 @@ void CYCondition::Output(CYOutput &out, CYFlags flags) const {
     test_->Output(out, Precedence() - 1, CYLeft(flags));
     out << ' ' << '?' << ' ';
     if (true_ != NULL)
-        true_->Output(out, CYAssign::Precedence_, CYNoFlags);
+        true_->Output(out, CYAssign::Precedence_, CYNoColon);
     out << ' ' << ':' << ' ';
     false_->Output(out, CYAssign::Precedence_, CYRight(flags));
 }
@@ -340,10 +340,12 @@ void CYContinue::Output(CYOutput &out, CYFlags flags) const {
 
 void CYClause::Output(CYOutput &out) const {
     out << '\t';
-    if (value_ != NULL)
-        out << "case" << ' ' << *value_;
-    else
+    if (value_ == NULL)
         out << "default";
+    else {
+        out << "case" << ' ';
+        value_->Output(out, CYNoColon);
+    }
     out << ':' << '\n';
     ++out.indent_;
     out << code_;
@@ -450,8 +452,13 @@ void CYExpression::Output(CYOutput &out, int precedence, CYFlags flags) const {
         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 << "extern" << ' ' << abi_ << ' ' << typed_;
     out.Terminate();
 }
 
@@ -658,7 +665,7 @@ void CYTemplate::Output(CYOutput &out, CYFlags flags) const {
 }
 
 void CYTypeArrayOf::Output(CYOutput &out, CYIdentifier *identifier) const {
-    next_->Output(out, Precedence(), identifier);
+    next_->Output(out, Precedence(), identifier, false);
     out << '[';
     out << size_;
     out << ']';
@@ -666,31 +673,42 @@ void CYTypeArrayOf::Output(CYOutput &out, CYIdentifier *identifier) const {
 
 void CYTypeBlockWith::Output(CYOutput &out, CYIdentifier *identifier) const {
     out << '(' << '^';
-    next_->Output(out, Precedence(), identifier);
+    next_->Output(out, Precedence(), identifier, false);
     out << ')' << '(' << parameters_ << ')';
 }
 
 void CYTypeConstant::Output(CYOutput &out, CYIdentifier *identifier) const {
-    out << "const" << ' ';
-    next_->Output(out, Precedence(), identifier);
+    out << "const";
+    next_->Output(out, Precedence(), identifier, false);
 }
 
 void CYTypeFunctionWith::Output(CYOutput &out, CYIdentifier *identifier) const {
-    next_->Output(out, Precedence(), identifier);
-    out << '(' << parameters_ << ')';
+    next_->Output(out, Precedence(), identifier, false);
+    out << '(' << parameters_;
+    if (variadic_) {
+        if (parameters_ != NULL)
+            out << ',' << ' ';
+        out << "...";
+    }
+    out << ')';
 }
 
 void CYTypePointerTo::Output(CYOutput &out, CYIdentifier *identifier) const {
     out << '*';
-    next_->Output(out, Precedence(), identifier);
+    next_->Output(out, Precedence(), identifier, false);
 }
 
 void CYTypeVolatile::Output(CYOutput &out, CYIdentifier *identifier) const {
     out << "volatile";
-    next_->Output(out, Precedence(), identifier);
+    next_->Output(out, Precedence(), identifier, true);
 }
 
-void CYTypeModifier::Output(CYOutput &out, int precedence, CYIdentifier *identifier) const {
+void CYTypeModifier::Output(CYOutput &out, int precedence, CYIdentifier *identifier, bool space) const {
+    if (this == NULL && identifier == NULL)
+        return;
+    else if (space)
+        out << ' ';
+
     if (this == NULL) {
         out << identifier;
         return;
@@ -707,7 +725,7 @@ void CYTypeModifier::Output(CYOutput &out, int precedence, CYIdentifier *identif
 
 void CYTypedIdentifier::Output(CYOutput &out) const {
     specifier_->Output(out);
-    modifier_->Output(out, 0, identifier_);
+    modifier_->Output(out, 0, identifier_, true);
 }
 
 void CYEncodedType::Output(CYOutput &out, CYFlags flags) const {
@@ -848,6 +866,14 @@ void CYRegEx::Output(CYOutput &out, CYFlags flags) const {
     out << Value();
 }
 
+void CYResolveMember::Output(CYOutput &out, CYFlags flags) const {
+    object_->Output(out, Precedence(), CYLeft(flags));
+    if (const char *word = property_->Word())
+        out << "::" << word;
+    else
+        out << "::" << '[' << *property_ << ']';
+}
+
 void CYReturn::Output(CYOutput &out, CYFlags flags) const {
     out << "return";
     if (value_ != NULL)
@@ -856,7 +882,7 @@ void CYReturn::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));
 }
@@ -869,6 +895,11 @@ void CYRubyProc::Output(CYOutput &out, CYFlags flags) const {
     out << '\t' << '}';
 }
 
+void CYSubscriptMember::Output(CYOutput &out, CYFlags flags) const {
+    object_->Output(out, Precedence(), CYLeft(flags));
+    out << "." << '[' << *property_ << ']';
+}
+
 void CYStatement::Multiple(CYOutput &out, CYFlags flags) const {
     bool first(true);
     CYForEach (next, this) {
@@ -964,7 +995,7 @@ void CYStructTail::Output(CYOutput &out) const {
         out << '\n';
     }
     --out.indent_;
-    out << '}';
+    out << '\t' << '}';
 }
 
 void CYSuperAccess::Output(CYOutput &out, CYFlags flags) const {
@@ -987,6 +1018,15 @@ void CYSwitch::Output(CYOutput &out, CYFlags flags) const {
     out << '\t' << '}';
 }
 
+void CYSymbol::Output(CYOutput &out, CYFlags flags) const {
+    bool protect((flags & CYNoColon) != 0);
+    if (protect)
+        out << '(';
+    out << ':' << name_;
+    if (protect)
+        out << ')';
+}
+
 void CYThis::Output(CYOutput &out, CYFlags flags) const {
     out << "this";
 }
@@ -1013,20 +1053,30 @@ void Try::Output(CYOutput &out, CYFlags flags) const {
 
 } }
 
-void CYTypeError::Output(CYOutput &out) const {
-    out << "@error";
-}
+void CYTypeCharacter::Output(CYOutput &out) const {
+    switch (signing_) {
+        case CYTypeNeutral: break;
+        case CYTypeSigned: out << "signed" << ' '; break;
+        case CYTypeUnsigned: out << "unsigned" << ' '; break;
+    }
 
-void CYTypeLong::Output(CYOutput &out) const {
-    out << "long" << specifier_;
+    out << "char";
 }
 
-void CYTypeShort::Output(CYOutput &out) const {
-    out << "short" << specifier_;
+void CYTypeError::Output(CYOutput &out) const {
+    out << "@error";
 }
 
-void CYTypeSigned::Output(CYOutput &out) const {
-    out << "signed" << specifier_;
+void CYTypeIntegral::Output(CYOutput &out) const {
+    if (signing_ == CYTypeUnsigned)
+        out << "unsigned" << ' ';
+    switch (length_) {
+        case 0: out << "short"; break;
+        case 1: out << "int"; break;
+        case 2: out << "long"; break;
+        case 3: out << "long" << ' ' << "long"; break;
+        default: _assert(false);
+    }
 }
 
 void CYTypeStruct::Output(CYOutput &out) const {
@@ -1037,10 +1087,6 @@ void CYTypeStruct::Output(CYOutput &out) const {
         out << *tail_;
 }
 
-void CYTypeUnsigned::Output(CYOutput &out) const {
-    out << "unsigned" << specifier_;
-}
-
 void CYTypeReference::Output(CYOutput &out) const {
     out << "struct" << ' ' << *name_;
 }