]> git.saurik.com Git - cycript.git/commitdiff
Drastically improve pretty printed code structure.
authorJay Freeman (saurik) <saurik@saurik.com>
Tue, 24 Nov 2015 10:21:23 +0000 (02:21 -0800)
committerJay Freeman (saurik) <saurik@saurik.com>
Tue, 24 Nov 2015 10:21:23 +0000 (02:21 -0800)
Console.cpp
Execute.cpp
Library.cpp
ObjectiveC/Syntax.hpp
Output.cpp
Parser.hpp

index df349966623b4fc912590725f3e3405ad2b1cfc3..4de0b7d1a49d49d6a8e52bd31e8c72c3c009382a 100644 (file)
@@ -309,7 +309,7 @@ static char **Complete(const char *word, int start, int end) {
 
     driver.program_->Replace(context);
 
-    std::ostringstream str;
+    std::stringbuf str;
     CYOutput out(str, options);
     out << *driver.program_;
 
@@ -593,7 +593,7 @@ static void Console(CYOptions &options) {
             if (driver.program_ == NULL)
                 goto restart;
 
-            std::ostringstream str;
+            std::stringbuf str;
             CYOutput out(str, options);
             Setup(out, driver, options, lower);
             out << *driver.program_;
@@ -924,7 +924,7 @@ int Main(int argc, char * const argv[], char const * const envp[]) {
             for (CYDriver::Errors::const_iterator i(driver.errors_.begin()); i != driver.errors_.end(); ++i)
                 std::cerr << i->location_.begin << ": " << i->message_ << std::endl;
         } else if (driver.program_ != NULL) {
-            std::ostringstream str;
+            std::stringbuf str;
             CYOutput out(str, options);
             Setup(out, driver, options, true);
             out << *driver.program_;
index 70751a4b2555a331c9d05a98c53f032bb4cf8b83..c871ef51b1a7efe3cf092f28d45dcc3ec50980ad 100644 (file)
@@ -1464,7 +1464,7 @@ static JSValueRef Type_callAsFunction_toString(JSContextRef context, JSObjectRef
 static JSValueRef Type_callAsFunction_toCYON(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
     Type_privateData *internal(reinterpret_cast<Type_privateData *>(JSObjectGetPrivate(_this)));
     CYLocalPool pool;
-    std::ostringstream out;
+    std::stringbuf out;
     CYOptions options;
     CYOutput output(out, options);
     (new(pool) CYEncodedType(Decode(pool, internal->type_)))->Output(output, CYNoFlags);
index 575ccd57cec52c54971fcaaf9040b487d10f14ca..afa705c14da88ab12bd224dedf0214d2d5634d54 100644 (file)
@@ -206,7 +206,7 @@ CYUTF8String CYPoolCode(CYPool &pool, std::istream &stream) {
     CYContext context(options);
     driver.program_->Replace(context);
 
-    std::ostringstream str;
+    std::stringbuf str;
     CYOutput out(str, options);
     out << *driver.program_;
     return $pool.strdup(str.str().c_str());
index 8beabb98342160c2cbee4bed12b912e10b1bed1d..0f3cc38ca498484c019f7000a8443ade36642416 100644 (file)
@@ -228,6 +228,8 @@ struct CYClassStatement :
     {
     }
 
+    CYCompact(None)
+
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
@@ -244,6 +246,8 @@ struct CYCategory :
     {
     }
 
+    CYCompact(None)
+
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
index cdfe1bd1e4a3c5c8a49c8f3deeb47678dd2549c2..d3dbb0f71838d427d2655554dd9b3806b1a36949 100644 (file)
 #include <sstream>
 
 void CYOutput::Terminate() {
-    out_ << ';';
+    operator ()(';');
     mode_ = NoMode;
 }
 
 CYOutput &CYOutput::operator <<(char rhs) {
     if (rhs == ' ' || rhs == '\n')
         if (pretty_)
-            out_ << rhs;
+            operator ()(rhs);
         else goto done;
     else if (rhs == '\t')
         if (pretty_)
             for (unsigned i(0); i != indent_; ++i)
-                out_ << "    ";
+                operator ()("    ", 4);
         else goto done;
     else if (rhs == '\r') {
         if (right_) {
-            out_ << '\n';
+            operator ()('\n');
             right_ = false;
         } goto done;
     } else goto work;
@@ -53,7 +53,7 @@ CYOutput &CYOutput::operator <<(char rhs) {
   work:
     if (mode_ == Terminated && rhs != '}') {
         right_ = true;
-        out_ << ';';
+        operator ()(';');
     }
 
     if (rhs == ';') {
@@ -65,21 +65,21 @@ CYOutput &CYOutput::operator <<(char rhs) {
         }
     } else if (rhs == '+') {
         if (mode_ == NoPlus)
-            out_ << ' ';
+            operator ()(' ');
         mode_ = NoPlus;
     } else if (rhs == '-') {
         if (mode_ == NoHyphen)
-            out_ << ' ';
+            operator ()(' ');
         mode_ = NoHyphen;
     } else if (WordEndRange_[rhs]) {
         if (mode_ == NoLetter)
-            out_ << ' ';
+            operator ()(' ');
         mode_ = NoLetter;
     } else none:
         mode_ = NoMode;
 
     right_ = true;
-    out_ << rhs;
+    operator ()(rhs);
   done:
     return *this;
 }
@@ -91,13 +91,13 @@ CYOutput &CYOutput::operator <<(const char *rhs) {
         return *this << *rhs;
 
     if (mode_ == Terminated)
-        out_ << ';';
+        operator ()(';');
     else if (
         mode_ == NoPlus && *rhs == '+' ||
         mode_ == NoHyphen && *rhs == '-' ||
         mode_ == NoLetter && WordEndRange_[*rhs]
     )
-        out_ << ' ';
+        operator ()(' ');
 
     char last(rhs[size - 1]);
     if (WordEndRange_[last] || last == '/')
@@ -106,7 +106,7 @@ CYOutput &CYOutput::operator <<(const char *rhs) {
         mode_ = NoMode;
 
     right_ = true;
-    out_ << rhs;
+    operator ()(rhs, size);
     return *this;
 }
 
@@ -183,7 +183,7 @@ void Catch::Output(CYOutput &out) const {
 
 void CYComment::Output(CYOutput &out, CYFlags flags) const {
     out << '\r';
-    out.out_ << value_;
+    out(value_);
     out.right_ = true;
     out << '\r';
 }
@@ -215,12 +215,15 @@ void CYContinue::Output(CYOutput &out, CYFlags flags) const {
 }
 
 void CYClause::Output(CYOutput &out) const {
+    out << '\t';
     if (case_ != NULL)
         out << "case" << ' ' << *case_;
     else
         out << "default";
     out << ':' << '\n';
+    ++out.indent_;
     out << code_;
+    --out.indent_;
     out << next_;
 }
 
@@ -229,7 +232,7 @@ void CYDebugger::Output(CYOutput &out, CYFlags flags) const {
 }
 
 void CYDeclaration::ForIn(CYOutput &out, CYFlags flags) const {
-    out << "var";
+    out << "var" << ' ';
     Output(out, CYRight(flags));
 }
 
@@ -243,7 +246,7 @@ void CYDeclaration::Output(CYOutput &out, CYFlags flags) const {
 }
 
 void CYForDeclarations::Output(CYOutput &out, CYFlags flags) const {
-    out << "var";
+    out << "var" << ' ';
     declarations_->Output(out, CYRight(flags));
 }
 
@@ -280,7 +283,16 @@ void CYDirectMember::Output(CYOutput &out, CYFlags flags) const {
 
 void CYDoWhile::Output(CYOutput &out, CYFlags flags) const {
     out << "do";
-    code_->Single(out, CYCenter(flags));
+
+    unsigned line(out.position_.line);
+    unsigned indent(out.indent_);
+    code_->Single(out, CYCenter(flags), CYCompactLong);
+
+    if (out.position_.line != line && out.recent_ == indent)
+        out << ' ';
+    else
+        out << '\n' << '\t';
+
     out << "while" << ' ' << '(' << *test_ << ')';
 }
 
@@ -354,14 +366,14 @@ void CYFor::Output(CYOutput &out, CYFlags flags) const {
         out << ' ';
     out << increment_;
     out << ')';
-    code_->Single(out, CYRight(flags));
+    code_->Single(out, CYRight(flags), CYCompactShort);
 }
 
 void CYForOf::Output(CYOutput &out, CYFlags flags) const {
     out << "for" << ' ' << "each" << ' ' << '(';
     initialiser_->ForIn(out, CYNoIn);
-    out << "in" << *set_ << ')';
-    code_->Single(out, CYRight(flags));
+    out << ' ' << "in" << ' ' << *set_ << ')';
+    code_->Single(out, CYRight(flags), CYCompactShort);
 }
 
 void CYForOfComprehension::Output(CYOutput &out) const {
@@ -372,8 +384,8 @@ void CYForIn::Output(CYOutput &out, CYFlags flags) const {
     out << "for" << ' ' << '(';
     if (initialiser_ != NULL)
         initialiser_->ForIn(out, CYNoIn);
-    out << "in" << *set_ << ')';
-    code_->Single(out, CYRight(flags));
+    out << ' ' << "in" << ' ' << *set_ << ')';
+    code_->Single(out, CYRight(flags), CYCompactShort);
 }
 
 void CYForInComprehension::Output(CYOutput &out) const {
@@ -433,11 +445,18 @@ void CYIf::Output(CYOutput &out, CYFlags flags) const {
     else
         jacks |= protect ? CYNoFlags : CYCenter(flags);
 
-    true_->Single(out, jacks);
+    unsigned line(out.position_.line);
+    unsigned indent(out.indent_);
+    true_->Single(out, jacks, CYCompactShort);
 
     if (false_ != NULL) {
-        out << '\t' << "else";
-        false_->Single(out, right);
+        if (out.position_.line != line && out.recent_ == indent)
+            out << ' ';
+        else
+            out << '\n' << '\t';
+
+        out << "else";
+        false_->Single(out, right, CYCompactLong);
     }
 
     if (protect)
@@ -475,8 +494,8 @@ void CYInfix::Output(CYOutput &out, CYFlags flags) const {
 }
 
 void CYLabel::Output(CYOutput &out, CYFlags flags) const {
-    out << *name_ << ':' << ' ';
-    statement_->Single(out, CYRight(flags));
+    out << *name_ << ':';
+    statement_->Single(out, CYRight(flags), CYCompactShort);
 }
 
 void CYParenthetical::Output(CYOutput &out, CYFlags flags) const {
@@ -503,7 +522,7 @@ void CYTypeBlockWith::Output(CYOutput &out, CYIdentifier *identifier) const {
 }
 
 void CYTypeConstant::Output(CYOutput &out, CYIdentifier *identifier) const {
-    out << "const";
+    out << "const" << ' ';
     next_->Output(out, Precedence(), identifier);
 }
 
@@ -561,12 +580,12 @@ void CYLambda::Output(CYOutput &out, CYFlags flags) const {
 }
 
 void CYTypeDefinition::Output(CYOutput &out, CYFlags flags) const {
-    out << "typedef" << *typed_;
+    out << "typedef" << ' ' << *typed_;
 }
 
 void CYLetStatement::Output(CYOutput &out, CYFlags flags) const {
     out << "let" << ' ' << '(' << *declarations_ << ')';
-    code_->Single(out, CYRight(flags));
+    code_->Single(out, CYRight(flags), CYCompactShort);
 }
 
 void CYModule::Output(CYOutput &out) const {
@@ -685,17 +704,26 @@ void CYStatement::Multiple(CYOutput &out, CYFlags flags) const {
     }
 }
 
-void CYStatement::Single(CYOutput &out, CYFlags flags) const {
+void CYStatement::Single(CYOutput &out, CYFlags flags, CYCompactType request) const {
     if (this == NULL)
         return out.Terminate();
 
     _assert(next_ == NULL);
-    out << '\n';
-    ++out.indent_;
-    out << '\t';
+
+    CYCompactType compact(Compact());
+
+    if (compact >= request)
+        out << ' ';
+    else {
+        out << '\n';
+        ++out.indent_;
+        out << '\t';
+    }
+
     Output(out, flags);
-    out << '\n';
-    --out.indent_;
+
+    if (compact < request)
+        --out.indent_;
 }
 
 void CYString::Output(CYOutput &out, CYFlags flags) const {
@@ -747,9 +775,11 @@ const char *CYString::Word() const {
 }
 
 void CYSwitch::Output(CYOutput &out, CYFlags flags) const {
-    out << "switch" << ' ' << '(' << *value_ << ')' << ' ' << '{';
+    out << "switch" << ' ' << '(' << *value_ << ')' << ' ' << '{' << '\n';
+    ++out.indent_;
     out << clauses_;
-    out << '}';
+    --out.indent_;
+    out << '\t' << '}';
 }
 
 void CYThis::Output(CYOutput &out, CYFlags flags) const {
@@ -807,7 +837,7 @@ void CYTypeVoid::Output(CYOutput &out) const {
 }
 
 void CYVar::Output(CYOutput &out, CYFlags flags) const {
-    out << "var";
+    out << "var" << ' ';
     declarations_->Output(out, flags);
     out << ';';
 }
@@ -817,13 +847,13 @@ void CYVariable::Output(CYOutput &out, CYFlags flags) const {
 }
 
 void CYWhile::Output(CYOutput &out, CYFlags flags) const {
-    out << "while" << '(' << *test_ << ')';
-    code_->Single(out, CYRight(flags));
+    out << "while" << ' ' << '(' << *test_ << ')';
+    code_->Single(out, CYRight(flags), CYCompactShort);
 }
 
 void CYWith::Output(CYOutput &out, CYFlags flags) const {
-    out << "with" << '(' << *scope_ << ')';
-    code_->Single(out, CYRight(flags));
+    out << "with" << ' ' << '(' << *scope_ << ')';
+    code_->Single(out, CYRight(flags), CYCompactShort);
 }
 
 void CYWord::ClassName(CYOutput &out, bool object) const {
@@ -836,8 +866,12 @@ void CYWord::ClassName(CYOutput &out, bool object) const {
 
 void CYWord::Output(CYOutput &out) const {
     out << Word();
-    if (out.options_.verbose_)
-        out.out_ << '@' << this;
+    if (out.options_.verbose_) {
+        out('@');
+        char number[32];
+        sprintf(number, "%p", this);
+        out(number);
+    }
 }
 
 void CYWord::PropertyName(CYOutput &out) const {
index 2c534cce50f150d70e6941625a4f8162b2275f29..028ea0cc222dca3b10713805640eee10805e1a57 100644 (file)
@@ -22,8 +22,7 @@
 #ifndef CYCRIPT_PARSER_HPP
 #define CYCRIPT_PARSER_HPP
 
-#include <iostream>
-
+#include <streambuf>
 #include <string>
 #include <vector>
 #include <map>
@@ -47,10 +46,13 @@ struct CYThing {
 };
 
 struct CYOutput {
-    std::ostream &out_;
+    std::streambuf &out_;
+    CYPosition position_;
+
     CYOptions &options_;
     bool pretty_;
     unsigned indent_;
+    unsigned recent_;
     bool right_;
 
     enum {
@@ -61,11 +63,12 @@ struct CYOutput {
         Terminated
     } mode_;
 
-    CYOutput(std::ostream &out, CYOptions &options) :
+    CYOutput(std::streambuf &out, CYOptions &options) :
         out_(out),
         options_(options),
         pretty_(false),
         indent_(0),
+        recent_(0),
         right_(false),
         mode_(NoMode)
     {
@@ -74,6 +77,25 @@ struct CYOutput {
     void Check(char value);
     void Terminate();
 
+    _finline void operator ()(char value) {
+        _assert(out_.sputc(value) != EOF);
+        recent_ = indent_;
+        if (value == '\n')
+            position_.lines(1);
+        else
+            position_.columns(1);
+    }
+
+    _finline void operator ()(const char *data, std::streamsize size) {
+        _assert(out_.sputn(data, size) == size);
+        recent_ = indent_;
+        position_.columns(size);
+    }
+
+    _finline void operator ()(const char *data) {
+        return operator ()(data, strlen(data));
+    }
+
     CYOutput &operator <<(char rhs);
     CYOutput &operator <<(const char *rhs);
 
@@ -145,6 +167,17 @@ _finline CYFlags CYCenter(CYFlags flags) {
     return CYLeft(CYRight(flags));
 }
 
+enum CYCompactType {
+    CYCompactNone,
+    CYCompactLong,
+    CYCompactShort,
+};
+
+#define CYCompact(type) \
+    virtual CYCompactType Compact() const { \
+        return CYCompact ## type; \
+    }
+
 struct CYStatement :
     CYNext<CYStatement>,
     CYThing
@@ -152,12 +185,13 @@ struct CYStatement :
     virtual ~CYStatement() {
     }
 
-    void Single(CYOutput &out, CYFlags flags) const;
+    void Single(CYOutput &out, CYFlags flags, CYCompactType request) const;
     void Multiple(CYOutput &out, CYFlags flags = CYNoFlags) const;
     virtual void Output(CYOutput &out) const;
 
     virtual CYStatement *Replace(CYContext &context) = 0;
 
+    virtual CYCompactType Compact() const = 0;
     virtual CYStatement *Return();
 
   private:
@@ -260,6 +294,8 @@ struct CYComment :
     {
     }
 
+    CYCompact(None)
+
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
@@ -276,6 +312,8 @@ struct CYLabel :
     {
     }
 
+    CYCompact(Short)
+
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
@@ -446,6 +484,8 @@ struct CYBlock :
     {
     }
 
+    CYCompact(Short)
+
     virtual CYStatement *Replace(CYContext &context);
 
     virtual void Output(CYOutput &out, CYFlags flags) const;
@@ -1179,6 +1219,8 @@ struct CYVar :
     {
     }
 
+    CYCompact(None)
+
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
@@ -1195,6 +1237,8 @@ struct CYLetStatement :
     {
     }
 
+    CYCompact(Long)
+
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
@@ -1215,6 +1259,8 @@ struct CYFor :
     {
     }
 
+    CYCompact(Long)
+
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
@@ -1233,6 +1279,8 @@ struct CYForIn :
     {
     }
 
+    CYCompact(Long)
+
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
@@ -1251,6 +1299,8 @@ struct CYForOf :
     {
     }
 
+    CYCompact(Long)
+
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
@@ -1401,6 +1451,8 @@ struct CYIf :
     {
     }
 
+    CYCompact(Long)
+
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 
@@ -1419,6 +1471,8 @@ struct CYDoWhile :
     {
     }
 
+    CYCompact(None)
+
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
@@ -1435,6 +1489,8 @@ struct CYWhile :
     {
     }
 
+    CYCompact(Long)
+
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
@@ -1523,6 +1579,8 @@ struct CYFunctionStatement :
     {
     }
 
+    CYCompact(None)
+
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
@@ -1539,6 +1597,8 @@ struct CYExpress :
             throw;
     }
 
+    CYCompact(None)
+
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 
@@ -1555,6 +1615,8 @@ struct CYContinue :
     {
     }
 
+    CYCompact(Short)
+
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
@@ -1569,6 +1631,8 @@ struct CYBreak :
     {
     }
 
+    CYCompact(Short)
+
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
@@ -1583,6 +1647,8 @@ struct CYReturn :
     {
     }
 
+    CYCompact(None)
+
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
@@ -1590,6 +1656,8 @@ struct CYReturn :
 struct CYEmpty :
     CYStatement
 {
+    CYCompact(Short)
+
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
@@ -1905,6 +1973,8 @@ struct CYImport :
     {
     }
 
+    CYCompact(None)
+
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
@@ -1921,6 +1991,8 @@ struct CYExternal :
     {
     }
 
+    CYCompact(None)
+
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
@@ -1935,6 +2007,8 @@ struct CYTypeDefinition :
     {
     }
 
+    CYCompact(None)
+
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
@@ -2008,6 +2082,8 @@ struct Try :
     {
     }
 
+    CYCompact(Short)
+
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
@@ -2022,6 +2098,8 @@ struct Throw :
     {
     }
 
+    CYCompact(None)
+
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
@@ -2040,6 +2118,8 @@ struct CYWith :
     {
     }
 
+    CYCompact(Long)
+
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
@@ -2056,6 +2136,8 @@ struct CYSwitch :
     {
     }
 
+    CYCompact(Long)
+
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
@@ -2067,6 +2149,8 @@ struct CYDebugger :
     {
     }
 
+    CYCompact(None)
+
     virtual CYStatement *Replace(CYContext &context);
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };