#include <mach/mach_time.h>
#endif
+#include "Code.hpp"
#include "Driver.hpp"
#include "Error.hpp"
#include "Highlight.hpp"
static std::ostream *out_;
-static void Output(CYUTF8String json, std::ostream *out, bool expand = false) {
+static void Output(CYUTF8String json, std::ostream *out, bool expand = false, bool reparse = false) {
+ CYPool pool;
+
+ if (reparse) do {
+ CYStream stream(json.data, json.data + json.size);
+ CYDriver driver(pool, stream);
+ if (driver.Parse(CYMarkExpression))
+ break;
+ std::stringbuf str;
+ CYOptions options;
+ CYOutput out(str, options);
+ out.pretty_ = true;
+ out << *driver.context_;
+ std::string data(str.str());
+ json = CYPoolUTF8String(pool, data);
+ if (json.size == 0)
+ json.data = NULL;
+ } while (false);
+
const char *data(json.data);
size_t size(json.size);
CYConsoleRemapKeys(vi_movement_keymap);
}
-static void CYOutputRun(const std::string &code, bool expand = false) {
+static void CYOutputRun(const std::string &code, bool expand = false, bool reparse = false) {
CYPool pool;
- Output(Run(pool, client_, code), &std::cout, expand);
+ Output(Run(pool, client_, code), &std::cout, expand, reparse);
}
static void Console(CYOptions &options) {
bool debug(false);
bool expand(false);
bool lower(true);
+ bool reparse(false);
out_ = &std::cout;
} else if (data == "lower") {
lower = !lower;
*out_ << "lower == " << (lower ? "true" : "false") << std::endl;
+ } else if (data == "reparse") {
+ reparse = !reparse;
+ *out_ << "reparse == " << (reparse ? "true" : "false") << std::endl;
}
continue;
std::cout << std::endl;
}
- CYOutputRun(code, expand);
+ CYOutputRun(code, expand, reparse);
}
}
enum CYMark {
CYMarkScript,
CYMarkModule,
+ CYMarkExpression,
};
class _visible CYDriver {
return pool.strndup(utf8.data, utf8.size);
}
+CYUTF8String CYPoolUTF8String(CYPool &pool, CYUTF8String utf8) {
+ return {pool.strndup(utf8.data, utf8.size), utf8.size};
+}
+
+_visible CYUTF8String CYPoolUTF8String(CYPool &pool, const std::string &value) {
+ return {pool.strndup(value.data(), value.size()), value.size()};
+}
+
CYUTF8String CYPoolUTF8String(CYPool &pool, JSContextRef context, JSStringRef value) {
return CYPoolUTF8String(pool, CYCastUTF16String(value));
}
}
void CYObjCDictionary::Output(CYOutput &out, CYFlags flags) const {
- out << '@' << '{' << '}';
+ unsigned count(0);
+ CYForEach (pair, pairs_)
+ ++count;
+ bool large(count > 8);
+
+ out << '@' << '{';
+ if (large) {
+ out << '\n';
+ ++out.indent_;
+ }
+
+ bool comma(false);
+ CYForEach (pair, pairs_) {
+ if (!comma)
+ comma = true;
+ else {
+ out << ',';
+ if (large)
+ out << '\n';
+ else
+ out << ' ';
+ }
+
+ if (large)
+ out << '\t';
+
+ pair->key_->Output(out, CYAssign::Precedence_, CYNoFlags);
+ out << ':' << ' ';
+ pair->value_->Output(out, CYAssign::Precedence_, CYNoFlags);
+ }
+
+ if (large && out.pretty_)
+ out << ',';
+
+ if (large) {
+ out << '\n';
+ --out.indent_;
+ }
+
+ out << '\t' << '}';
}
void CYObjCBlock::Output(CYOutput &out, CYFlags flags) const {
++out.indent_;
out << code_;
--out.indent_;
- out << '\n' << '}';
+ out << '\t' << '}';
}
void CYProtocol::Output(CYOutput &out) const {
case CYMarkModule:
driver.hold_ = yytranslate_(token::MarkModule);
break;
+ case CYMarkExpression:
+ driver.hold_ = yytranslate_(token::MarkExpression);
+ break;
}
};
%start Program
%token MarkModule
%token MarkScript
+%token MarkExpression
%%
Program
: MarkScript Script
| MarkModule Module
+ | MarkExpression Expression[expression] { driver.context_ = $expression; }
;
/* Lexer State {{{ */
bool CYStartsWith(const CYUTF8String &haystack, const CYUTF8String &needle);
const char *CYPoolCString(CYPool &pool, CYUTF8String utf8);
+CYUTF8String CYPoolUTF8String(CYPool &pool, CYUTF8String utf8);
+CYUTF8String CYPoolUTF8String(CYPool &pool, const std::string &value);
+
CYUTF8String CYPoolUTF8String(CYPool &pool, CYUTF16String utf16);
CYUTF16String CYPoolUTF16String(CYPool &pool, CYUTF8String utf8);