#include <dlfcn.h>
+#ifdef __APPLE__
+#include <mach/mach_time.h>
+#endif
+
#include "Display.hpp"
#include "Driver.hpp"
#include "Highlight.hpp"
-#include "Replace.hpp"
+#include "Parser.hpp"
static volatile enum {
Working,
}
static bool bison_;
+static bool timing_;
static bool strict_;
static bool pretty_;
driver.strict_ = true;
}
-void Setup(CYPool &pool, CYOutput &out, CYDriver &driver, CYOptions &options, bool lower) {
+void Setup(CYOutput &out, CYDriver &driver, CYOptions &options, bool lower) {
out.pretty_ = pretty_;
if (lower)
- driver.Replace(pool, options);
+ driver.Replace(options);
}
static CYUTF8String Run(CYPool &pool, int client, CYUTF8String code) {
code = command_;
else {
std::istringstream stream(command_);
- CYDriver driver(stream);
- Setup(driver);
CYPool pool;
- bool failed(driver.Parse(pool));
+ CYDriver driver(pool, stream);
+ Setup(driver);
+
+ bool failed(driver.Parse());
if (failed || !driver.errors_.empty()) {
for (CYDriver::Errors::const_iterator error(driver.errors_.begin()); error != driver.errors_.end(); ++error) {
goto read;
}
- if (driver.program_ == NULL)
+ if (driver.script_ == NULL)
goto restart;
std::stringbuf str;
CYOutput out(str, options);
- Setup(pool, out, driver, options, lower);
- out << *driver.program_;
+ Setup(out, driver, options, lower);
+ out << *driver.script_;
code = str.str();
}
void InjectLibrary(pid_t, int, const char *const []);
+static uint64_t CYGetTime() {
+#ifdef __APPLE__
+ return mach_absolute_time();
+#else
+ struct timespec spec;
+ clock_gettime(CLOCK_MONOTONIC, &spec);
+ return spec.tv_sec * UINT64_C(1000000000) + spec.tv_nsec;
+#endif
+}
+
int Main(int argc, char * const argv[], char const * const envp[]) {
bool tty(isatty(STDIN_FILENO));
bool compile(false);
options.verbose_ = true;
else if (strcmp(optarg, "bison") == 0)
bison_ = true;
+ else if (strcmp(optarg, "timing") == 0)
+ timing_ = true;
else {
fprintf(stderr, "invalid name for -g\n");
return 1;
_assert(!stream->fail());
}
- CYDriver driver(*stream, script);
- Setup(driver);
+ if (timing_) {
+ std::stringbuf buffer;
+ stream->get(buffer, '\0');
+ _assert(!stream->fail());
+
+ double average(0);
+ int samples(-50);
+ uint64_t start(CYGetTime());
+
+ for (;;) {
+ stream = new std::istringstream(buffer.str());
+
+ CYPool pool;
+ CYDriver driver(pool, *stream, script);
+ Setup(driver);
+
+ uint64_t begin(CYGetTime());
+ driver.Parse();
+ uint64_t end(CYGetTime());
+
+ delete stream;
+
+ average += (end - begin - average) / ++samples;
+
+ uint64_t now(CYGetTime());
+ if (samples == 0)
+ average = 0;
+ else if ((now - start) / 1000000000 >= 1)
+ std::cout << std::fixed << average << '\t' << (end - begin) << '\t' << samples << std::endl;
+ else continue;
+
+ start = now;
+ }
+
+ stream = new std::istringstream(buffer.str());
+ std::cin.get();
+ }
CYPool pool;
- bool failed(driver.Parse(pool));
+ CYDriver driver(pool, *stream, script);
+ Setup(driver);
+
+ bool failed(driver.Parse());
if (failed || !driver.errors_.empty()) {
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) {
+ } else if (driver.script_ != NULL) {
std::stringbuf str;
CYOutput out(str, options);
- Setup(pool, out, driver, options, true);
- out << *driver.program_;
+ Setup(out, driver, options, true);
+ out << *driver.script_;
std::string code(str.str());
if (compile)
std::cout << code;