From e6e2f0d2a2dd92a29bd1a9025aacb31d95be5762 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Klapka?= Date: Wed, 26 Aug 2020 18:31:40 +0200 Subject: [PATCH] wchar_t -> char; fixed archiving of inputs and lexemes --- debug-js.sh | 4 +- debug.sh | 2 + js/embindings.h | 10 +- release-js.sh | 2 + release.sh | 2 + src/CMakeLists.txt | 17 +- src/archive.cpp | 1330 ++++++++++++++++++++---------------- src/archive.h | 159 ++--- src/bdd.cpp | 72 +- src/bdd.h | 17 +- src/bdd_ext.cpp | 104 +-- src/char_defs.h | 69 ++ src/defs.h | 34 +- src/dict.cpp | 43 +- src/dict.h | 44 +- src/driver.cpp | 148 ++-- src/driver.h | 103 +-- src/err.h | 121 ++-- src/input.cpp | 738 +++++++++++--------- src/input.h | 282 +++++--- src/main.cpp | 53 +- src/memory_map.h | 83 +-- src/options.cpp | 304 ++++----- src/options.h | 170 ++--- src/output.cpp | 421 +++++++----- src/output.h | 126 ++-- src/print_prolog.cpp | 137 ++-- src/print_souffle.cpp | 125 ++-- src/proof.cpp | 15 +- src/repl.cpp | 301 ++++---- src/repl.h | 74 +- src/save_csv.cpp | 19 +- src/tables.cpp | 342 +++++----- src/tables.h | 49 +- src/tables_ext.cpp | 68 +- src/term.h | 3 +- src/transform.cpp | 120 ++-- src/tree.cpp | 6 +- src/udp.h | 18 +- src/utils.cpp | 26 +- tests/archive.test.cpp | 240 +++---- tests/archive.test.data.h | 558 ++++++--------- tests/archive.test.sh | 6 +- tests/bdd.test.cpp | 30 +- tests/input.test.cpp | 90 +++ tests/input.test.file | 3 + tests/input.test.sh | 16 + tests/memory_map.test.cpp | 28 +- tests/memory_map.test.sh | 2 + tests/output.test.cpp | 122 ++-- tests/parse_error.test.cpp | 121 ++-- tests/parse_error.test.sh | 2 + tests/query.test.cpp | 26 +- tests/simple_test.h | 42 +- tests/test_input.cpp | 16 +- 55 files changed, 3832 insertions(+), 3231 deletions(-) create mode 100644 src/char_defs.h create mode 100644 tests/input.test.cpp create mode 100644 tests/input.test.file create mode 100755 tests/input.test.sh diff --git a/debug-js.sh b/debug-js.sh index cdf3f37f..8d5901ce 100755 --- a/debug-js.sh +++ b/debug-js.sh @@ -1,2 +1,4 @@ +#!/bin/bash + ./build.sh Debug -DBUILD_JSLIB=1 $@ -cp js/test.html js/tmljs build-Debug/ \ No newline at end of file +cp js/test.html js/tmljs build-Debug/ diff --git a/debug.sh b/debug.sh index 00e532ed..37fa1694 100755 --- a/debug.sh +++ b/debug.sh @@ -1 +1,3 @@ +#!/bin/bash + ./build.sh Debug $@ diff --git a/js/embindings.h b/js/embindings.h index 37397f50..19ba0cd9 100644 --- a/js/embindings.h +++ b/js/embindings.h @@ -32,9 +32,9 @@ EMSCRIPTEN_BINDINGS(tml) { .class_function("gc", &bdd::gc) ; class_("driver") - .constructor() + .constructor() .class_function("create", - optional_override([](std::wstring s, options o) { + optional_override([](string_t s, options o) { return new driver(s, o); }), allow_raw_pointers()) .class_function("create", @@ -77,7 +77,7 @@ EMSCRIPTEN_BINDINGS(tml) { .function("get_bool", &options::get_bool) .function("get_string", &options::get_string) .function("to_string", optional_override([](options& o) { - std::wstringstream wss; wss << o; + ostringstream_t wss; wss << o; return wss.str(); }), allow_raw_pointers()) ; @@ -85,8 +85,8 @@ EMSCRIPTEN_BINDINGS(tml) { .function("name", &output::name) .function("type", &output::type) //.function("os", &output::os) - .function("target", select_overload(&output::target), allow_raw_pointers()) - //.function("set_target", select_overload(&output::target)) + .function("target", select_overload(&output::target), allow_raw_pointers()) + //.function("set_target", select_overload(&output::target)) //.function("target", &output::target) .function("read", &output::read) .function("is_null", &output::is_null) diff --git a/release-js.sh b/release-js.sh index 4b5c8018..84069d5e 100755 --- a/release-js.sh +++ b/release-js.sh @@ -1,2 +1,4 @@ +#!/bin/bash + ./build.sh Release -DBUILD_JSLIB=1 $@ cp js/test.html js/tmljs build-Release/ diff --git a/release.sh b/release.sh index 9fd2560b..16a110e6 100755 --- a/release.sh +++ b/release.sh @@ -1 +1,3 @@ +#!/bin/bash + ./build.sh Release $@ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4b8f6d1f..ec73b47b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -87,6 +87,9 @@ target_include_directories(TMLo PUBLIC if (WITH_THREADS) target_compile_definitions(TMLo PRIVATE "-DWITH_THREADS") endif () +if (WITH_WCHAR) + target_compile_definitions(TMLo PRIVATE "-DWITH_WCHAR") +endif () # boost ########### @@ -99,6 +102,13 @@ if (WITH_BOOST) endif (Boost_FOUND) endif () +# pthreads +########### +if (WITH_THREADS) + set(THREADS_PREFER_PTHREAD_FLAG ON) + find_package(Threads) +endif() + # shared library ################# @@ -146,7 +156,9 @@ if (WITH_THREADS) target_compile_definitions(tml PRIVATE "-DWITH_THREADS") target_link_libraries(tml Threads::Threads) endif() - +if (WITH_WCHAR) + target_compile_definitions(tml PRIVATE "-DWITH_WCHAR") +endif () # executable using shared library ################################## @@ -161,6 +173,9 @@ if (WITH_THREADS) target_compile_definitions(tml_shared PRIVATE "-DWITH_THREADS") target_link_libraries(tml_shared Threads::Threads) endif() +if (WITH_WCHAR) + target_compile_definitions(tml_shared PRIVATE "-DWITH_WCHAR") +endif () exclude(tml_shared) diff --git a/src/archive.cpp b/src/archive.cpp index 131091cc..d2db74dd 100644 --- a/src/archive.cpp +++ b/src/archive.cpp @@ -13,39 +13,80 @@ #include "archive.h" #include "input.h" #include "options.h" -#include "types.h" +#include "err.h" -using std::wstring; using std::endl; +//#define DEBUG_ARCHIVE_POS +#ifdef DEBUG_ARCHIVE_POS +#define POS(x) pos(x); +#define SPOS(x, v) spos((x), (v), s); +#define SPOS0(x) spos((x), (char)0, s); +#define SPOSL(x, l) sposl((x), (l), s); +//#define SPOS(x) spos((x), (size_t)-1, s); +#else +#define POS(x) +#define SPOS(x, v) +#define SPOS0(x) +#define SPOSL(x, l) +#endif + +archive::archive(type typ, const std::string& filename, size_t s, bool mm_write) + : type_(typ), mm_(filename, s, bool2mode(mm_write)), data_(mm_.data()), + size_(s) +{ + if (mm_.error) throw_runtime_error(err_fnf, filename); +} + unsigned char archive::enc_bools(std::initializer_list list) { DBG(assert(list.size() <= 8);) unsigned char i = 0, r = 0; for (auto b : list) r |= (unsigned char) (b << i++); return r; } + bool archive::dec_bool(unsigned char bls, int pos) { return (bls >> pos) & 1; } -void archive::write(const char* data, size_t s) { - // DBG(o::dbg() << L"write const char* data[0]: " << &data << L' ' << (int)data[0] << std::endl;) +archive& archive::write(const char* data, size_t s) { + // DBG(o::dbg() << "write const char* data[0]: " << &data << ' ' << (int)data[0] << std::endl;) memcpy(((char*)data_) + pos_, data, s); pos_ += s; + return *this; } -void archive::read(char* data, size_t s) { - // o::dbg() << L"read char* data: " << &data << std::endl; +archive& archive::read(char* data, size_t s) { + // o::dbg() << "read char* data: " << &data << std::endl; memcpy(data, ((char*)data_) + pos_, s); pos_ += s; + return *this; +} + +archive& archive::write(const void* data, size_t s) { + // DBG(o::dbg() << "write const void* data: " << &data << ' ' << data << std::endl;) + return write(static_cast(data), s); +} +archive& archive::read(void* data, size_t s) { + // o::dbg() << "read void* data: " << &data << std::endl; + return read(static_cast(data), s); } -void archive::write(const void* data, size_t s) { - // DBG(o::dbg() << L"write const void* data: " << &data << L' ' << data << std::endl;) - write(static_cast(data), s); +// arrays +template +archive& archive::operator<<(const std::array& a) { + for (auto m : a) *this << m; + return *this; +} +template +archive& archive::operator>>(std::array& a) { + for (size_t i = 0; i != N; ++i) *this >> a[i]; + return *this; } -void archive::read(void* data, size_t s) { - // o::dbg() << L"read void* data: " << &data << std::endl; - read(static_cast(data), s); +template +size_t archive::size(const std::array& a) { + size_t s = sizeof(size_t); + for (auto e : a) s += size(e); + return s; } // vectors @@ -84,8 +125,8 @@ archive& archive::operator>>(std::set& v) { archive& archive::operator>>(std::set &st) { size_t s; *this >> s; for(size_t i = 0; i != s; ++i) { - o::dbg() << L"i: " << i << L" "; - term t(0, {}, {}); + //DBG(o::dbg() << "i: " << i << " ";) + term t; *this >> t, st.insert(t); }; return *this; @@ -110,16 +151,6 @@ size_t archive::setsize(const std::set& v) { for (auto e : v) s += size(e); return s; } -//size_t archive::size(const std::set& lxms) { -// size_t s = sizeof(size_t); -// for (auto l : lxms) s += l.size() + sizeof(size_t); -// return s; -//} -//size_t archive::size(const std::set& lxms) { -// size_t s = sizeof(size_t); -// for (auto l : lxms) s += l.size() + sizeof(size_t); -// return s; -//} // maps template @@ -176,7 +207,7 @@ archive& archive::operator>>(std::map>& mhits) { if (nsize) do { *this >> nt >> tsize; if (tsize) do { - term t = {0, {}, {}}; + term t; *this >> t; st.insert(t); } while (tsize-- > 0); @@ -184,61 +215,7 @@ archive& archive::operator>>(std::map>& mhits) { } while (--nsize > 0); return *this; } -archive& archive::operator>>(std::map>& minvtyps) { - size_t nsize, ssize; - *this >> nsize; - std::set saa; - if (nsize) do { - multi_arg ma(0, 0, {}); - *this >> ma >> ssize; - if (ssize) do { - alt_arg aa(0, 0, 0, 0); - *this >> aa; - saa.insert(aa); - } while (ssize-- > 0); - minvtyps.emplace(ma, saa); - } while (--nsize > 0); - return *this; -} -archive& archive::operator>>(std::map>& tblbodies) { - size_t nsize, ssize; - ntable nt; - *this >> nsize; - std::set sta; - if (nsize) do { - *this >> nt >> ssize; - if (ssize) do { - tbl_alt ta = tbl_alt::get_empty(); - *this >> ta; - sta.insert(ta); - } while (ssize-- > 0); - tblbodies.emplace(nt, sta); - } while (--nsize > 0); - return *this; -} -archive& archive::operator>>(std::map& mtyps) { - size_t nsize; - *this >> nsize; - if (nsize) do { - alt_arg aa(0, 0, 0, 0); - multi_arg ma(0, 0, {}); - *this >> aa >> ma; - mtyps.emplace(aa, ma); - } while (--nsize > 0); - return *this; -} -archive& archive::operator>>(std::map& altordermap) { - size_t nsize; - *this >> nsize; - if (nsize) do { - tbl_alt k = tbl_alt::get_empty(); - tbl_alt v = tbl_alt::get_empty(); - *this >> k >> v; - altordermap.emplace(k, v); - } while (--nsize > 0); - return *this; -} template size_t archive::mapsize(const std::map& m) { size_t s = sizeof(size_t); @@ -273,84 +250,86 @@ size_t archive::header_size() { } archive& archive::operator<<(const int_t& val) { - //DBG(o::dbg() << L"writing int_t: " << val << endl;) + //DBG(o::dbg() << "writing int_t: " << val << endl;) write((const char*)&val, sizeof(int_t)); return *this; } archive& archive::operator>>(int_t& val) { read(&val, sizeof(int_t)); - //DBG(o::dbg() << L"reading int_t: " << val << endl;) + //DBG(o::dbg() << "reading int_t: " << val << endl;) return *this; } archive& archive::operator<<(const int16_t& val) { - //DBG(o::dbg() << L"writing int16_t: " << val << endl;) - write((const char*)&val, sizeof(int16_t)); + //DBG(o::dbg() << "writing int16_t: " << val << endl;) + write((const char*) &val, sizeof(int16_t)); return *this; } archive& archive::operator>>(int16_t& val) { read(&val, sizeof(int16_t)); - //DBG(o::dbg() << L"reading int16_t: " << val << endl;) + //DBG(o::dbg() << "reading int16_t: " << val << endl;) return *this; } archive& archive::operator<<(const size_t& val) { - // DBG(o::dbg() << L"writing size_t: " << val << endl;) - write((const char*)&val, sizeof(size_t)); + // DBG(o::dbg() << "writing size_t: " << val << endl;) + write((const char*) &val, sizeof(size_t)); return *this; } archive& archive::operator>>(size_t& val) { - read((char*)&val, sizeof(size_t)); - // DBG(o::dbg() << L"reading size_t: " << val << endl;) + read((char*) &val, sizeof(size_t)); + // DBG(o::dbg() << "reading size_t: " << val << endl;) return *this; } archive& archive::operator<<(const unsigned int& val) { - //DBG(o::dbg() << L"writing uint: " << val << endl;) - write((const char*)&val, sizeof(unsigned int)); + //DBG(o::dbg() << "writing uint: " << val << endl;) + write((const char*) &val, sizeof(unsigned int)); return *this; } archive& archive::operator>>(unsigned int& val) { read(&val, sizeof(unsigned int)); - //DBG(o::dbg() << L"reading uint: " << val << endl;) + //DBG(o::dbg() << "reading uint: " << val << endl;) return *this; } archive& archive::operator<<(const unsigned char& val) { - // DBG(o::dbg() << L"writing char: " << val << endl;) - write((const char*)(&val), sizeof(unsigned char)); + // DBG(o::dbg() << "writing char: " << val << endl;) + write((const char*) &val, sizeof(unsigned char)); return *this; } archive& archive::operator>>(unsigned char& val) { read(&val, sizeof(unsigned char)); - // DBG(o::dbg() << L"reading char: " << val << endl;) + // DBG(o::dbg() << "reading char: " << val << endl;) return *this; } archive& archive::operator<<(const char& val) { - // DBG(o::dbg() << L"writing char: " << val << endl;) - write((const char*)(&val), sizeof(char)); + // DBG(o::dbg() << "writing char: " << val << endl;) + write((const char*) &val, sizeof(char)); return *this; } archive& archive::operator>>(char& val) { read(&val, sizeof(char)); - // DBG(o::dbg() << L"reading char: " << val << endl;) + // DBG(o::dbg() << "reading char: " << val << endl;) return *this; } archive& archive::operator<<(const lexeme& val) { - // DBG(o::dbg() << L"writing lexeme: " << lexeme2str(val) << endl;) - return *this << std::wstring(val[0], val[1]-val[0]); +// //DBG(o::dbg() << "writing lexeme: " << lexeme2str(val) << endl;) + auto it = lmap_.find(val); + if (it == lmap_.end()) throw 0; + return *this << it->second; } archive& archive::operator>>(lexeme& r) { - std::wstring s; - *this >> s; - r = get_dict()->get_lexeme(s); + size_t pos; + *this >> pos; r[0] = (ccs) data_ + pos; + *this >> pos; r[1] = (ccs) data_ + pos; return *this; } -size_t archive::size(const lexeme& l) { - return l[1] - l[0] + sizeof(size_t); +size_t archive::size(const lexeme& /*l*/) { + return 2 * sizeof(size_t); } archive& archive::operator<<(const lexeme_range& r) { @@ -360,101 +339,37 @@ archive& archive::operator>>(lexeme_range& r) { return *this >> r[0] >> r[1]; } -archive& archive::operator<<(const std::wstring& val) { - // DBG(o::dbg() << L"writing wstring: " << val << endl;) - return *this << ws2s(val); -} -archive& archive::operator>>(std::wstring& val) { - std::string s; *this >> s; val = s2ws(s); - return *this; -} - archive& archive::operator<<(const std::string& val) { - // DBG(o::dbg() << L"writing string: " << s2ws(val) - // << L" size: " << val.size() << endl;) + //COUT << "writing string: " << val + // << " size: " << val.size() << endl; + //POS("string begin") *this << val.size(); - write((const char*)val.c_str(), val.size()); + if (val.size() > 0) write((const char*)val.c_str(), val.size()); + *this << (char)0; + //POS("string end") return *this; } archive& archive::operator>>(std::string& val) { - size_t s; *this >> s; - //DBG(o::dbg() << L"reading string, size: " << s << endl;) - if (s == 0) { - val = ""; - return *this; - } - char* str = new char[s+1]; str[s] = 0x0; // ??? - read(str, s); - val = std::string(str); - //DBG(o::dbg() << L"reading string, value: " << s2ws(val) << endl;) + //POS("string begin") + size_t l; *this >> l; + //DBG(o::dbg() << "reading string, size: " << l << endl;) + if (l == 0) return (val = "", ++pos_), *this; + val = std::string(read_ccs(l)); + //POS("string end") return *this; } archive& archive::operator<<(const spbdd_handle& val) { - //DBG(o::dbg() << L"writing spbdd_handle: " << (val ? val->b : (int_t)0) << endl;) + //DBG(o::dbg() << "writing spbdd_handle: " << (val ? val->b : (int_t)0) << endl;) return *this << (val ? val->b : (int_t)0); } archive& archive::operator>>(spbdd_handle& val) { int_t b; *this >> b; val = bdd_handle::get(b); - //DBG(o::dbg() << L"reading spbdd_handle: " << b << endl;) + //DBG(o::dbg() << "reading spbdd_handle: " << b << endl;) return *this; } -archive& archive::operator<<(const dict_t& d) { - std::wostringstream data; - std::map lmap{}; - std::vector lranges; - size_t pos = 0; - auto add_lexeme_and_map = - [&data, &lmap, &lranges, &pos] (const lexeme& l) { - lexeme_range r = { pos, pos }; - auto it = lmap.find(l); - if (it == lmap.end()) { // not in map - if (l[1]-l[0] > 0) // non-0 - for (cws c = l[0]; c != l[1]; ++c) - data << *c, ++pos, r[1] = pos; - lmap.insert({ l, r }); - lranges.push_back(r); - } else lranges.push_back(it->second); - }; - for (auto& v : {d.rels, d.syms, d.bltins}) - for (auto& l : v) add_lexeme_and_map(l); - *this << ws2s(data.str()) << d.rels_dict.size() << d.syms_dict.size() - << d.bltins_dict.size(); - for (auto& r : lranges) *this << r; - write_container(d.types); - return *this; -} -archive& archive::operator>>(dict_t& d) { - size_t nrels, nsyms, nbltins; - // TODO: don't allocate. use mmap addresses (switch from wchar first?) - std::string s; *this >> s; cws source = wcsdup(s2ws(s).c_str()); - *this >> nrels >> nsyms >> nbltins; - lexeme_range r; - for (size_t i = 0; i != nrels; ++i) *this >> r, - d.get_rel(lexeme{ source+r[0], source+r[1] }); - for (size_t i = 0; i != nsyms; ++i) *this >> r, - d.get_sym(lexeme{ source+r[0], source+r[1] }); - for (size_t i = 0; i != nbltins; ++i) *this >> r, - d.get_bltin(lexeme{ source+r[0], source+r[1] }); - return *this >> d.types; -} -size_t archive::size(const dict_t& d) { - size_t s = (4 * sizeof(size_t)) + size(d.types) - + (2 * sizeof(size_t) - * (d.rels.size() + d.syms.size() + d.bltins.size())); - std::set lexemes{}; - auto add_lexeme_size = - [&lexemes, &s] (const lexeme& l) { - if (lexemes.insert(l).second) s += l[1]-l[0]; - }; - for (auto& l : d.rels) add_lexeme_size(l); - for (auto& l : d.syms) add_lexeme_size(l); - for (auto& l : d.bltins) add_lexeme_size(l); - return s; -} - archive& archive::operator<<(const term& t) { *this << t.tab << (unsigned char)t.extype; if (t.extype == term::ARITH) *this << (unsigned char) t.arith_op; @@ -505,187 +420,13 @@ size_t archive::size(const sig& sign) { return (sign.second.size() + 1) * sizeof(int_t) + sizeof(size_t); } -archive& archive::operator<<(const alt_arg& a) { - return *this << a.tab << a.alt - << a.arg << a.subarg << a.path - << (unsigned char)a.special; -} -archive& archive::operator>>(alt_arg& a) { - unsigned char tmp; - *this - >> a.tab - >> a.alt - >> a.arg - >> a.subarg - >> a.path - >> tmp; - a.special = (decltype(a.special)) tmp; - return *this; -} -size_t archive::size(const alt_arg& a) { - return 3 * sizeof(int_t) + ((a.path.size() + 2) * sizeof(size_t)) - + sizeof(unsigned char); -} - -archive& archive::operator<<(const tbl_arg& a) { - return *this << a.tab << a.arg << a.subarg; -} -archive& archive::operator>>(tbl_arg& a) { - return *this >> a.tab >> a.arg >> a.subarg; -} -size_t archive::size(const tbl_arg&) { - return 2 * sizeof(int_t) + sizeof(size_t); -} - -archive& archive::operator<<(const multi_arg& a) { - return *this << a.tab << a.arg << a.subarg << a.path - << (unsigned char)a.special; -} -archive& archive::operator>>(multi_arg& a) { - unsigned char tmp; - *this >> a.tab >> a.arg >> a.subarg >> a.path >> tmp; - a.special = (decltype(a.special)) tmp; - return *this; -} -size_t archive::size(const multi_arg& a) { - return 2 * sizeof(int_t) + ((a.path.size() + 2) * sizeof(size_t)) - + sizeof(unsigned char); -} - -archive& archive::operator<<(const infer_types& inf) { - return *this - << inf.minvtyps - << inf.mtyps - << inf.altids4types - << inf.tblbodies - << inf.tblrules - << inf.altordermap - //<< inf.altsmap - ; -} -archive& archive::operator>>(infer_types& inf) { - return *this - >> inf.minvtyps - >> inf.mtyps - >> inf.altids4types - >> inf.tblbodies - >> inf.tblrules - >> inf.altordermap - // >> inf.altsmap - ; -} -size_t archive::size(const infer_types& inf) { - return size(inf.minvtyps) + size(inf.mtyps) + size(inf.altids4types) - + size(inf.tblbodies) + size(inf.tblrules) - + size(inf.altordermap) ;//+ size(inf.altsmap); -} - -archive& archive::operator<<(const compound_type& ct) { - *this - << enc_bools({ ct.isroot, ct.bitaligned }) - << ct.alignment // only if bitaligned? - << ct.sumOfBits << ct.sumOfPrimitives // mutable - ; - return write_container(ct.types); - // static align_bits bool -} -archive& archive::operator>>(compound_type& ct) { - unsigned char bls; - *this >> bls >> ct.alignment >> ct.sumOfBits >> ct.sumOfPrimitives; - ct.isroot = dec_bool(bls), ct.bitaligned = dec_bool(bls, 1); - return *this >> ct.types; -} -size_t archive::size(const compound_type& ct) { - return sizeof(unsigned char) + size(ct.alignment) - + 2 * sizeof(size_t) + size(ct.types); -} - -archive& archive::operator<<(const primitive_type& pt) { - return *this << (unsigned char) pt.type << pt.bitness << pt.num; -} -archive& archive::operator>>(primitive_type& pt) { - unsigned char t; - *this >> t >> pt.bitness >> pt.num; - pt.type = (base_type)t; - return *this; -} -size_t archive::size(const primitive_type&) { - return sizeof(unsigned char) + sizeof(size_t) + sizeof(int_t); -} - -archive& archive::operator<<(const ::type& at) { - *this - << at.sig - << at.mprimes - << (unsigned char) at.kind; - if (at.isPrimitive()) *this << at.primitive; - else if (at.isCompound()) *this << at.compound; - return *this; -} -archive& archive::operator>>(::type& at) { - unsigned char tmp; - *this - >> at.sig - >> at.mprimes - >> tmp; - at.kind = static_cast(tmp); - if (at.isPrimitive()) *this >> at.primitive; - else if (at.isCompound()) *this >> at.compound; - return *this; -} -size_t archive::size(const ::type& at) { - size_t s = size(at.sig) + size(at.mprimes) + sizeof(unsigned char); - if (at.isPrimitive()) s += size(at.primitive); - else if (at.isCompound()) s += size(at.compound); - return s; -} - -archive& archive::operator<<(const bitsmeta& bm) { - write_container>(bm.types) - << bm.vargs - << bm.vbits - << bm.nterms - << bm.args_bits - << bm.maxbits - << bm.mleftbits - << bm.mleftargs - << enc_bools({ bm.bitsfixed, bm.hasmultivals, bm.fromheader }); - return *this; -} -archive& archive::operator>>(bitsmeta& bm) { - char bls; - *this - >> bm.types - >> bm.vargs - >> bm.vbits - >> bm.nterms - >> bm.args_bits - >> bm.maxbits - >> bm.mleftbits - >> bm.mleftargs - >> bls; - bm.bitsfixed = dec_bool(bls), - bm.hasmultivals = dec_bool(bls, 1), - bm.fromheader = dec_bool(bls, 2); - return *this; -} -size_t archive::size(const bitsmeta& bm) { - size_t s = size(bm.types) - + 3 * sizeof(size_t) - + size(bm.vargs) + size(bm.vbits) - + size(bm.mleftbits) - + sizeof(unsigned char) - + sizeof(size_t); - for (auto m : bm.mleftargs) s += sizeof(size_t) + size(m.second); - return s; -} - archive& archive::operator<<(const elem& e) { *this << (unsigned char)e.type; switch (e.type) { case elem::ARITH: *this << (unsigned char)e.arith_op; break; case elem::NUM: *this << e.num; break; - case elem::CHR: *this << (unsigned int)e.ch; break; // TODO save char as utf8 string? + case elem::CHR: *this << (unsigned int)e.ch; break; + case elem::SYM: case elem::STR: case elem::VAR: *this << e.e; default:; @@ -693,15 +434,15 @@ archive& archive::operator<<(const elem& e) { return *this; } archive& archive::operator>>(elem& e) { - wstring s; unsigned int ch; unsigned char tmp; *this >> tmp, e.type = (elem::etype)tmp; switch (e.type) { case elem::ARITH: *this>>tmp, e.arith_op=(t_arith_op)tmp; break; case elem::NUM: *this >> e.num; break; - case elem::CHR: *this >> ch, e.ch = (wchar_t)ch; break; + case elem::CHR: *this >> ch, e.ch = (char)ch; break; + case elem::SYM: case elem::STR: - case elem::VAR: *this >> s, e.e = get_dict()->get_lexeme(s); + case elem::VAR: *this >> e.e; break; default:; } @@ -713,8 +454,9 @@ size_t archive::size(const elem& e) { case elem::ARITH: s += sizeof(unsigned char); break; case elem::NUM: s += sizeof(int_t); break; case elem::CHR: s += sizeof(unsigned int); break; + case elem::SYM: case elem::STR: - case elem::VAR: s += size(e.e); break; + case elem::VAR: s += 2 * sizeof(size_t); break; default:; } return s; @@ -746,8 +488,7 @@ archive& archive::operator<<(const directive& d) { } archive& archive::operator>>(directive& d) { *this >> d.rel; - wstring s; *this >> s; - d.arg = get_dict()->get_lexeme(s); + *this >> d.arg; return *this >> d.t; } size_t archive::size(const directive& d) { @@ -777,18 +518,45 @@ size_t archive::size(const raw_rule& r) { return s; } archive& archive::operator<<(const raw_prog& rp) { - return *this << rp.d << rp.g << rp.r << rp.builtins; + //POS("rp.d") + *this << rp.d; + //POS("rp.g") + *this << rp.g; + //POS("rp.r") + *this << rp.r; + //POS("rp.builtins") + *this << rp.builtins; + //POS("rp end") + return *this; } archive& archive::operator>>(raw_prog& rp) { size_t nsize; - wstring s; - *this >> rp.d >> rp.g >> rp.r >> nsize; + lexeme l; + //POS("rp.d") + *this >> rp.d; + //POS("rp.g") + *this >> rp.g; + //POS("rp.r") + *this >> rp.r; + //POS("rp.builtins size") + *this >> nsize; + //POS("rp.builtins pairs") for (size_t i = 0; i != nsize; ++i) - *this >> s, rp.builtins.insert(get_dict()->get_lexeme(s)); + *this >> l, rp.builtins.insert(l); + //POS("rp end") return *this; } size_t archive::size(const raw_prog& rp) { - return size(rp.d) + size(rp.g) + size(rp.r) + size(rp.builtins); + size_t s = 0; + //SPOS("rp.d", rp.d) + s += size(rp.d); + //SPOS("rp.g", rp.g) + s += size(rp.g); + //SPOS("rp.r", rp.r) + s += size(rp.r); + //SPOS("rp.builtins", rp.builtins) + s += size(rp.builtins); + return s; } archive& archive::operator<<(const raw_progs& rps) { @@ -800,14 +568,68 @@ archive& archive::operator>>(raw_progs& rps) { size_t archive::size(const raw_progs& rps) { return size(rps.p); } + +archive& archive::write_ccs(const char* s, size_t l) { + *this << l; write(s, l); + return *this; +} + +archive& archive::write_ccs(const char* s) { + size_t l = strlen(s); + return write_ccs(s, l); +} + +ccs archive::read_ccs(size_t l) { + ccs s = (ccs)data_ + pos_; + //POS("read_chars") + pos_ += l * sizeof(char) + 1; + //POS("chars read") + return s; +} + +archive& archive::operator<<(const input& in) { + //POS("input bools") + *this << enc_bools({ in.newseq }); + //POS("input data") + //COUT << "writing in.beg_: " << (void*)in.beg_ << " " << in.beg_ << endl; + write_ccs(in.beg_); + *this << '\0'; + //POS("input end") + return *this; +} +archive& archive::operator>>(input& in) { + unsigned char tmp; + //POS("input bools") + *this >> tmp; in.newseq = dec_bool(tmp); + in.allocated_ = false; + //POS("input data") + *this >> in.size_; + in.beg_ = read_ccs(in.size_); + //COUT << "loading in.size_: " << in.size_ << " in.beg_: " << (void*)in.beg_ << " " << in.beg_ << endl; + in.data_ = in.beg_; + //POS("input end") + return *this; +} +size_t archive::size(const input& in) { + return 2 * sizeof(unsigned char) + + + sizeof(size_t) + + strlen(in.beg_); +} + archive& archive::operator<<(const option& o) { - *this << (unsigned char)o.t << o.n[0]; + //POS("option type") + *this << (unsigned char)o.t; + //POS("option name") + *this << o.n[0]; + //COUT << "option name written: " << o.n[0] << " type: " << (int_t) o.t << endl; + //POS("option value") switch (o.t) { case option::type::INT: *this << o.v.v_i; break; case option::type::BOOL: *this << enc_bools({ o.v.v_b }); break; case option::type::STRING: *this << o.v.v_s; break; default: ; } + //POS("option end") return *this; } size_t archive::size(const option& o) { @@ -823,56 +645,99 @@ size_t archive::size(const option& o) { archive& archive::operator<<(const options& o) { size_t n = 0; + //POS("options size") for (auto it : o.opts) if (!it.second.is_undefined()) n++; *this << n; + //POS("option pairs") for (auto it : o.opts) if (!it.second.is_undefined()) *this<>(options& opts) { size_t nsize; + //POS("options size") *this >> nsize; + //POS("option pairs") for (size_t i = 0; i != nsize; ++i) { int_t val; - wstring ws, n; + std::string s, n; unsigned char uch; - *this >> uch >> n; + //POS("option start: type[1]") + *this >> uch; + //POS("option name"); + *this >> n; + //COUT << "name: " << n << " type: " << (int_t)uch << endl; // option o; opts.get(n, o); + //POS("option value") switch ((option::type) uch) { case option::type::INT: - *this >> val; opts.set(n, val); break; + *this >> val; opts.set(n, val); + //COUT << "int written: " << val << endl; + break; case option::type::BOOL: *this >> uch; opts.set(n, dec_bool(uch)); + //COUT << "bool read: " << dec_bool(uch) << endl; break; case option::type::STRING: - *this >> ws; opts.set(n, ws); break; + *this >> s; opts.set(n, s); + //COUT << "string read: " << s << endl; + break; default: throw 0; } + //POS("option end") } return *this; } size_t archive::size(const options& opts) { - size_t s = sizeof(size_t); - for (auto it : opts.opts) if (!it.second.is_undefined()) + size_t s = 0; + //SPOS("options size", s); + s += sizeof(size_t); + for (auto it : opts.opts) if (!it.second.is_undefined()) { + //SPOS("option pair", it.second) s += size(it.second); + } + //SPOS0("options end") return s; } archive& archive::operator<<(const prog_data& pd) { - return *this - << pd.strs - << enc_bools({ pd.bwd }) - << pd.n - << pd.start_step - << pd.elapsed_steps; + //POS("std_input") + *this << pd.std_input; + //POS("pd.strs") + *this << pd.strs; + //POS("pd.bools (bwd)") + *this << enc_bools({ pd.bwd }); + //POS("pd.n") + *this << pd.n; + //POS("pd.start_step") + *this << pd.start_step; + //POS("pd.elapsed_steps") + *this << pd.elapsed_steps; + //POS("pd end") + return *this; } archive& archive::operator>>(prog_data& pd) { unsigned char bls; - *this >> pd.strs >> bls; + //POS("pd.std_input") + *this >> pd.std_input; + //POS("pd.strs") + *this >> pd.strs; + //POS("pd.bools (bwd)") + *this >> bls; pd.bwd = dec_bool(bls); - return *this >> pd.n >> pd.start_step >> pd.elapsed_steps; + //POS("pd.n") + *this >> pd.n; + //POS("pd.start_step") + *this >> pd.start_step; + //POS("pd.elapsed_steps") + *this >> pd.elapsed_steps; + //POS("pd end") + return *this; } size_t archive::size(const prog_data& pd) { - return size(pd.strs) + sizeof(unsigned char) + 3 * sizeof(size_t); + return size(pd.strs) + size(pd.std_input) + + sizeof(unsigned char) + + 3 * sizeof(size_t); } archive& archive::operator<<(const strs_t& strs) { @@ -900,9 +765,7 @@ archive& archive::operator>>(flat_prog& fp) { std::vector vt{}; *this >> tsize; if (tsize) do { - term t = {0, {}, {}}; - *this >> t; - vt.push_back(t); + term t; *this >> t; vt.push_back(t); } while (tsize-- > 0); fp.insert(vt); } while (--nsize > 0); @@ -915,234 +778,533 @@ size_t archive::size(const flat_prog& fp) { } archive& archive::operator<<(const table& t) { - *this - << t.sign - << t.bm - << t.tq - << t.len - << t.priority - << t.r - << enc_bools({ t.ext, t.unsat, t.tmp }) - << t.idbltin - << t.bltinargs - << t.bltinsize; + //POS("table signature") + *this << t.s; + //POS("table t") + *this << t.t; + //POS("table len") + *this << t.len; + //POS("table priority") + *this << t.priority; + //POS("table r") + *this << t.r; + //POS("table bools(ext, unsat, tmp)") + *this << enc_bools({ t.ext, t.unsat, t.tmp }); + //POS("table idbltin") + *this << t.idbltin; + //POS("table bltinargs") + *this << t.bltinargs; + //POS("table bltinsize") + *this << t.bltinsize; + //POS("table end") return *this; } archive& archive::read_table(tables& tbls) { char bls; sig s; - bitsmeta bm; - if (!dict) dict = &tbls.dict; - *this - >> s - >> bm; - ntable nt = tbls.get_table(s, bm.types); - table& t = tbls.tbls[nt]; - t.bm = bm; - *this - >> t.tq - >> t.len - >> t.priority - >> t.r - >> bls - >> t.idbltin - >> t.bltinargs - >> t.bltinsize - ; + if (!dict_) dict_ = &tbls.dict; + //POS("table signature") + *this >> s; + //POS("table t") + table& t = tbls.tbls[tbls.get_table(s)]; + *this >> t.t; + //POS("table len") + *this >> t.len; + //POS("table priority") + *this >> t.priority; + //POS("table r") + *this >> t.r; + //POS("table bools(ext, unsat, tmp)") + *this >> bls; t.ext = dec_bool(bls), t.unsat = dec_bool(bls, 1), t.tmp = dec_bool(bls, 2); + //POS("table idbltin") + *this >> t.idbltin; + //POS("table bltinargs") + *this >> t.bltinargs; + //POS("table bltinsize") + *this >> t.bltinsize; + //POS("table end") return *this; } size_t archive::size(const table& t) { - size_t s = 0 - + size(t.sign) - + size(t.bm) - + size(t.len) - + size(t.priority) - + size(t.tq) - + size(t.r) - + size(t.idbltin) - + size(t.bltinargs) - + size(t.bltinsize) - + sizeof(unsigned char); - //DBG(o::dbg() << L"table size: " << t.sign.first << L'/' << t.sign.second[0] << L' ' << s - // << L" size(bm): " << size(t.bm) - // << L" (t.bltinargs.size(): " << t.bltinargs.size() - // << L" (t.r.size(): " << t.r.size() + size_t s = 0; + //SPOS("t.s", t.s) + s += size(t.s); + //SPOS("table t", t.t) + s += size(t.t); + //SPOS("table len", t.len) + s += size(t.len); + //SPOS("table priority", t.priority) + s += size(t.priority); + //SPOS("table r", t.r) + s += size(t.r); + //SPOS0("table bools") + s += sizeof(unsigned char); + //SPOS("table idbltin", t.idbltin) + s += size(t.idbltin); + //SPOS("table bltinargs", t.bltinargs) + s += size(t.bltinargs); + //SPOS("table bltinsize", t.bltinsize) + s += size(t.bltinsize); + //DBG(o::dbg() << "table size: " << t.sign.first << '/' << t.sign.second[0] << ' ' << s + // << " size(bm): " << size(t.bm) + // << " (t.bltinargs.size(): " << t.bltinargs.size() + // << " (t.r.size(): " << t.r.size() // << std::endl;) return s; } archive& archive::operator<<(const tables& tbls) { - *this - << tbls.dict - << tbls.rules - << tbls.fronts - << tbls.levels - //<< bodies - //<< alts - << tbls.nstep - << tbls.tmprels - << tbls.deps - << tbls.mhits - << tbls.altids - << tbls.pBin - << tbls.max_args - << tbls.range_compound_memo - << tbls.goals - << tbls.to_drop - << tbls.exts - << tbls.strs - << tbls.str_rels - << tbls.prog_after_fp - << tbls.infer - //<< tbls.addBits - << enc_bools({ tbls.populate_tml_update, tbls.print_updates, - tbls.print_steps, tbls.autotype }) - ; + //POS("tables rules") + *this << tbls.rules; + //POS("tables fronts") + *this << tbls.fronts; + //POS("tables levels") + *this << tbls.levels; + //POS("tables nstep") + *this << tbls.nstep; + //POS("tables tmprels") + *this << tbls.tmprels; + //POS("tables deps") + *this << tbls.deps; + //POS("tables max_args") + *this << tbls.max_args; + //POS("tables range_memo") + *this << tbls.range_memo; + //POS("tables goals") + *this << tbls.goals; + //POS("tables to_drop") + *this << tbls.to_drop; + //POS("tables exts") + //*this << tbls.exts; + //POS("tables strs") + *this << tbls.strs; + //POS("tables str_rels") + *this << tbls.str_rels; + //POS("tables prog_after_fp") + *this << tbls.prog_after_fp; + //POS("tables bools(populate_tml_update, print_updates, print_steps)") + *this << enc_bools({ tbls.populate_tml_update, tbls.print_updates, + tbls.print_steps }); + //POS("tables tbls size") *this << tbls.tbls.size(); + //POS("tables tbls") for (size_t i = 0; i != tbls.tbls.size(); ++i) *this << tbls.tbls[i]; + //POS("tables end") return *this; } + archive& archive::operator>>(tables& tbls) { unsigned char tmp; size_t nsize; - *this >> tbls.dict >> nsize; - for (size_t i = 0; i != nsize; ++i) { - tbls.rules.push_back(rule(false, 0, term(0, {}, {}))); - *this >> tbls.rules.back(); - } - *this - >> tbls.fronts - >> tbls.levels - >> tbls.nstep - >> tbls.tmprels - >> tbls.deps - >> tbls.mhits - >> tbls.altids - >> tbls.pBin - >> tbls.max_args - >> tbls.range_compound_memo - >> tbls.goals - >> tbls.to_drop - >> tbls.exts - >> tbls.strs - >> tbls.str_rels - >> tbls.prog_after_fp - >> tbls.infer - //>> tbls.addBits - >> tmp - >> nsize; - for (size_t i = 0; i != nsize; ++i) read_table(tbls); + //POS("tables rules") + *this >> tbls.rules; + //POS("tables fronts") + *this >> tbls.fronts; + //POS("tables levels") + *this >> tbls.levels; + //POS("tables nstep") + *this >> tbls.nstep; + //POS("tables tmprels") + *this >> tbls.tmprels; + //POS("tables deps") + *this >> tbls.deps; + //POS("tables max_args") + *this >> tbls.max_args; + //POS("tables range_memo") + *this >> tbls.range_memo; + //POS("tables goals") + *this >> tbls.goals; + //POS("tables to_drop") + *this >> tbls.to_drop; + //POS("tables exts") + //*this >> tbls.exts; + //POS("tables strs") + *this >> tbls.strs; + //POS("tables str_rels") + *this >> tbls.str_rels; + //POS("tables prog_after_fp") + *this >> tbls.prog_after_fp; + //POS("tables bools(populate_tml_update, print_updates, print_steps)") + *this >> tmp; tbls.populate_tml_update = dec_bool(tmp); tbls.print_updates = dec_bool(tmp, 1); tbls.print_steps = dec_bool(tmp, 2); - tbls.autotype = dec_bool(tmp, 3); + //POS("tables tbls size") + *this >> nsize; + //POS("tables tbls") + for (size_t i = 0; i != nsize; ++i) read_table(tbls); + //POS("tables end") + //COUT << "dict after load: " << tbls.dict << endl; return *this; } size_t archive::size(const tables& t) { - size_t s = 0 - + size(t.rules) - + size(t.fronts) - + size(t.levels) - + sizeof(nlevel) - + size(t.tmprels) - + size(t.deps) - + size(t.mhits) - + size(t.altids) - + size(t.pBin) - + size(t.dict) - + 2 * sizeof(size_t) - + size(t.goals) - + size(t.strs) - + size(t.prog_after_fp) - + size(t.infer) - + 3 * sizeof(size_t) - + sizeof(int_t) - * (t.to_drop.size() + t.exts.size() + t.str_rels.size()) - + sizeof(unsigned char) - + sizeof(size_t); - for (auto p : t.range_compound_memo) s += size(p.first) + sizeof(int_t); + size_t s = 0; + //SPOS("tables rules", t.rules) + s += size(t.rules); + //SPOS("tables fronts", t.fronts) + s += size(t.fronts); + //SPOS("tables levels", t.levels) + s += size(t.levels); + //SPOS("tables nstep", t.nstep) + s += size(t.nstep); + //SPOS("tables tmprels", t.tmprels) + s += size(t.tmprels); + //SPOS("tables deps", t.deps) + s += size(t.deps); + //SPOS("tables max_args", t.max_args) + s += size(t.max_args); + //SPOS("tables range_memo", t.range_memo) + s += size(t.range_memo); + //SPOS("tables goals", t.goals) + s += size(t.goals); + //SPOS("tables to_drop", t.to_drop) + s += size(t.to_drop); + //SPOS("tables exts", t.exts) + //s += size(t.exts); + //SPOS("tables strs", t.strs) + s += size(t.strs); + //SPOS("tables str_rels", t.str_rels) + s += size(t.str_rels); + //SPOS("tables prog_after_fp", t.prog_after_fp) + s += size(t.prog_after_fp); + //SPOS0("tables bools") + s += sizeof(unsigned char); + //SPOS("tables tbls size", t.tbls.size()) + s += size(t.tbls.size()); + //for (auto p : t.range_memo) s += size(p.first) + sizeof(int_t); + //SPOS("tables tbls", t.tbls) for (size_t i = 0; i != t.tbls.size(); ++i) s += size(t.tbls[i]); + //SPOS0("tables end") return s; } + +archive& archive::add_lexeme_and_map(const dict_t &d, const lexeme& l,bool add){ + //COUT << "add_lexeme_and_map: " << (add ? "" : "no add ") << l << endl; + size_t inp = header_size() + sizeof(size_t) + sizeof(int_t); + lexeme_range lr; input* in; + if (d.ii && d.ii->lexeme_pos(inp, l, &in, lr)) { + auto it = lmap_.find(l); + if (it == lmap_.end()) lmap_.insert({ l, lr }); + if (add) lranges_.push_back({ lr, true }); + } else { + lr = { lpos_, lpos_ }; + auto it = lmap_.find(l); + if (it == lmap_.end()) { // not in map + if (l[1]-l[0] > 0) // non-0 + for (ccs c = l[0]; c != l[1]; ++c) + ldata_ << *c, ++lpos_, lr[1] = lpos_; + lmap_.insert({ l, lr }); + if (add) lranges_.push_back({ lr, false }); + } else if (add) lranges_.push_back({ it->second, false }); + } + return *this; +} + +template +archive& archive::add_lexemes(const dict_t& d, const T& lxms) { + for (const lexeme& l : lxms) add_lexeme_and_map(d, l); + return *this; +} + +archive& archive::add_dict_lexemes(const dict_t& d) { + //POS("dict rels") + add_lexemes(d, d.rels); + //POS("dict syms") + add_lexemes(d, d.syms); + //POS("dict bltins") + add_lexemes(d, d.bltins); + //POS("dict strs_extra") + add_lexemes(d, d.strs_extra); + //POS("dict end") + return *this; +} + +archive& archive::write_lexemes() { + write_ccs(ldata_.str().c_str()); + //POS("lexeme ranges") + //*this << lranges_.size(); + for (auto& r : lranges_) { + //POS("lexeme") + if (r.second) *this << r.first; // points to input, no recount + else *this<size(); + input *in = d.ii->first(); + while (in) { + current++; + *this << in; + in = in->next(); + } + *this << current; + } else *this << (size_t)0 << (int_t)-1; + //POS("dict") + dict_t& dr = d.tbl->dict; + dict_ = &dr; + *this << dict_->rels.size(); + *this << dict_->syms.size(); + *this << dict_->bltins.size(); + *this << dict_->strs_extra.size(); + *this << d.strs_extra.size(); + *this << d.rels.size(); + *this << d.vars.size(); + lpos_ = pos_ + sizeof(size_t); + //POS("dict lexemes") + add_dict_lexemes(*dict_); + //POS("strs_extra lexemes") + add_lexemes(*dict_, d.strs_extra); + add_lexemes(*dict_, d.rels); + add_lexemes(*dict_, d.vars); + for (const raw_prog& p : d.rp.p) { + for (const lexeme& l : p.builtins) + add_lexeme_and_map(dr, l, false); + for (const directive& dir : p.d) + add_lexeme_and_map(dr, dir.arg, false); + for (const raw_rule& r : p.r) { + for (const raw_term& rt : r.h) + for (const elem& e : rt.e) + add_lexeme_and_map(dr, e.e, false); + for (const std::vector& vrt : r.b) + for (const raw_term& rt : vrt) + for (const elem& e : rt.e) + add_lexeme_and_map(dr, e.e, false); + } + } + //POS("lexemes data and lexemes") + write_lexemes(); + //POS("bdd") write_bdd(); - *this - << d.pd - << d.nums - << d.chars - << d.syms - << d.builtin_rels - << d.transformed_strings - << d.strs_extra - << d.rels - << d.vars - << d.rp - << d.opts - << d.std_input - << enc_bools({ d.result, d.running }) - ; + //POS("opts"); + *this << d.opts; + //POS("pd") + *this << d.pd; + //POS("nums") + *this << d.nums; + //POS("chars") + *this << d.chars; + //POS("syms") + *this << d.syms; + //POS("builtin_rels") + *this << d.builtin_rels; + //POS("transformed_strings") + *this << d.transformed_strings; + //POS("rp") + *this << d.rp; + //POS("bools(result, running)") + *this << enc_bools({ d.result, d.running }); + //POS("tables") write_tables(d); - return *this << input::source << int16_t(0x8362); + //POS("footer") + *this << int16_t(0x8362); + //POS("end") + return *this; } archive& archive::operator>>(driver& d) { - std::string source; - //DBG(o::dbg() << L"loading driver\n";) + //DBG(o::dbg() << "loading driver\n";) size_t nsize; - wstring s; + std::string s; char bls; dict_t& dict_r = d.tbl->dict; - dict = &(dict_r); + dict_ = &(dict_r); read_header(); - read_bdd(); - *this >> d.pd >> d.nums >> d.chars >> d.syms >> d.builtin_rels - >> d.transformed_strings >> nsize; - for (size_t i = 0; i != nsize; ++i) - *this >> s, d.strs_extra.insert(dict_r.get_lexeme(s)); - *this >> nsize; - for (size_t i = 0; i != nsize; ++i) - *this >> s, d.rels.insert(dict_r.get_lexeme(s)); + + //POS("inputs") + int_t current = -1; *this >> nsize; - for (size_t i = 0; i != nsize; ++i) - *this >> s, d.vars.insert(dict_r.get_lexeme(s)); - *this >> d.rp >> d.opts >> d.std_input >> bls; + if (nsize > 0 && d.ii) do { + d.ii->add(std::make_unique((void*)0, (size_t)0)); + *this >> *(d.ii->last()); + } while (--nsize > 0); + if (!d.ii) { + *this >> current; + if (current >= 0) { + input *in = d.ii->first(); + while (in && current >= 0) { + current--; + in = in->next(); + } + if (in) d.ii->current_ = in; + } + } else pos_ += sizeof(int_t); + + //POS("dict") + size_t nrels, nsyms, nbltins, ndict_strs_extra, nstrs_extra, + ndriver_rels, nvars; + *this >> nrels >> nsyms >> nbltins >> ndict_strs_extra >> nstrs_extra + >> ndriver_rels >> nvars; + //POS("extra lexemes data") + *this >> nsize; pos_ += nsize; // skip (strs) extra lexemes data + lexeme_range r; + #define LEXEME (lexeme{ (ccs) data_ + r[0], (ccs) data_ + r[1] }) + //POS("rel lexemes") + for (size_t i = 0; i != nrels; ++i) *this >> r, + dict_r.get_rel(LEXEME); + //POS("sym lexemes") + for (size_t i = 0; i != nsyms; ++i) *this >> r, + dict_r.get_sym(LEXEME); + //POS("bltin lexemes") + for (size_t i = 0; i != nbltins; ++i) *this >> r, + dict_r.get_bltin(LEXEME); + //POS("strs_extra lexemes") + for (size_t i = 0; i != ndict_strs_extra; ++i) *this >> r, + dict_r.strs_extra.insert(LEXEME); + //POS("dict strs_extra lexemes") + for (size_t i = 0; i != nstrs_extra; ++i) *this >> r, + d.strs_extra.insert(LEXEME); + //POS("dict rels lexemes") + for (size_t i = 0; i != ndriver_rels; ++i) *this >> r, + d.rels.insert(LEXEME); + //POS("dict vars lexemes") + for (size_t i = 0; i != nvars; ++i) *this >> r, + d.vars.insert(LEXEME); + #undef LEXEME + + //POS("bdd") + read_bdd(); + //POS("opts") + *this >> d.opts; + //POS("pd"); + *this >> d.pd; + //POS("nums") + *this >> d.nums; + //POS("chars") + *this >> d.chars; + //POS("syms") + *this >> d.syms; + //POS("buildtin_rels") + *this >> d.builtin_rels; + //POS("transformed_strings") + *this >> d.transformed_strings; + //POS("rp") + *this >> d.rp; + //POS("bools(running, result") + *this >> bls; d.running = dec_bool(bls, 1), d.result = dec_bool(bls); - *this >> *d.tbl >> source; - input::source = dict_r.get_lexeme(s2ws(source)); + //POS("tables") + *this >> *d.tbl; + //POS("footer") + int16_t footer; *this >> footer; + //POS("end") DBG(assert(footer == (int16_t)0x8362)); return *this; } + +size_t archive::dict_and_lexemes_size(const driver& drv) { + const dict_t& d = drv.tbl->dict; + size_t beg = header_size() + sizeof(size_t) + sizeof(int_t); + size_t s = 0; + //SPOS0("dict_and_lexemes_size begin") + s += 8 * sizeof(size_t) + (2 * sizeof(size_t) * (d.rels.size() + + d.syms.size() + d.bltins.size() + d.strs_extra.size() + + drv.strs_extra.size() + drv.rels.size() + drv.vars.size())); + std::set lexemes{}; + auto add_lexeme_size = + [&d, &lexemes, &beg, &s] (const lexeme& l) { + input* in; lexeme_range lr; + //COUT << "add lexeme size: " << l[1]-l[0] << " " << l << endl; + //s += l[1]-l[0]; + if ((!d.ii || !d.ii->lexeme_pos(beg, l, &in, lr)) + && (lexemes.insert(l).second)) { + //COUT << "adding lexeme size: " << l[1]-l[0] << endl; + s += l[1]-l[0]; + } + }; + //SPOS0("dict rels") + for (const lexeme& l : d.rels) add_lexeme_size(l); + //SPOS0("dict syms") + for (const lexeme& l : d.syms) add_lexeme_size(l); + //SPOS0("dict bltins") + for (const lexeme& l : d.bltins) add_lexeme_size(l); + //SPOS0("dict strs_extra") + for (const lexeme& l : d.strs_extra) add_lexeme_size(l); + //SPOS0("driver strs_extra") + for (const lexeme& l : drv.strs_extra) add_lexeme_size(l); + //SPOS0("driver rels") + for (const lexeme& l : drv.rels) add_lexeme_size(l); + //SPOS0("driver varsd") + for (const lexeme& l : drv.vars) add_lexeme_size(l); + //SPOS0("driver raw prog") + for (const raw_prog& p : drv.rp.p) { + //SPOS0("rp builtins") + for (const lexeme& l : p.builtins) add_lexeme_size(l); + //SPOS0("rp directive args") + for (const directive& dir : p.d) add_lexeme_size(dir.arg); + //SPOS0("rp raw rule") + for (const raw_rule& r : p.r) { + //SPOS0("rp h") + for (const raw_term& rt : r.h) + for (const elem& e : rt.e) + add_lexeme_size(e.e); + //SPOS0("rp b") + for (const std::vector& vrt : r.b) + for (const raw_term& rt : vrt) + for (const elem& e : rt.e) + add_lexeme_size(e.e); + } + } + //SPOS0("driver_and_lexemes_size_end") + return s; +} + size_t archive::size(const driver& d) { - size_t s = header_size() - + bdd_size() - + size(d.pd) - + 3 * sizeof(int_t) - + size(d.builtin_rels) - + size(d.transformed_strings) - + size(d.strs_extra) - + size(d.rels) - + size(d.vars) - + size(d.rp) - + size(d.opts) - + size(d.std_input) - + sizeof(unsigned char) - + tables_size(d) - + size(input::source) - + sizeof(int16_t); - DBG(o::dbg() << L"driver size: " << s - << L" tbls: " << size(*(d.tbl)) - << L" (includes dict: " << size(d.tbl->dict) - << L") bdd: " << bdd_size() - << L" (" << V->size() << L" nodes) input.size: " - << size(input::source) - << sizeof(int16_t) - << std::endl;) + size_t s = 0; + s += header_size(); + //SPOS("inputs size", s); + s += sizeof(size_t); + s += sizeof(int_t); + if (d.ii) { + input *in = d.ii->first(); + while (in) { + s += size(*in); + in = in->next(); + } + } + //SPOS0("dict") + s += dict_and_lexemes_size(d); + //SPOS("bdd", bdd_size()) + s += bdd_size(); + //SPOS("opts", d.opts); + s += size(d.opts); + //SPOS("pd", d.pd) + s += size(d.pd); + //SPOS("nums", (int_t)0) + s += sizeof(int_t); + //SPOS("chars", (int_t)0) + s += sizeof(int_t); + //SPOS("syms", (int_t)0) + s += sizeof(int_t); + //SPOS("builtin_rels", d.builtin_rels) + s += size(d.builtin_rels); + //SPOS("transformed_strings", d.transformed_strings) + s += size(d.transformed_strings); + //SPOS("rp", d.rp) + s += size(d.rp); + //SPOS0("bools(result, running)") + s += sizeof(unsigned char); + //SPOS("tables", (size_t)0) + s += tables_size(d); + //SPOS("footer", (int16_t)0) + s += sizeof(int16_t); + //SPOS0("end") + //DBG(o::dbg() << "driver size: " << s + // << " tbls: " << size(*(d.tbl)) + // //<< " (includes dict: " << size(d.tbl->dict) << ")" + // << " bdd: " << bdd_size() + // << " (" << V->size() << " nodes)" << std::endl;) return s; } @@ -1153,18 +1315,20 @@ archive& archive::write_bdd() { } archive& archive::read_bdd() { size_t nsize; + //POS("reading bdd size") *this >> nsize; + //COUT << "nsize: " << nsize << endl; size_t s = nsize * 3 * sizeof(int_t); - //DBG(o::dbg() << L"loading bdd size: " << s << endl;) + //COUT << "loading bdd size: " << nsize << " " << s << endl; V = std::make_unique(nsize, bdd{0,0,0}, memory_map_allocator("", bdd_mmap_mode)); read((char *)V->data(), s); //for (size_t i = 0; i != V->size(); ++i) { // bdd& b = (*V)[i]; - // DBG(o::dbg() << i << L" " - // << b.v << L' ' - // << b.h << L' ' - // << b.l << L' ' << endl;) + // DBG(COUT << i << " " + // << b.v << ' ' + // << b.h << ' ' + // << b.l << ' ' << endl;) //} return *this; } @@ -1173,29 +1337,3 @@ size_t archive::bdd_size() { return s; } -archive& archive::operator<<(const std::tuple& rcm) { - return *this - << std::get<0>(rcm) - << std::get<1>(rcm) - << std::get<2>(rcm) - << std::get<3>(rcm) - << std::get<4>(rcm) - << std::get<5>(rcm) - << std::get<6>(rcm); -} -archive& archive::operator>>(std::tuple& rcm) { - return *this - >> std::get<0>(rcm) - >> std::get<1>(rcm) - >> std::get<2>(rcm) - >> std::get<3>(rcm) - >> std::get<4>(rcm) - >> std::get<5>(rcm) - >> std::get<6>(rcm); -} -size_t archive::size( - const std::tuple& t) -{ - return 3 * sizeof(int_t) + 3 * sizeof(size_t) - + size((uints)std::get<6>(t)); -} diff --git a/src/archive.h b/src/archive.h index d11746f0..70e1279d 100644 --- a/src/archive.h +++ b/src/archive.h @@ -16,8 +16,6 @@ #include "driver.h" #include "memory_map.h" -using lexeme_range = std::array; - inline static mmap_mode bool2mode(bool write) { return write ? MMAP_WRITE : MMAP_READ; } @@ -33,46 +31,55 @@ class archive { size_t pos_ = 0; size_t size_ = 0; size_t version_ = 0; - dict_t* dict = 0; + dict_t* dict_ = 0; + std::ostringstream ldata_; + size_t lpos_ = 0; + std::map lmap_; + std::vector> lranges_; + ccs lexemes_extra_ = 0; public: // archive with mmap - archive(std::string filename, size_t s, bool mmap_writeable) - : archive(NONE, filename, s, mmap_writeable) {} - archive(type typ, std::string filename, size_t s, bool mmap_writeable) - : type_(typ), - mm_(filename.c_str(), s, bool2mode(mmap_writeable)), - data_(mm_.data()), size_(s) - { - // DBG(o::dbg()<< - // L"archive (mmap): " << s2ws(filename) - // << L" size: " << s << L" writeable: " << mmap_writeable - // << L" map size: " << mm_.size() - // < + static void spos(const std::string& n, const T& v, size_t s) { + sposl(n, archive::size(v), s); + } + static void sposl(const std::string& n, size_t l, size_t s) { + DBG(COUT << "spos: \t" << s << " \t0x" << std::hex << s + << std::dec << " \t" << n << "\t size: " << l << + std::endl;) + } + archive& pos(const std::string& n) { + DBG(COUT << "pos: \t" << pos_ << " \t0x" << std::hex << + pos_ << std::dec << " \t" << n << std::endl;) + return *this; } - virtual ~archive() { mm_.close(); } - dict_t dict_fallback; - dict_t* get_dict() { return dict ? dict : &dict_fallback; } + dict_t dict_fallback_; + dict_t* get_dict() { return dict_ ? dict_ : &dict_fallback_; } unsigned char enc_bools(std::initializer_list list); bool dec_bool(unsigned char bls, int pos = 0); - void write(const char* data, size_t s); - void read(char* data, size_t s); + const char* read_chars(size_t l); + ccs read_ccs(size_t l); + archive& write_ccs(const char* s, size_t l); +// archive& write_ccs(const wchar_t* s, size_t l); + archive& write_ccs(const char* s); +// archive& write_ccs(const wchar_t* s); + archive& write(const char* data, size_t s); + archive& read(char* data, size_t s); - void write(const void* data, size_t s); - void read(void* data, size_t s); + archive& write(const void* data, size_t s); + archive& read(void* data, size_t s); // common writer for vector/set/map template @@ -82,6 +89,14 @@ class archive { return *this; } + // arrays + template + archive& operator<<(const std::array& a); + template + archive& operator>>(std::array& a); + template + static size_t size(const std::array& a); + // vectors template archive& operator<<(const std::vector& v); @@ -91,9 +106,6 @@ class archive { static size_t vecsize(const std::vector& v); template static size_t size(const std::vector& v) { return vecsize(v); } - //template - //static size_t size(const std::vector& v) { - // return sizeof(size_t) + v.size() * sizeof(T); } static size_t size(const std::vector& v) { return vecsize(v); } @@ -112,8 +124,6 @@ class archive { static size_t size(const std::set& v) { return setsize(v); } template static size_t size(const std::set& v) { return setsize(v); } - //static size_t size(const std::set& lxms); - //static size_t size(const std::set& lxms); // maps template @@ -130,10 +140,7 @@ class archive { archive& read_map(std::map& m); archive& operator>>(std::map>& deps); archive& operator>>(std::map>& mhits); - archive& operator>>(std::map>& minvtyps); - archive& operator>>(std::map>& tblbodies); - archive& operator>>(std::map& mtyps); - archive& operator>>(std::map& altordermap); + template static size_t mapsize(const std::map& m); template @@ -147,7 +154,7 @@ class archive { archive& write_header(); archive& read_header(); - static size_t header_size(); + inline static size_t header_size(); archive& operator<<(const int_t&); archive& operator>>(int_t&); @@ -180,23 +187,23 @@ class archive { archive& operator<<(const lexeme_range&); archive& operator>>(lexeme_range&); - archive& operator<<(const std::wstring&); - archive& operator>>(std::wstring&); - static size_t size(const std::wstring& s) { return size(ws2s(s)); } - archive& operator<<(const std::string&); archive& operator>>(std::string&); static size_t size(const std::string& s) { - return s.size() + sizeof(size_t); } + return sizeof(size_t) + s.size() + 1; } archive& operator<<(const spbdd_handle&); archive& operator>>(spbdd_handle&); static size_t size(const spbdd_handle&) { return sizeof(int_t); } static size_t size(const bdd_handle&) { return sizeof(int_t); } - archive& operator<<(const dict_t&); - archive& operator>>(dict_t&); - static size_t size(const dict_t&); + archive& add_lexeme_and_map(const dict_t& d,const lexeme& l,bool add=1); + template + archive& add_lexemes(const dict_t& d, const T& lxms); + archive& add_dict_lexemes(const dict_t&); + archive& write_lexemes(); + + static size_t dict_and_lexemes_size(const driver& drv); archive& operator<<(const term&); archive& operator>>(term&); @@ -210,49 +217,6 @@ class archive { archive& operator>>(sig&); static size_t size(const sig&); - archive& operator<<(const alt_arg&); - archive& operator>>(alt_arg&); - static size_t size(const alt_arg&); - - archive& operator<<(const tbl_arg&); - archive& operator>>(tbl_arg&); - static size_t size(const tbl_arg&); - - archive& operator<<(const multi_arg&); - archive& operator>>(multi_arg&); - static size_t size(const multi_arg&); - - archive& operator<<(const infer_types&); - archive& operator>>(infer_types&); - static size_t size(const infer_types&); - - archive& operator<<(const union_type&); - archive& operator>>(union_type&); - - archive& operator<<(const sub_type&); - archive& operator>>(sub_type&); - - archive& operator<<(const record_type&); - archive& operator>>(record_type&); - - archive& operator<<(const compound_type&); - archive& operator>>(compound_type&); - static size_t size(const compound_type&); - - archive& operator<<(const primitive_type&); - archive& operator>>(primitive_type&); - static size_t size(const primitive_type&); - - archive& operator<<(const ::type&); - archive& operator>>(::type&); - static size_t size(const ::type&); - - archive& operator<<(const argtypes&); - - archive& operator<<(const bitsmeta&); - archive& operator>>(bitsmeta&); - static size_t size(const bitsmeta&); - archive& operator<<(const elem&); archive& operator>>(elem&); static size_t size(const elem&); @@ -281,6 +245,10 @@ class archive { archive& operator>>(raw_progs&); static size_t size(const raw_progs&); + archive& operator<<(const input&); + archive& operator>>(input&); + static size_t size(const input&); + archive& operator<<(const option&); static size_t size(const option&); @@ -319,13 +287,6 @@ class archive { archive& read_bdd(); static size_t bdd_size(); - // range_compound_memo - archive& operator<<(const std::tuple< - int_t, int_t, int_t, size_t, size_t, size_t, uints>&); - archive& operator>>(std::tuple< - int_t, int_t, int_t, size_t, size_t, size_t, uints>&); - static size_t size(const std::tuple< - int_t, int_t, int_t, size_t, size_t, size_t, uints>&); }; #endif diff --git a/src/bdd.cpp b/src/bdd.cpp index f3821238..99621312 100644 --- a/src/bdd.cpp +++ b/src/bdd.cpp @@ -27,7 +27,7 @@ template struct veccmp { }; template struct vec2cmp { - typedef pair, vector> t; + typedef pair, vector> t; bool operator()(const t& x, const t& y) const { static veccmp t1; static veccmp t2; @@ -37,10 +37,10 @@ template struct vec2cmp { }; vector> Mp, Mn; -std::unique_ptr V; +unique_ptr V; size_t max_bdd_nodes = 0; mmap_mode bdd_mmap_mode = MMAP_NONE; -std::string bdd_mmap_file = ""; +string bdd_mmap_file = ""; unordered_map C; map, int_t>, veccmp> CX; map, unordered_map, int_t>, @@ -64,16 +64,16 @@ auto am_cmp = [](int_t x, int_t y) { const size_t gclimit = 1e+6; -void bdd::init(mmap_mode m, size_t max_size, const std::string fn) { +void bdd::init(mmap_mode m, size_t max_size, const string fn) { bdd_mmap_mode = m; if ((max_bdd_nodes = max_size / sizeof(bdd)) < 2) max_bdd_nodes = 2; - V = std::make_unique(memory_map_allocator(fn, m)); + V = make_unique(memory_map_allocator(fn, m)); if (m != MMAP_NONE) V->reserve(max_bdd_nodes); - DBG(o::dbg() << L"bdd::init(m: MMAP_" << - (m == MMAP_NONE ? L"NONE" : L"WRITE") << - L", max_size: " << max_size << L", fn: " << s2ws(fn) - << L") max_bdd_nodes=" << max_bdd_nodes << L"\n";) + DBG(o::dbg() << "bdd::init(m: MMAP_" << + (m == MMAP_NONE ? "NONE" : "WRITE") << + ", max_size: " << max_size << ", fn: " << fn + << ") max_bdd_nodes=" << max_bdd_nodes << "\n";) S.insert(0), S.insert(1), V->emplace_back(0, 0, 0), // dummy V->emplace_back(0, 1, 1), Mp.resize(1), @@ -83,11 +83,11 @@ void bdd::init(mmap_mode m, size_t max_size, const std::string fn) { } void bdd::max_bdd_size_check() { - //DBG(o::dbg() << L"add_check V->size()-1=" << V->size()-1 - // << L" max_bdd_nodes=" << max_bdd_nodes << std::endl;) + //DBG(o::dbg() << "add_check V->size()-1=" << V->size()-1 + // << " max_bdd_nodes=" << max_bdd_nodes << endl;) if (V->size() == max_bdd_nodes) - std::wcerr << L"Maximum bdd size reached. Increase the limit" - L" with --bdd-max-size parameter. Exitting." << std::endl, + CERR << "Maximum bdd size reached. Increase the limit" + " with --bdd-max-size parameter. Exitting." << endl, onexit = true, exit(0); // TODO: offer user to remap instead of exit @@ -99,7 +99,7 @@ int_t bdd::add(int_t v, int_t h, int_t l) { DBG(assert(leaf(l) || v < abs((*V)[abs(l)].v));); if (h == l) return h; if (abs(h) < abs(l)) swap(h, l), v = -v; - static std::unordered_map::const_iterator it; + static unordered_map::const_iterator it; static bdd_key k; auto &mm = v < 0 ? Mn : Mp; if (mm.size() <= (size_t)abs(v)) mm.resize(abs(v)+1); @@ -108,13 +108,13 @@ int_t bdd::add(int_t v, int_t h, int_t l) { k = bdd_key(hash_pair(-h, -l), -h, -l); return (it = m.find(k)) != m.end() ? -it->second : (V->emplace_back(v, -h, -l), - m.emplace(std::move(k), V->size()-1), + m.emplace(move(k), V->size()-1), -V->size()+1); } k = bdd_key(hash_pair(h, l), h, l); return (it = m.find(k)) != m.end() ? it->second : (V->emplace_back(v, h, l), - m.emplace(std::move(k), V->size()-1), + m.emplace(move(k), V->size()-1), V->size()-1); } @@ -579,12 +579,16 @@ void bdd::mark_all(int_t i) { mark_all(hi(i)), mark_all(lo(i)), S.insert(i); } -wostream& bdd::stats(wostream& os) { +template +basic_ostream& bdd::stats(basic_ostream& os) { return os << "S: " << S.size() << " V: "<< V->size() << " AM: " << AM.size() << " C: "<< C.size(); } +template basic_ostream& bdd::stats(basic_ostream&); +template basic_ostream& bdd::stats(basic_ostream&); void bdd::gc() { + if (!V) return; S.clear(); for (auto x : bdd_handle::M) mark_all(x.first); // if (V->size() < S.size() << 3) return; @@ -592,7 +596,7 @@ void bdd::gc() { Mp.clear(), Mn.clear(), S.insert(0), S.insert(1); // if (S.size() >= 1e+6) { o::err() << "out of memory" << endl; exit(1); } vector p(V->size(), 0); - std::unique_ptr v1 = make_unique( + unique_ptr v1 = make_unique( memory_map_allocator("", bdd_mmap_mode)); v1->reserve(bdd_mmap_mode == MMAP_NONE ? S.size() : max_bdd_nodes); for (size_t n = 0; n < V->size(); ++n) @@ -711,8 +715,8 @@ void bdd::gc() { } void bdd_handle::update(const vector& p) { - std::unordered_map> m; - for (pair> x : M) + unordered_map> m; + for (pair> x : M) //DBG(assert(!x.second.expired());) // is this needed? cannot load from archive with this if (!x.second.expired()) f(x.second.lock()->b), m.emplace(f(x.first), x.second); @@ -725,7 +729,7 @@ spbdd_handle bdd_handle::get(int_t b) { auto it = M.find(b); if (it != M.end()) return it->second.lock(); spbdd_handle h(new bdd_handle(b)); - return M.emplace(b, std::weak_ptr(h)), h; + return M.emplace(b, weak_ptr(h)), h; } void bdd::bdd_sz(int_t x, set& s) { @@ -855,7 +859,7 @@ size_t bdd::satcount_perm(const bdd& bx, int_t x, size_t leafvar) { return r; } -static std::set ourvars; +static set ourvars; size_t bdd::getvar(int_t h, int_t l, int_t v, int_t x, size_t maxv) { if (leaf(x)) return maxv; const bdd bhi = get(h), blo = get(l); @@ -884,7 +888,7 @@ size_t bdd::satcount_k(int_t x, const bools& ex, const uints&) { map inv; int_t ivar = 1; for (auto x : ourvars) { - //o::dbg() << L"satcount: inv: " << x << L", " << ivar << L" ." << endl; + //o::dbg() << "satcount: inv: " << x << ", " << ivar << " ." << endl; inv.emplace(x, ivar++); } leafvar = ivar; @@ -1118,20 +1122,23 @@ size_t bdd_nvars(bdd_handles x) { size_t bdd_nvars(spbdd_handle x) { return bdd::bdd_nvars(x->b); } bool leaf(cr_spbdd_handle h) { return bdd::leaf(h->b); } bool trueleaf(cr_spbdd_handle h) { return bdd::trueleaf(h->b); } -wostream& out(wostream& os, cr_spbdd_handle x) { return bdd::out(os, x->b); } +template +basic_ostream& out(basic_ostream& os, cr_spbdd_handle x) { return bdd::out(os, x->b); } +template basic_ostream& out(basic_ostream&, cr_spbdd_handle); +template basic_ostream& out(basic_ostream&, cr_spbdd_handle); -size_t std::hash::operator()(const ite_memo& m) const { +size_t hash::operator()(const ite_memo& m) const { return m.hash; } -size_t std::hash>::operator()(const array& x) const { +size_t hash>::operator()(const array& x) const { return hash_pair(x[0], x[1]); } -size_t std::hash::operator()(const bdd_key& k) const {return k.hash;} +size_t hash::operator()(const bdd_key& k) const {return k.hash;} -size_t std::hash::operator()(const bdds& b) const { +size_t hash::operator()(const bdds& b) const { size_t r = 0; for (int_t i : b) r ^= i; return r; @@ -1141,9 +1148,10 @@ bdd::bdd(int_t v, int_t h, int_t l) : h(h), l(l), v(v) { // DBG(assert(V->size() < 2 || (v && h && l));) } -wostream& bdd::out(wostream& os, int_t x) { - if (leaf(x)) return os << (trueleaf(x) ? L'T' : L'F'); +template +basic_ostream& bdd::out(basic_ostream& os, int_t x) { + if (leaf(x)) return os << (trueleaf(x) ? 'T' : 'F'); const bdd b = get(x); - //return out(out(os << b.v << L" ? ", b.h) << L" : ", b.l); - return out(out(os << b.v << L" ? (", b.h) << L") : (", b.l) << L")"; + //return out(out(os << b.v << " ? ", b.h) << " : ", b.l); + return out(out(os << b.v << " ? (", b.h) << ") : (", b.l) << ")"; } diff --git a/src/bdd.h b/src/bdd.h index 3a516ae2..94e56fab 100644 --- a/src/bdd.h +++ b/src/bdd.h @@ -69,7 +69,8 @@ const int_t T = 1, F = -1; spbdd_handle from_bit(uint_t b, bool v); bool leaf(cr_spbdd_handle h); bool trueleaf(cr_spbdd_handle h); -std::wostream& out(std::wostream& os, cr_spbdd_handle x); +template +std::basic_ostream& out(std::basic_ostream& os, cr_spbdd_handle x); spbdd_handle operator&&(cr_spbdd_handle x, cr_spbdd_handle y); spbdd_handle operator%(cr_spbdd_handle x, cr_spbdd_handle y); spbdd_handle operator||(cr_spbdd_handle x, cr_spbdd_handle y); @@ -194,10 +195,8 @@ class bdd { friend size_t bdd_nvars(spbdd_handle x); friend bool leaf(cr_spbdd_handle h); friend bool trueleaf(cr_spbdd_handle h); - friend std::wostream& out(std::wostream& os, cr_spbdd_handle x); - friend std::ostream& write_bdd(std::ostream& os); - friend std::istream& read_bdd(std::istream& is); - + template + friend std::basic_ostream& out(std::basic_ostream& os, cr_spbdd_handle x); friend void bdd_size(cr_spbdd_handle x, std::set& s); friend int_t bdd_root(cr_spbdd_handle x); friend spbdd_handle bdd_not(cr_spbdd_handle x); @@ -258,12 +257,13 @@ class bdd { static void bdd_nvars(int_t x, std::set& s); static size_t bdd_nvars(int_t x); static bool bdd_subsumes(int_t x, int_t y); - inline static int_t add(int_t v, int_t h, int_t l); + static int_t add(int_t v, int_t h, int_t l); inline static int_t from_bit(uint_t b, bool v); inline static void max_bdd_size_check(); inline static bool leaf(int_t t) { return abs(t) == T; } inline static bool trueleaf(int_t t) { return t > 0; } - static std::wostream& out(std::wostream& os, int_t x); + template + static std::basic_ostream& out(std::basic_ostream& os, int_t x); int_t h, l, v; //--- @@ -325,7 +325,8 @@ class bdd { static void init(mmap_mode m = MMAP_NONE, size_t max_size=10000, const std::string fn=""); static void gc(); - static std::wostream& stats(std::wostream& os); + template + static std::basic_ostream& stats(std::basic_ostream& os); inline static int_t hi(int_t x) { return x < 0 ? (*V)[-x].v < 0 ? -(*V)[-x].l : -(*V)[-x].h : (*V)[x].v < 0 ? (*V)[x].l : (*V)[x].h; diff --git a/src/bdd_ext.cpp b/src/bdd_ext.cpp index 8b4780f5..a4794592 100644 --- a/src/bdd_ext.cpp +++ b/src/bdd_ext.cpp @@ -142,7 +142,7 @@ int_t bdd::bitwiseAND(int_t a_in, int_t b_in) { pos = a.v+2; else pos = b.v + 1; - //o::dbg() << L"--- pos = " << pos << L"\n"; + //o::dbg() << "--- pos = " << pos << "\n"; int_t c = add(pos, bitwiseAND(a.h, b.h ), @@ -202,7 +202,7 @@ int_t bdd::bitwiseXOR(int_t a_in, int_t b_in) { pos = a.v + 2; else pos = b.v + 1; - //o::dbg() << L"--- pos = " << pos << L"\n"; + //o::dbg() << "--- pos = " << pos << "\n"; int_t c = add(pos, bdd_or(bitwiseXOR(a.h, b.l), bitwiseXOR(a.l, b.h)), @@ -314,7 +314,7 @@ int_t bdd::solve_pathXL(size_t i, size_t bits, bool carry, size_t n_args, size_t t_pathv aux_pathX_a = pathX_a; #ifdef VERBOSE - wcout << L" ---solve XL pos = " << pos << L"\n"; + COUT << " ---solve XL pos = " << pos << "\n"; #endif pathX_a.push_back(L); int_t c0; @@ -322,7 +322,7 @@ int_t bdd::solve_pathXL(size_t i, size_t bits, bool carry, size_t n_args, size_t pathX_a = aux_pathX_a; #ifdef VERBOSE - wcout << L" ---solve XL pos = " << pos << L"\n"; + COUT << " ---solve XL pos = " << pos << "\n"; #endif pathX_a.push_back(H); int_t c1; @@ -339,7 +339,7 @@ int_t bdd::solve_pathXL(size_t i, size_t bits, bool carry, size_t n_args, size_t t_path aux = pathX_b.front(); pathX_b.erase(pathX_b.begin()); #ifdef VERBOSE - wcout << L" ---solve XL pos = " << pos << L"\n"; + COUT << " ---solve XL pos = " << pos << "\n"; #endif int_t c0; if (!carry) { @@ -378,7 +378,7 @@ int_t bdd::solve_pathLX(size_t i, size_t bits, bool carry, size_t n_args, size_t t_pathv aux_pathX_b = pathX_b; #ifdef VERBOSE - wcout << L" ---solve LX pos = " << pos << L"\n"; + COUT << " ---solve LX pos = " << pos << "\n"; #endif pathX_b.push_back(L); int_t c0; @@ -386,7 +386,7 @@ int_t bdd::solve_pathLX(size_t i, size_t bits, bool carry, size_t n_args, size_t pathX_b = aux_pathX_b; #ifdef VERBOSE - wcout << L" ---solve LX pos = " << pos << L"\n"; + COUT << " ---solve LX pos = " << pos << "\n"; #endif pathX_b.push_back(H); int_t c1; @@ -402,7 +402,7 @@ int_t bdd::solve_pathLX(size_t i, size_t bits, bool carry, size_t n_args, size_t t_path aux = pathX_a.front(); pathX_a.erase(pathX_a.begin()); #ifdef VERBOSE - wcout << L" ---solve LX pos = " << pos << L"\n"; + COUT << " ---solve LX pos = " << pos << "\n"; #endif int_t c0; if (!carry) { @@ -442,7 +442,7 @@ int_t bdd::solve_pathXH(size_t i, size_t bits, bool carry, size_t n_args, size_t t_pathv aux_pathX_a = pathX_a; #ifdef VERBOSE - wcout << L" ---solve XH pos = " << pos << L"\n"; + COUT << " ---solve XH pos = " << pos << "\n"; #endif pathX_a.push_back(L); int_t c0, c1; @@ -453,7 +453,7 @@ int_t bdd::solve_pathXH(size_t i, size_t bits, bool carry, size_t n_args, size_t pathX_a = aux_pathX_a; #ifdef VERBOSE - wcout << L" ---solve XH pos = " << pos << L"\n"; + COUT << " ---solve XH pos = " << pos << "\n"; #endif pathX_a.push_back(H); @@ -470,7 +470,7 @@ int_t bdd::solve_pathXH(size_t i, size_t bits, bool carry, size_t n_args, size_t t_path aux = pathX_b.front(); pathX_b.erase(pathX_b.begin()); #ifdef VERBOSE - wcout << L" ---solve XH pos = " << pos << L"\n"; + COUT << " ---solve XH pos = " << pos << "\n"; #endif int_t c0; if (!carry) { @@ -511,7 +511,7 @@ int_t bdd::solve_pathHX(size_t i, size_t bits, bool carry, size_t n_args, size_t t_pathv aux_pathX_b = pathX_b; #ifdef VERBOSE - wcout << L" ---solve HX pos = " << pos << L"\n"; + COUT << " ---solve HX pos = " << pos << "\n"; #endif pathX_b.push_back(L); int_t c0, c1; @@ -522,7 +522,7 @@ int_t bdd::solve_pathHX(size_t i, size_t bits, bool carry, size_t n_args, size_t pathX_b = aux_pathX_b; #ifdef VERBOSE - wcout << L" ---solve HX pos = " << pos << L"\n"; + COUT << " ---solve HX pos = " << pos << "\n"; #endif pathX_b.push_back(H); @@ -539,7 +539,7 @@ int_t bdd::solve_pathHX(size_t i, size_t bits, bool carry, size_t n_args, size_t t_path aux = pathX_a.front(); pathX_a.erase(pathX_a.begin()); #ifdef VERBOSE - wcout << L" ---solve HX pos = " << pos << L"\n"; + COUT << " ---solve HX pos = " << pos << "\n"; #endif int_t c0; if (!carry) { @@ -589,7 +589,7 @@ int_t bdd::solve_pathXX(size_t i, size_t bits, bool carry, size_t n_args, size_t } else { #ifdef VERBOSE - wcout << L" ---solve XX pos = " << pos << L"\n"; + COUT << " ---solve XX pos = " << pos << "\n"; #endif t_path aux; int_t c0,c1,ch = F, cl = F; @@ -678,7 +678,7 @@ int_t bdd::solve_path(size_t i, size_t bits, bool carry, size_t n_args, size_t d int_t c = T; int_t pos = i * n_args + 3; #ifdef VERBOSE - wcout << L" ---solve pos = " << pos << L"\n"; + COUT << " ---solve pos = " << pos << "\n"; #endif if (!carry) { @@ -699,7 +699,7 @@ int_t bdd::solve_path(size_t i, size_t bits, bool carry, size_t n_args, size_t d c = solve_pathLX(i,bits, false, n_args, depth, path_a, path_b, pathX_a, pathX_b); else if(path_a[bits-i-1] == X && path_b[bits-i-1] == X) c = solve_pathXX(i, bits, false, n_args, depth, path_a, path_b, pathX_a, pathX_b); - else wcout << L" --- ERROR" << L"\n"; + else COUT << " --- ERROR" << "\n"; } else { if(path_a[bits-i-1] == L && path_b[bits-i-1] == L) @@ -719,12 +719,12 @@ int_t bdd::solve_path(size_t i, size_t bits, bool carry, size_t n_args, size_t d c = solve_pathLX(i,bits, true, n_args, depth, path_a, path_b, pathX_a, pathX_b); else if(path_a[bits-i-1] == X && path_b[bits-i-1] == X) c = solve_pathXX(i, bits, true, n_args, depth, path_a, path_b, pathX_a, pathX_b); - else wcout << L" --- ERROR" << L"\n"; + else COUT << " --- ERROR" << "\n"; } - //wcout << L"##[C" << pos << L"]:"<< endl; - //out(wcout, c); - //wcout < b.v + 1 && b.v != 0) { @@ -1219,7 +1219,7 @@ void bdd::MULT_DFS(int_t a_in, int_t b_in, int_t *accs, size_t depth, size_t bit // else // pos = b.v + 1; // -// o::dbg() << L" ------------------- pos = " << pos << L"\n"; +// o::dbg() << " ------------------- pos = " << pos << "\n"; // // // --------------------------------------------------------------------------- // diff --git a/src/char_defs.h b/src/char_defs.h new file mode 100644 index 00000000..a9b15cba --- /dev/null +++ b/src/char_defs.h @@ -0,0 +1,69 @@ +// LICENSE +// This software is free for use and redistribution while including this +// license notice, unless: +// 1. is used for commercial or non-personal purposes, or +// 2. used for a product which includes or associated with a blockchain or other +// decentralized database technology, or +// 3. used for a product which includes or associated with the issuance or use +// of cryptographic or electronic currencies/coins/tokens. +// On all of the mentioned cases, an explicit and written permission is required +// from the Author (Ohad Asor). +// Contact ohad@idni.org for requesting a permission. This license may be +// modified over time by the Author. +#include +#include +#include +#include + +extern std::wostream wcnull; +extern std::ostream cnull; + +#define WITH_WCHAR +#ifdef WITH_WCHAR +typedef wchar_t syschar_t; +#define CIN std::wcin +#define COUT std::wcout +#define CERR std::wcerr +#define CNULL wcnull +#define EMPTY_STRING L"" +#else // WITH_WCHAR +typedef char syschar_t; +#define CIN std::cin +#define COUT std::cout +#define CERR std::cerr +#define CNULL cnull +#define EMPTY_STRING "" +#endif // WITH_WCHAR + +typedef std::basic_string sysstring_t; +typedef std::basic_istream istream_t; +typedef std::basic_ostream ostream_t; +typedef std::basic_ofstream ofstream_t; +typedef std::basic_ostringstream ostringstream_t; +typedef std::basic_istringstream istringstream_t; +typedef std::vector strings; +typedef std::vector wstrings; + +typedef char char_t; // internal char representation +typedef std::basic_string string_t; // internal string representation +typedef char32_t codepoint; // single unicode codepoint / symbol +typedef char_t* cstr; +typedef const char_t* ccs; +typedef ccs* pccs; +typedef std::array ccs_range; +typedef ccs_range lexeme; +typedef std::vector lexemes; +typedef std::array lexeme_range; + +struct lexcmp { bool operator()(const lexeme& x, const lexeme& y) const; }; +typedef std::map strs_t; + +std::wstring s2ws(const std::string&); +std::wstring s2ws(const std::wstring&); +std::string ws2s(const std::string&); +std::string ws2s(const std::wstring&); + +std::wostream& operator<<(std::wostream& os, const std::string& s); +std::ostream& operator<<(std::ostream& os, const char c); + +std::string to_string_(int_t v); diff --git a/src/defs.h b/src/defs.h index db19ca01..25b940b2 100644 --- a/src/defs.h +++ b/src/defs.h @@ -21,6 +21,7 @@ #include #include #include +#include #ifndef __EMSCRIPTEN__ #ifdef __unix__ @@ -31,22 +32,15 @@ typedef int32_t int_t; typedef uint32_t uint_t; typedef std::vector uints; - -typedef wchar_t* wstr; -typedef const wchar_t* cws; -typedef cws* pcws; -typedef std::array cws_range; -typedef cws_range lexeme; -typedef std::vector lexemes; typedef std::vector ints; -struct lexcmp { bool operator()(const lexeme& x, const lexeme& y) const; }; -typedef std::map strs_t; typedef std::vector bools; typedef std::vector vbools; typedef int_t ntable; typedef size_t nlevel; //typedef std::vector sizes; +#include "char_defs.h" + //#define DEEPDEBUG #ifdef DEBUG #define DBG(x) x @@ -65,30 +59,34 @@ typedef size_t nlevel; #define measure_time_end() end = clock(), \ o::ms() << std::fixed << std::setprecision(2) << \ (double(end - start) / CLOCKS_PER_SEC) * 1000 \ - << L" ms" << endl + << " ms" << endl #define measure_time(x) measure_time_start(); x; measure_time_end() -#define elem_openp elem(elem::OPENP, get_lexeme(L"(")) -#define elem_closep elem(elem::CLOSEP, get_lexeme(L")")) +#define elem_openp elem(elem::OPENP, get_lexeme("(")) +#define elem_closep elem(elem::CLOSEP, get_lexeme(")")) #define htrue bdd_handle::T #define hfalse bdd_handle::F template T sort(const T& x){T t=x;return sort(t.begin(),t.end()),t;} -void parse_error(std::wstring e, lexeme l); -std::wstring s2ws(const std::string&); -std::string ws2s(const std::wstring&); #ifdef _WIN32 std::string temp_filename(); #else int temp_fileno(); std::string filename(int fd); #endif -std::string to_string_(int_t v); -std::wstring to_wstring_(int_t v); typedef enum { NOP, ADD, SUB, MULT, BITWAND, BITWOR, BITWXOR, BITWNOT, SHR, SHL } t_arith_op; +struct alt; struct form; -#endif +struct body; + +struct pnf_t; +typedef enum {EX, UN, FA} quant_t; +typedef std::map varmap; + +typedef std::shared_ptr spbdd_handle; + //#define TRANSFORM_BIN_DRIVER +#endif diff --git a/src/dict.cpp b/src/dict.cpp index 893fbd4a..0260c9e2 100644 --- a/src/dict.cpp +++ b/src/dict.cpp @@ -10,41 +10,41 @@ // from the Author (Ohad Asor). // Contact ohad@idni.org for requesting a permission. This license may be // modified over time by the Author. +#include +#include "defs.h" #include "dict.h" #include "err.h" -#include "defs.h" +#include "input.h" using namespace std; -dict_t::dict_t() : op(get_lexeme(L"(")), cl(get_lexeme(L")")) {} +dict_t::dict_t() : op(get_lexeme("(")), cl(get_lexeme(")")) {} -dict_t::~dict_t() { for (auto x : strs_extra) free((wstr)x[0]); } +dict_t::~dict_t() { for (auto x : strs_allocated) free((char *)x); } lexeme dict_t::get_sym(int_t t) const { DBG(assert(!(t&1) && !(t&2) && syms.size()>(size_t)(t>>2));) - static wchar_t str_nums[20], str_chr[] = L"'a'"; + static char str_nums[20], str_chr[] = { '\'', 'a', '\'' }; if (t & 1) { str_chr[1] = t>>=2; return { str_chr, str_chr + 3 }; } - if (t & 2) return wcscpy(str_nums, to_wstring(t>>=2).c_str()), - lexeme{ str_nums, str_nums + wcslen(str_nums) }; + if (t & 2) return strcpy(str_nums, to_string_(t>>=2).c_str()), + lexeme{ str_nums, str_nums + strlen(str_nums) }; return syms[t>>2]; } int_t dict_t::get_fresh_var(int_t old) { - - static int_t counter=0; - wstring fresh = L"?0f"+ to_wstring(++counter)+to_wstring(old); + static int_t counter = 0; + std::string fresh = "?0f" + to_string_(++counter) + to_string_(old); int_t fresh_int = get_var(get_lexeme(fresh)); return fresh_int; } int_t dict_t::get_fresh_sym(int_t old) { - - static int_t counter=0; - wstring fresh = L"0f" + to_wstring(++counter)+to_wstring(old); + static int_t counter = 0; + std::string fresh = "0f" + to_string_(++counter) + to_string_(old); int_t fresh_int = get_sym(get_lexeme(fresh)); return fresh_int; } int_t dict_t::get_var(const lexeme& l) { - assert(*l[0] == L'?'); + assert(*l[0] == '?'); auto it = vars_dict.find(l); if (it != vars_dict.end()) return it->second; int_t r = -vars_dict.size() - 1; @@ -60,14 +60,14 @@ lexeme dict_t::get_var_lexeme_from(int_t r) { DBG(assert(nr == r);) return vars[index]; } - lexeme l = get_lexeme(wstring(L"?v") + to_wstring(-r)); + lexeme l = get_lexeme(string("?v") + to_string_(-r)); int nr = get_var(l) ; DBG(assert(nr == r)); return l; } int_t dict_t::get_rel(const lexeme& l) { - if (*l[0] == L'?') parse_error(err_var_relsym, l); + if (*l[0] == '?') parse_error(err_var_relsym, l); auto it = rels_dict.find(l); if (it != rels_dict.end()) return it->second; rels.push_back(l); @@ -81,19 +81,20 @@ int_t dict_t::get_sym(const lexeme& l) { } int_t dict_t::get_bltin(const lexeme& l) { - if (*l[0] == L'?') parse_error(err_var_relsym, l); + if (*l[0] == '?') parse_error(err_var_relsym, l); auto it = bltins_dict.find(l); if (it != bltins_dict.end()) return it->second; bltins.push_back(l); return bltins_dict[l] = bltins.size() - 1; } -lexeme dict_t::get_lexeme(const wstring& s) { - cws w = s.c_str(); - auto it = strs_extra.find({w, w + s.size()}); +lexeme dict_t::get_lexeme(const std::string& s) { + ccs w = s.c_str(); + auto it = strs_extra.find({ w, w + s.size() }); if (it != strs_extra.end()) return *it; - wstr r = wcsdup(w); - lexeme l = {r, r + s.size()}; + cstr r = strdup(w); + strs_allocated.push_back(r); + lexeme l = { r, r + s.size() }; strs_extra.insert(l); return l; } diff --git a/src/dict.h b/src/dict.h index 388ed0a5..1d8eb6ee 100644 --- a/src/dict.h +++ b/src/dict.h @@ -15,6 +15,7 @@ #include "defs.h" #include +class inputs; class archive; class dict_t { @@ -23,19 +24,31 @@ class dict_t { dictmap syms_dict, vars_dict, rels_dict, bltins_dict; std::vector vars, syms, rels, bltins; std::set strs_extra; + std::vector strs_allocated; + inputs* ii; public: dict_t(); dict_t(const dict_t& d) : syms_dict(d.syms_dict), vars_dict(d.vars_dict), rels_dict(d.rels_dict), bltins_dict(d.bltins_dict), vars(d.vars), syms(d.syms), rels(d.rels), bltins(d.bltins), - op(d.op), cl(d.cl) { // strs_extra(d.strs_extra), + ii(d.ii), op(d.op), cl(d.cl) { // strs_extra(d.strs_extra), DBG(assert(false);); // we shouldn't be copying, use move instead - for (const lexeme& c : d.strs_extra) { - wstr r = wcsdup((wstr)c[0]); - size_t s = wcslen(r); - lexeme l = { r, r + s }; - strs_extra.insert(l); + std::map remap; + for (ccs c : d.strs_allocated) { + ccs r = strdup(c); + remap.insert({ c, r }); + strs_allocated.push_back(r); } + for (const lexeme& l : d.strs_extra) + for (ccs c : d.strs_allocated) + if (l[0] == c) { // remapped + auto it = remap.find(c); + if (it == remap.end()) throw 0; + ccs r = it->second; + size_t s = strlen(r); + lexeme lx = { r, r+s }; + strs_extra.insert(lx); + } else strs_extra.insert(l); } dict_t(dict_t&& d) noexcept : syms_dict(std::move(d.syms_dict)), @@ -48,13 +61,16 @@ class dict_t { rels(std::move(d.rels)), bltins(std::move(d.bltins)), //types(std::move(d.types)), - strs_extra(std::move(d.strs_extra)), + strs_extra(std::move(d.strs_extra)), + strs_allocated(std::move(d.strs_allocated)), + ii(d.ii), op(std::move(d.op)), cl(std::move(d.cl)) { std::fill(std::begin(d.op), std::end(d.op), nullptr); std::fill(std::begin(d.cl), std::end(d.cl), nullptr); //d.strs_extra.clear(); } lexeme op, cl; + void set_inputs(inputs* ins) { ii = ins; } const lexeme& get_rel(int_t t) const { return rels[t]; } const lexeme& get_bltin(int_t t) const { return bltins[t]; } lexeme get_sym(int_t t) const; @@ -62,12 +78,12 @@ class dict_t { int_t get_rel(const lexeme& l); int_t get_sym(const lexeme& l); int_t get_bltin(const lexeme& l); - int_t get_fresh_sym( int_t old); - int_t get_fresh_var( int_t old); + int_t get_fresh_sym(int_t old); + int_t get_fresh_var(int_t old); lexeme get_var_lexeme_from(int_t r); - lexeme get_lexeme(const std::wstring& s); - int_t get_rel(const std::wstring& s) { return get_rel(get_lexeme(s)); } - int_t get_bltin(const std::wstring& s) { return get_bltin(get_lexeme(s)); } + lexeme get_lexeme(const std::string& s); + int_t get_rel(const std::string& s) { return get_rel(get_lexeme(s)); } + int_t get_bltin(const std::string& s) { return get_bltin(get_lexeme(s)); } size_t nsyms() const { return syms.size(); } size_t nvars() const { return vars_dict.size(); } size_t nrels() const { return rels.size(); } @@ -87,6 +103,7 @@ class dict_t { swap(rels, d.rels), swap(bltins, d.bltins), swap(strs_extra, d.strs_extra), + swap(ii, d.ii), swap(op, d.op), swap(cl, d.cl), //swap(types_dict, d.types_dict), @@ -96,6 +113,7 @@ class dict_t { ~dict_t(); }; -std::wostream& operator<<(std::wostream& os, const dict_t& d); +template +std::basic_ostream& operator<<(std::basic_ostream& os, const dict_t& d); #endif // __DICT_H__ diff --git a/src/driver.cpp b/src/driver.cpp index 78d0d5fd..fa75fa75 100644 --- a/src/driver.cpp +++ b/src/driver.cpp @@ -32,11 +32,12 @@ using namespace std; -wostream& operator<<(wostream& os, const pair& p); +template +std::basic_ostream& operator<<(std::basic_ostream& os, const pair& p); void driver::transform_len(raw_term& r, const strs_t& s) { for (size_t n = 1; n < r.e.size(); ++n) - if ( r.e[n].type == elem::SYM && r.e[n].e == L"len" && + if ( r.e[n].type == elem::SYM && r.e[n].e == "len" && n+3 < r.e.size() && r.e[n+1].type == elem::OPENP && r.e[n+2].type == elem::SYM && @@ -46,23 +47,23 @@ void driver::transform_len(raw_term& r, const strs_t& s) { // if (it == s.end()) parse_error(err_len, r.e[n+2].e); r.e.erase(r.e.begin()+n,r.e.begin()+n+4), r.e.insert(r.e.begin()+n, elem(len)), - r.calc_arity(); + r.calc_arity(*(ii->current())); } } size_t driver::load_stdin() { - wstringstream ss; - std_input = ((ss << wcin.rdbuf()), ss.str()); - return std_input.size(); + ostringstream_t ss; ss << CIN.rdbuf(); + pd.std_input = ws2s(ss.str()); + return pd.std_input.size(); } -void unquote(wstring& str); +void unquote(std::string& str); -wstring driver::directive_load(const directive& d) { - wstring str(d.arg[0]+1, d.arg[1]-d.arg[0]-2); +string driver::directive_load(const directive& d) { + std::string str(d.arg[0]+1, d.arg[1]-d.arg[0]-2); switch (d.type) { - case directive::FNAME: return file_read(str); - case directive::STDIN: return move(std_input); + case directive::FNAME: return input::file_read(ws2s(str)); + case directive::STDIN: return move(pd.std_input); default: return unquote(str), str; } throw 0; // unreachable @@ -77,7 +78,7 @@ void driver::directives_load(raw_prog& p, lexeme& trel) { case directive::CMDLINE: if (d.n < opts.argc()) pd.strs.emplace(d.rel.e, opts.argv(d.n)); - else parse_error(err_num_cmdline, L""); // FIXME + else parse_error(err_num_cmdline); break; /* case directive::STDOUT: pd.out.push_back(get_term(d.t,pd.strs)); break; @@ -92,6 +93,7 @@ void driver::directives_load(raw_prog& p, lexeme& trel) { } void driver::transform(raw_progs& rp, size_t n, const strs_t& /*strtrees*/) { + if (!rp.p.size()) return; lexeme trel = { 0, 0 }; directives_load(rp.p[n], trel); auto get_vars = [this](const raw_term& t) { @@ -121,11 +123,11 @@ void driver::transform(raw_progs& rp, size_t n, const strs_t& /*strtrees*/) { // else transform_grammar(rp.p[n], pd.strs.begin()->first, // pd.strs.begin()->second.size()); // } -// if (opts.enabled(L"sdt")) +// if (opts.enabled("sdt")) // for (raw_prog& p : rp.p) // p = transform_sdt(move(p)); #ifdef TRANSFORM_BIN_DRIVER - if (opts.enabled(L"bin")) + if (opts.enabled("bin")) for (raw_prog& p : rp.p) transform_bin(p); #endif @@ -135,22 +137,22 @@ void driver::transform(raw_progs& rp, size_t n, const strs_t& /*strtrees*/) { } void driver::output_pl(const raw_prog& p) const { - if (opts.enabled(L"xsb")) print_xsb (o::to(L"xsb"), p); - if (opts.enabled(L"swipl")) print_swipl (o::to(L"swipl"), p); - if (opts.enabled(L"souffle")) print_souffle(o::to(L"souffle"), p); + if (opts.enabled("xsb")) print_xsb(o::to("xsb"), p); + if (opts.enabled("swipl")) print_swipl(o::to("swipl"), p); + if (opts.enabled("souffle")) print_souffle(o::to("souffle"), p); } bool driver::prog_run(raw_progs& rp, size_t n, size_t steps, size_t break_on_step) { // pd.clear(); - //DBG(o::out() << L"original program:"<run_prog(rp.p[n], pd.strs, steps, break_on_step); - o::ms() << L"# elapsed: "; + o::ms() << "# elapsed: "; measure_time_end(); pd.elapsed_steps = nsteps() - step; //if (pd.elapsed_steps > 0 && steps && pd.elapsed_steps > steps) throw 0; @@ -160,28 +162,31 @@ bool driver::prog_run(raw_progs& rp, size_t n, size_t steps, return fp; } -void driver::add(wstring& prog, bool newseq) { - rp.parse(prog, tbl->get_dict(), newseq); - if (!newseq) transform(rp, pd.n, pd.strs); +void driver::add(input& in) { + rp.parse(in, tbl->get_dict(), in.newseq); + if (!in.newseq) transform(rp, pd.n, pd.strs); } -void driver::list(wostream& os, size_t n) { +template +void driver::list(std::basic_ostream& os, size_t n) { size_t e = n ? n-- : rp.p.size(); - if (e > rp.p.size()) { os< rp.p.size()) { os<<"# no such program exist"<&, size_t); +template void driver::list(std::basic_ostream&, size_t); void driver::new_sequence() { - //DBG(o::dbg() << L"new sequence" << endl;) + //DBG(o::dbg() << "new sequence" << endl;) transform(rp, pd.n, pd.strs); raw_prog &p = rp.p[pd.n]; - for (const wstring& s : str_bltins) p.builtins.insert(get_lexeme(s)); + for (const string& s : str_bltins) p.builtins.insert(get_lexeme(s)); output_pl(p); - if (opts.enabled(L"t")) o::to(L"transformed") - << L"# Transformed program " << pd.n + 1 << L":" << endl - << L'{' << endl << p << L'}' << endl; + if (opts.enabled("t")) o::to("transformed") + << "# Transformed program " << pd.n + 1 << ":" << endl + << '{' << endl << p << '}' << endl; } void driver::restart() { @@ -196,11 +201,11 @@ bool driver::run(size_t steps, size_t break_on_step, bool break_on_fp) { if (!running) restart(); next_sequence: if (nsteps() == pd.start_step) new_sequence(); - if (opts.disabled(L"run") && opts.disabled(L"repl")) + if (opts.disabled("run") && opts.disabled("repl")) return true; bool fp = prog_run(rp, pd.n, steps, break_on_step); if (fp) { - //DBG(if (opts.enabled(L"dump")) out(o::dump());) + //DBG(if (opts.enabled("dump")) out(o::dump());) if (pd.n == rp.p.size()-1) // all progs fp return result = true, true; ++pd.n; @@ -212,7 +217,7 @@ bool driver::run(size_t steps, size_t break_on_step, bool break_on_fp) { goto next_sequence; } } catch (unsat_exception& e) { - o::out() << s2ws(string(e.what())) << endl; + o::out() << e.what() << endl; result = false; } return false; @@ -222,63 +227,74 @@ bool driver::step(size_t steps, size_t break_on_step, bool break_on_fp) { return run(steps, break_on_step, break_on_fp); } -void driver::info(wostream& os) { +template +void driver::info(std::basic_ostream& os) { size_t l = rp.p.size(); - os<0?l:0) << endl; - os<0?l:0) << endl; + os<<"# step: \t" << nsteps() <<" - " << pd.start_step <<" = " + << (nsteps() - pd.start_step) << " (" + << (running ? "" : "not ") << "running)" << endl; + bdd::stats(os<<"# bdds: \t")<&); +template void driver::info(std::basic_ostream&); size_t driver::size() { return archive::size(*this); } -void driver::db_load(wstring filename) { - archive ar(archive::type::BDD, ws2s(filename), 0, false); - ar << *this; +void driver::db_load(std::string filename) { + load_archives.emplace_back(archive::type::BDD, filename, 0, false); + load_archives.back() >> *this; } -void driver::db_save(wstring filename) { - archive ar(archive::type::BDD, ws2s(filename), archive::size(*this), - true); +void driver::db_save(std::string filename) { + archive ar(archive::type::BDD, filename, archive::size(*this), true); ar << *this; } -void driver::load(wstring filename) { - archive ar(archive::type::DRIVER, ws2s(filename), 0, false); - ar >> *this; +void driver::load(std::string filename) { + load_archives.emplace_back(archive::type::DRIVER, filename, 0, + false); + load_archives.back() >> *this; } -void driver::save(wstring filename) { - archive ar(archive::type::DRIVER, ws2s(filename), archive::size(*this), +void driver::save(std::string filename) { + archive ar(archive::type::DRIVER, filename, archive::size(*this), true); ar << *this; } -driver::driver(wstring s, options o) : rp(), opts(o) { +driver::driver(string s, options o) : rp(), opts(o) { dict_t dict; - // parse outside the rp's ctor - rp.parse(s, dict); + + if (s.size()) opts.parse(strings{ "-ie", s }); + + // inject inputs from opts to driver and dict (needed for archiving) + dict.set_inputs(ii = opts.get_inputs()); + // we don't need the dict any more, tables owns it from now on... - tbl = new tables(move(dict), opts.enabled(L"proof"), - opts.enabled(L"optimize"), opts.enabled(L"bin"), - opts.enabled(L"t")); - set_print_step(opts.enabled(L"ps")); - set_print_updates(opts.enabled(L"pu")); - set_populate_tml_update(opts.enabled(L"tml_update")); + tbl = new tables(move(dict), opts.enabled("proof"), + opts.enabled("optimize"), opts.enabled("bin"), + opts.enabled("t")); + set_print_step(opts.enabled("ps")); + set_print_updates(opts.enabled("pu")); + set_populate_tml_update(opts.enabled("tml_update")); + + while (input* in = ii->next()) add(*in); } -driver::driver(FILE *f, options o) : driver(file_read_text(f), o) {} -driver::driver(char *s, options o) : driver(s2ws(string(s)), o) {} -driver::driver(options o) : driver(o.input(), o) {} +driver::driver(FILE *f, options o) : driver(input::file_read_text(f), o) {} +driver::driver(char *s, options o) : driver(string(s), o) {} +driver::driver(ccs s, options o) : driver(string(s), o) {} +driver::driver(options o) : driver(string(), o) {} driver::driver(FILE *f) : driver(f, options()) {} -driver::driver(wstring s) : driver(s, options()) {} +driver::driver(string s) : driver(s, options()) {} driver::driver(char *s) : driver(s, options()) {} +driver::driver(ccs s) : driver(string(s), options()) {} driver::~driver() { if (tbl) delete tbl; - for (auto x : strs_extra) free((wstr)x[0]); + for (auto x : strs_allocated) free((char *)x); } diff --git a/src/driver.h b/src/driver.h index ff0ac792..ef80c9c2 100644 --- a/src/driver.h +++ b/src/driver.h @@ -41,6 +41,7 @@ struct prog_data { size_t n = 0; size_t start_step = 0; size_t elapsed_steps = 0; + std::string std_input; }; class driver { @@ -56,13 +57,14 @@ class driver { // bool mult = false; std::set strs_extra, rels; + std::vector strs_allocated; lexeme get_var_lexeme(int_t i); lexeme get_new_var(); - lexeme get_lexeme(const std::wstring& s); + lexeme get_lexeme(const std::string& s); lexeme get_new_rel(); // std::function *fget_new_rel; // lexeme get_num_lexeme(int_t i); -// lexeme get_char_lexeme(wchar_t i); +// lexeme get_char_lexeme(char_t i); // lexeme get_demand_lexeme(elem e, const ints& i, const bools& b); void refresh_vars(raw_term& t, size_t& v, std::map& m); void refresh_vars(raw_prog& p); @@ -70,7 +72,7 @@ class driver { std::set refresh_vars(raw_rule& r); std::set get_queries(const raw_prog& p); - std::wstring directive_load(const directive& d); + std::string directive_load(const directive& d); void directives_load(raw_prog& p, lexeme& trel); void transform(raw_progs& rp, size_t n, const strs_t& strtrees); // std::set transform_ms(const std::set& p, @@ -84,25 +86,25 @@ class driver { std::set& s); void transform_bwd(raw_prog& p); void transform_proofs(raw_prog& r, const lexeme& rel); -// void transform_string(const std::wstring&, raw_prog&, int_t); +// void transform_string(const sysstring_t&, raw_prog&, int_t); void transform_grammar(raw_prog& r, lexeme rel, size_t len); raw_prog reify(const raw_prog& p); raw_term from_grammar_elem(const elem& v, int_t v1, int_t v2); raw_term from_grammar_elem_nt(const lexeme& r, const elem& c, int_t v1, int_t v2); - raw_term from_grammar_elem_builtin(const lexeme& r,const std::wstring&b, + raw_term from_grammar_elem_builtin(const lexeme& r, const std::string&b, int_t v); raw_term prepend_arg(const raw_term& t, lexeme s); -// void get_trees(std::wostream& os, const term& root, +// template +// void get_trees(std::basic_ostream& os, const term& root, // const std::map>&, std::set& done); -// std::wstring get_trees(const term& roots,const db_t& t,size_t bits); - void progs_read(wstr s); +// sysstring_t get_trees(const term& roots,const db_t& t,size_t bits); + void progs_read(cstr s); void new_sequence(); bool prog_run(raw_progs& rp, size_t n, nlevel steps=0, size_t brstep=0); //driver(raw_progs, options o); //driver(raw_progs); size_t load_stdin(); - std::wstring std_input; prog_data pd; std::set transformed_strings; tables *tbl = 0; @@ -110,40 +112,51 @@ class driver { std::set vars; raw_progs rp; bool running = false; + inputs* ii; + std::vector load_archives; public: bool result = true; options opts; driver(options o); driver(FILE *f, options o); - driver(std::wstring, options o); + driver(std::string, options o); driver(char *s, options o); + driver(ccs s, options o); driver(FILE *f); - driver(std::wstring); + driver(std::string); driver(char *s); + driver(ccs s); ~driver(); - void info(std::wostream& os); - void list(std::wostream& os, size_t p = 0); - void add(std::wstring& prog, bool newseq = true); + template + void info(std::basic_ostream&); + template + void list(std::basic_ostream& os, size_t p = 0); + void add(input& in); void restart(); bool run(size_t steps = 0, size_t br_on_step=0, bool br_on_fp = false); bool step(size_t steps = 1, size_t br_on_step=0, bool br_on_fp = false); size_t nsteps() { return tbl->step(); }; - void out(std::wostream& os) const { if (tbl) tbl->out(os); } + template + void out(std::basic_ostream& os) const { if (tbl) tbl->out(os); } void dump() { out(o::dump()); } void out(const tables::rt_printer& p) const { if (tbl) tbl->out(p); } void set_print_step (bool val) { tbl->print_steps = val; } void set_print_updates(bool val) { tbl->print_updates = val; } void set_populate_tml_update(bool val) { tbl->populate_tml_update=val; } - bool out_goals(std::wostream& os) const { return tbl->get_goals(os); } - void out_dict(std::wostream& os) const { tbl->print_dict(os); } + template + bool out_goals(std::basic_ostream& os) const { + return tbl->get_goals(os); } + template + void out_dict(std::basic_ostream& os) const { tbl->print_dict(os); } void save_bdd(std::string filename); size_t size(); - void load(std::wstring filename); - void save(std::wstring filename); + void load(std::string filename); + void save(std::string filename); size_t db_size(); - void db_load(std::wstring filename); - void db_save(std::wstring filename); + void db_load(std::string filename); + void db_save(std::string filename); + inputs* get_inputs() const { return ii; } #ifdef __EMSCRIPTEN__ void out(emscripten::val o) const { if (tbl) tbl->out(o); } emscripten::val to_bin() { @@ -157,31 +170,43 @@ class driver { } #endif -// std::wostream& printbdd(std::wostream& os, spbdd t, size_t bits, +// std::basic_ostream& printbdd(std::basic_ostream& os, spbdd t, size_t bits, // const prefix&) const; -// std::wostream& printbdd_one(std::wostream& os, spbdd t, size_t bits, +// std::basic_ostream& printbdd_one(std::basic_ostream& os, spbdd t, size_t bits, // const prefix&) const; - std::wostream& print_prolog(std::wostream&, const raw_prog&, - const prolog_dialect) const; - std::wostream& print_xsb(std::wostream&, const raw_prog&) const; - std::wostream& print_swipl(std::wostream&, const raw_prog&) const; - std::wostream& print_souffle(std::wostream&, const raw_prog&) const; - std::wostream& print_ast(std::wostream&) const; - std::wostream& print_ast_json(std::wostream&) const; - std::wostream& print_ast_xml(std::wostream&) const; - std::wostream& print_ast_html(std::wostream&) const; + template + std::basic_ostream& print_prolog(std::basic_ostream& os, + const raw_prog&, prolog_dialect) const; + template + std::basic_ostream& print_xsb(std::basic_ostream& os, + const raw_prog&) const; + template + std::basic_ostream& print_swipl(std::basic_ostream& os, + const raw_prog&) const; + template + std::basic_ostream& print_souffle(std::basic_ostream& os, + const raw_prog&) const; void save_csv() const; }; +template void driver::out(std::ostream&) const; +template void driver::out(std::wostream&) const; +template bool driver::out_goals(std::basic_ostream&) const; +template bool driver::out_goals(std::basic_ostream&) const; +template void driver::out_dict(std::basic_ostream&) const; +template void driver::out_dict(std::basic_ostream&) const; + #ifdef DEBUG extern driver* drv; -//std::wostream& printdb(std::wostream& os, lp *p); -std::wostream& printbdd(std::wostream& os, cr_spbdd_handle t, size_t bits, - ints ar, int_t rel); -std::wostream& printbdd_one(std::wostream& os, cr_spbdd_handle t, size_t bits, - ints ar, int_t rel); -//std::wostream& printbdd(std::wostream& os, size_t t, size_t bits, ints ar, +//template +//std::basic_ostream& printdb(std::basic_ostream& os, lp *p); +template +std::basic_ostream& printbdd(std::basic_ostream& os, cr_spbdd_handle t, size_t bits, ints ar, int_t rel); +template +std::basic_ostream& printbdd_one(std::basic_ostream& os, cr_spbdd_handle t, size_t bits, ints ar, int_t rel); +//template +//std::basic_ostream& printbdd(std::basic_ostream& os, size_t t, size_t bits, ints ar, // int_t rel); #endif -std::wstring _unquote(std::wstring str); +std::string _unquote(std::string str); #endif diff --git a/src/err.h b/src/err.h index 826e0bde..5796ec10 100644 --- a/src/err.h +++ b/src/err.h @@ -1,51 +1,72 @@ -const wchar_t dot_expected[] = L"'.' expected."; -const wchar_t sep_expected[] = L"Term or ':-' or '.' expected."; -const wchar_t unmatched_quotes[] = L"Unmatched \""; -const wchar_t err_inrel[] = L"Unable to read the input relation symbol."; -const wchar_t err_src[] = L"Unable to read src file."; -const wchar_t err_dst[] = L"Unable to read dst file."; -const wchar_t err_quotes[] = L"Expected \"."; -const wchar_t err_dots[] = L"Two consecutive dots, or dot in beginning of document."; -const wchar_t err_quote[] = L"' should come before and after a single character only."; -const wchar_t err_fname[] = L"Malformed filename."; -const wchar_t err_directive_arg[] = L"Invalid directive argument."; -const wchar_t err_escape[] = L"Invalid escaped character"; -const wchar_t err_int[] = L"Malformed int."; -const wchar_t err_lex[] = L"Lexer error (please report as a bug)."; -const wchar_t err_parse[] = L"Parser error (please report as a bug)."; -const wchar_t err_chr[] = L"Unexpected character."; -const wchar_t err_body[] = L"Rule's body expected."; -const wchar_t err_prod[] = L"Production's body expected."; -const wchar_t err_empty_prod[] = L"Empty production."; -const wchar_t err_constraint_syntax[] = L"Constraint Syntax not supported."; -const wchar_t err_start_sym[] = L"Expected a term to be fed to the start symbol."; -const wchar_t err_term_or_dot[] = L"Term or dot expected."; -const wchar_t err_close_curly[] = L"'}' expected."; -const wchar_t err_fnf[] = L"File not found."; -const wchar_t err_rule_dir_prod_expected[] = L"Rule or production or directive expected."; -const wchar_t err_paren[] = L"Unbalanced parenthesis."; -const wchar_t err_relsym_expected[] = L"Expected relation name in beginning of term."; -const wchar_t err_paren_expected[] = L"Expected parenthesis after a nonzero arity relation symbol."; -const wchar_t err_head[] = L"Expected dot or comma or update operator."; -const wchar_t err_digit[] = L"Symbol name cannot begin with a digit."; -const wchar_t err_var_relsym[] = L"Relation symbol cannot be a variable."; -const wchar_t err_proof[] = L"Proof extraction yet unsupported for programs with negation or deletion."; -const wchar_t err_directive_elem[] = L"Universe element in directive not appearing in program."; -const wchar_t err_goalsym[] = L"Goal symbol not appearing in program."; -const wchar_t err_goalarity[] = L"Goal arity larger than the program's."; -const wchar_t err_num_cmdline[] = L"Program expects more command line arguments."; -const wchar_t err_one_input[] = L"Only one input string allowed given grammar."; -const wchar_t err_str_defined[] = L"String already defined."; -const wchar_t warning_empty_domain[] = L"Warning: empty domain, adding dummy element."; -const wchar_t err_trace_rel[] = L"Trace directive has to be followed by a relation symbol."; -const wchar_t err_directive[] = L"Directives can be @string or @stdout or @trace."; -const wchar_t err_stdout[] = L"Expected term after @stdout."; -const wchar_t err_rel_expected[] = L"Expected relation symbol."; -const wchar_t err_len[] = L"Taking the length of an unknown string."; -const wchar_t err_comment[] = L"Unfinished comment."; -const wchar_t err_eof[] = L"Unexpected end of file."; -const wchar_t err_eq_expected[] = L"Expected =/!= in the middle of term."; -const wchar_t err_leq_expected[] = L"Expected <=/> in the middle of term."; -const wchar_t err_3_els_expected[] = L"Expected 3 elements in the term."; -const wchar_t err_builtin_expected[] = L"Expected builtin name in the beginning of term."; +// LICENSE +// This software is free for use and redistribution while including this +// license notice, unless: +// 1. is used for commercial or non-personal purposes, or +// 2. used for a product which includes or associated with a blockchain or other +// decentralized database technology, or +// 3. used for a product which includes or associated with the issuance or use +// of cryptographic or electronic currencies/coins/tokens. +// On all of the mentioned cases, an explicit and written permission is required +// from the Author (Ohad Asor). +// Contact ohad@idni.org for requesting a permission. This license may be +// modified over time by the Author. + +struct parse_error_exception : public virtual std::runtime_error { + using std::runtime_error::runtime_error; +}; + +struct runtime_error_exception : public virtual std::runtime_error { + using std::runtime_error::runtime_error; +}; + +const char dot_expected[] = "'.' expected."; +const char sep_expected[] = "Term or ':-' or '.' expected."; +const char unmatched_quotes[] = "Unmatched \""; +const char err_inrel[] = "Unable to read the input relation symbol."; +const char err_src[] = "Unable to read src file."; +const char err_dst[] = "Unable to read dst file."; +const char err_quotes[] = "Expected \"."; +const char err_dots[] = "Two consecutive dots, or dot in beginning of document."; +const char err_quote[] = "' should come before and after a single character only."; +const char err_fname[] = "Malformed filename."; +const char err_directive_arg[] = "Invalid directive argument."; +const char err_escape[] = "Invalid escaped character"; +const char err_int[] = "Malformed int."; +const char err_lex[] = "Lexer error (please report as a bug)."; +const char err_parse[] = "Parser error (please report as a bug)."; +const char err_chr[] = "Unexpected character."; +const char err_body[] = "Rule's body expected."; +const char err_prod[] = "Production's body expected."; +const char err_empty_prod[] = "Empty production."; +const char err_constraint_syntax[] = "Constraint Syntax not supported."; +const char err_start_sym[] = "Expected a term to be fed to the start symbol."; +const char err_term_or_dot[] = "Term or dot expected."; +const char err_close_curly[] = "'}' expected."; +const char err_fnf[] = "File not found."; +const char err_rule_dir_prod_expected[] = "Rule or production or directive expected."; +const char err_paren[] = "Unbalanced parenthesis."; +const char err_relsym_expected[] = "Expected relation name in beginning of term."; +const char err_paren_expected[] = "Expected parenthesis after a nonzero arity relation symbol."; +const char err_head[] = "Expected dot or comma or update operator."; +const char err_digit[] = "Symbol name cannot begin with a digit."; +const char err_var_relsym[] = "Relation symbol cannot be a variable."; +const char err_proof[] = "Proof extraction yet unsupported for programs with negation or deletion."; +const char err_directive_elem[] = "Universe element in directive not appearing in program."; +const char err_goalsym[] = "Goal symbol not appearing in program."; +const char err_goalarity[] = "Goal arity larger than the program's."; +const char err_num_cmdline[] = "Program expects more command line arguments."; +const char err_one_input[] = "Only one input string allowed given grammar."; +const char err_str_defined[] = "String already defined."; +const char warning_empty_domain[] = "Warning: empty domain, adding dummy element."; +const char err_trace_rel[] = "Trace directive has to be followed by a relation symbol."; +const char err_directive[] = "Directives can be @string or @stdout or @trace."; +const char err_stdout[] = "Expected term after @stdout."; +const char err_rel_expected[] = "Expected relation symbol."; +const char err_len[] = "Taking the length of an unknown string."; +const char err_comment[] = "Unfinished comment."; +const char err_eof[] = "Unexpected end of file."; +const char err_eq_expected[] = "Expected =/!= in the middle of term."; +const char err_leq_expected[] = "Expected <=/> in the middle of term."; +const char err_3_els_expected[] = "Expected 3 elements in the term."; +const char err_builtin_expected[] = "Expected builtin name in the beginning of term."; diff --git a/src/input.cpp b/src/input.cpp index d12e7792..f42db3ef 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -15,279 +15,320 @@ #include #include #include +#include #include "input.h" #include "err.h" #include "output.h" using namespace std; -cws_range input::source{0,0}; +uint_t file_size(const string &filename) { + try { + return filesystem::file_size(filename); + } catch(exception & e) { + cout << e.what() << '\n'; + } + return 0; +} + +input::input(string f, bool ns) : type_(FILE), newseq(ns), mm_(f), + beg_((ccs)(mm_.data())), data_(beg_), size_(mm_.size()), + allocated_(false) +{ + //COUT << "created file(mmap) input: " << beg_ << endl; + //COUT << "mmap input: " << f << " size: " << size_ << "\n"; + //COUT << mm_.data() << "\n"; + //COUT << "begin char: " << (const char*) beg_ << "\n"; + if (mm_.error) { + //CERR << "error: " << mm_.error_message <') { + if (**s == '-' && *(*s + 1) == '>') { return *s += 2, lexeme{ *s - 2, *s }; } // implication and coimplication - if (**s == L'<' && *(*s + 1) == L'-' && *(*s + 2) == L'>') { + if (**s == '<' && *(*s + 1) == '-' && *(*s + 2) == '>') { return *s += 3, lexeme{ *s - 3, *s }; } // LEQ: put this in front if '' below (as that'll eat us + error out) - //if (**s == L'<') { - if (**s == L'<' && !(*(*s + 1) == L'<')) { - if (*(*s + 1) == L'=') + //if (**s == '<') { + if (**s == '<' && !(*(*s + 1) == '<')) { + if (*(*s + 1) == '=') return *s += 2, lexeme{ *s - 2, *s }; // D: lex/parse: parsing is moved to directive::parse, tag just < return ++*s, lexeme{ *s-1, *s }; } - //if (**s == L'>') { - if (**s == L'>' && !(*(*s + 1) == L'>')) { - if (*(*s + 1) == L'=') + //if (**s == '>') { + if (**s == '>' && !(*(*s + 1) == '>')) { + if (*(*s + 1) == '=') return *s += 2, lexeme{ *s - 2, *s }; return ++*s, lexeme{ *s-1, *s }; } - if (**s == L'\'') { - if (*(*s + 1) == L'\'') return { t, ++++*s }; - if (*(*s + 1) == L'\\') { - //if ((*(*s+2)!=L'\''&&*(*s+2)!=L'\\') - if (!wcschr(L"\\'rnt",*(*s+2)) ||*(*s+3)!=L'\'') + if (**s == '\'') { + if (*(*s + 1) == '\'') return { t, ++++*s }; + if (*(*s + 1) == '\\') { + //if ((*(*s+2)!='\''&&*(*s+2)!='\\') + if (!strchr("\\'rnt",*(*s+2)) ||*(*s+3)!='\'') parse_error((*s+2), err_escape); return { t, ++++++++*s }; } - if (*(*s + 2) != L'\'') parse_error(*s+2, err_quote); + if (*(*s + 2) != '\'') parse_error(*s+2, err_quote); return { t, ++++++*s }; } - if (**s == L':') { - if (*++*s==L'-' || **s==L'=') return ++*s, lexeme{ *s-2, *s }; + if (**s == ':') { + if (*++*s=='-' || **s=='=') return ++*s, lexeme{ *s-2, *s }; else parse_error(*s, err_chr); } // NEQ: make sure we don't turn off directives (single '!'). limits? - if (**s == L'!' && *(*s + 1) == L'=') { + if (**s == '!' && *(*s + 1) == '=') { return *s += 2, lexeme{ *s - 2, *s }; } //ARITH operators: //SHR, SHL, XXX: EQ? - if (**s == L'>' && (*(*s + 1) == L'>')) return *s += 2, lexeme{ *s - 2, *s }; - if (**s == L'<' && (*(*s + 1) == L'<')) return *s += 2, lexeme{ *s - 2, *s }; - //if (**s == L'=' && *(*s + 1) == L'=') return *s += 2, lexeme{ *s - 2, *s }; + if (**s == '>' && (*(*s + 1) == '>')) return *s += 2, lexeme{ *s - 2, *s }; + if (**s == '<' && (*(*s + 1) == '<')) return *s += 2, lexeme{ *s - 2, *s }; + //if (**s == '=' && *(*s + 1) == '=') return *s += 2, lexeme{ *s - 2, *s }; // TODO: single = instead of == recheck if we're not messing up something? - if (**s == L'=') return ++*s, lexeme{ *s-1, *s }; - if (wcschr(L"!~.,;(){}$@=<>|&", **s)) return ++*s, lexeme{ *s-1, *s }; - if (wcschr(L"!~.,;(){}$@=<>|&^+*", **s)) return ++*s, lexeme{ *s-1, *s }; + if (**s == '=') return ++*s, lexeme{ *s-1, *s }; + if (strchr("!~.,;(){}$@=<>|&", **s)) return ++*s, lexeme{ *s-1, *s }; + if (strchr("!~.,;(){}$@=<>|&^+*", **s)) return ++*s, lexeme{ *s-1, *s }; //TODO: review - for subtraction - if (wcschr(L"?-", **s)) ++*s; - if (!iswalnum(**s) && **s != L'_') parse_error(*s, err_chr); - while (**s && (iswalnum(**s) || **s == L'_')) ++*s; + if (strchr("?-", **s)) ++*s; + if (!isalnum(**s) && **s != '_') parse_error(*s, err_chr); + while (**s && (isalnum(**s) || **s == '_')) ++*s; return { t, *s }; } -lexemes prog_lex(cws s) { - lexeme l; - lexemes r; - input::source[0] = s; - do { if ((l = lex(&s)) != lexeme{0, 0}) r.push_back(l); } while (*s); - input::source[1] = s; - return r; +lexemes& input::prog_lex() { + lexeme e; + do { + if ((e=lex(&data_)) != lexeme{0,0}) l.push_back(e); + } while (*(data_)); + //size_ = (*(data_)) - (*(beg_)); + size_ = (data_ - beg_) * sizeof(ccs); + //DBG(o::dbg() << "size of input: " << size_ + // << " beg_: " << (void*)beg_ << " data_: " << (void*)data_ + // << endl;) + return l; } -int_t get_int_t(cws from, cws to) { +int_t input::get_int_t(ccs from, ccs to) { int_t r = 0; bool neg = false; - if (*from == L'-') neg = true, ++from; - for (cws s = from; s != to; ++s) if (!iswdigit(*s)) - parse_error(from, err_int); - wstring s(from, to - from); + if (*from == '-') neg = true, ++from; + for (ccs s = from; s != to; ++s) if (!isdigit(*s)) + ::parse_error(from, err_int); + string s(from, to - from); try { r = stoll(s); } - catch (...) { parse_error(from, err_int); } + catch (...) { ::parse_error(from, err_int); } return neg ? -r : r; } -bool directive::parse(const lexemes& l, size_t& pos, const raw_prog& prog) { +bool directive::parse(input& in, const raw_prog& prog) { + const lexemes& l = in.l; + size_t& pos = in.pos; if (*l[pos][0] != '@') return false; - if (l[++pos] == L"trace") { - type = TRACE; - if (!rel.parse(l, ++pos) || rel.type != elem::SYM) - parse_error(l[pos-1][0], err_trace_rel, l[pos-1]); + if (l[++pos] == "trace") { + type = TRACE; ++pos; + if (!rel.parse(in) || rel.type != elem::SYM) + in.parse_error(l[pos-1][0], err_trace_rel, l[pos-1]); if (*l[pos++][0] != '.') - parse_error(l[pos-1][0], dot_expected, l[pos-1]); + in.parse_error(l[pos-1][0], dot_expected, l[pos-1]); return true; } - if (l[pos] == L"bwd") { + if (l[pos] == "bwd") { type = BWD; if (*l[++pos][0] != '.') - parse_error(l[pos][0], dot_expected, l[pos]); + in.parse_error(l[pos][0], dot_expected, l[pos]); return ++pos, true; } - if (l[pos] == L"stdout") { - type = STDOUT; - if (!t.parse(l, ++pos, prog)) - parse_error(l[pos][0], err_stdout, l[pos]); + if (l[pos] == "stdout") { + type = STDOUT; ++pos; + if (!t.parse(in, prog)) + in.parse_error(l[pos][0], err_stdout, l[pos]); if (*l[pos++][0] != '.') - parse_error(l[pos-1][0], dot_expected, l[pos-1]); + in.parse_error(l[pos-1][0], dot_expected, l[pos-1]); return true; } - if (!(l[pos] == L"string")) - parse_error(l[pos][0], err_directive, l[pos]); - if (!rel.parse(l, ++pos) || rel.type != elem::SYM) - parse_error(l[pos-1][0], err_rel_expected, l[pos-1]); + if (!(l[pos] == "string")) + in.parse_error(l[pos][0], err_directive, l[pos]); + ++pos; + if (!rel.parse(in) || rel.type != elem::SYM) + in.parse_error(l[pos-1][0], err_rel_expected, l[pos-1]); size_t curr2 = pos; - if (*l[pos][0] == L'<') { + if (*l[pos][0] == '<') { // D: parsing is moved here (from lex) so we could process LT. //type = FNAME, arg = l[pos++]; - while (*l[pos++][0] != L'>') - if (!(pos < l.size())) parse_error(l[curr2][1], err_fname); + while (*l[pos++][0] != '>') + if (!(pos < l.size())) + in.parse_error(l[curr2][1], err_fname); type = FNAME, arg = lexeme{ l[curr2][0], l[pos-1][1] }; } - else if (*l[pos][0] == L'"') type = STR, arg = l[pos++]; - else if (*l[pos][0] == L'$') - type=CMDLINE, ++pos, n = get_int_t(l[pos][0], l[pos][1]), ++pos; - else if (l[pos] == L"stdin") type = STDIN; - else if (t.parse(l, pos, prog)) { + else if (*l[pos][0] == '"') type = STR, arg = l[pos++]; + else if (*l[pos][0] == '$') + type=CMDLINE, ++pos, n = in.get_int_t(l[pos][0], l[pos][1]), ++pos; + else if (l[pos] == "stdin") type = STDIN; + else if (t.parse(in, prog)) { type = TREE; if (*l[pos++][0]!='.') - parse_error(l[pos][0], dot_expected, l[pos]); + in.parse_error(l[pos][0], dot_expected, l[pos]); return true; - } else parse_error(l[pos][0], err_directive_arg, l[pos]); + } else in.parse_error(l[pos][0], err_directive_arg, l[pos]); if (*l[pos++][0]!='.') - parse_error(l[curr2][1], dot_expected, l[curr2]); + in.parse_error(l[curr2][1], dot_expected, l[curr2]); return true; } -elem::etype elem::peek(const lexemes& l, size_t& pos) { - - size_t curr = pos; +elem::etype elem::peek(input& in) { + size_t curr = in.pos; type = NONE; - if( pos < l.size() ) parse(l,pos); - pos = curr; + if (in.pos < in.l.size()) parse(in); + in.pos = curr; return type; } -bool elem::parse(const lexemes& l, size_t& pos) { - if (L'|' == *l[pos][0]) return e = l[pos++],type=ALT, true; - if (L'(' == *l[pos][0]) return e = l[pos++],type=OPENP, true; - if (L')' == *l[pos][0]) return e = l[pos++],type=CLOSEP,true; +bool elem::parse(input& in) { + const lexemes& l = in.l; + size_t& pos = in.pos; + if ('|' == *l[pos][0]) return e = l[pos++],type=ALT, true; + if ('(' == *l[pos][0]) return e = l[pos++],type=OPENP, true; + if (')' == *l[pos][0]) return e = l[pos++],type=CLOSEP,true; // NEQ: should we check for any limits here? - if (L'!' == l[pos][0][0] && - L'=' == l[pos][0][1]) { + if ('!' == l[pos][0][0] && + '=' == l[pos][0][1]) { return e = l[pos++], type = NEQ, true; } - if (L'-' == l[pos][0][0] && - L'>' == l[pos][0][1]) { + if ('-' == l[pos][0][0] && + '>' == l[pos][0][1]) { return e = l[pos++], type = IMPLIES, true; } - if (L'<' == l[pos][0][0] && - L'-' == l[pos][0][1] && - L'>' == l[pos][0][2]) { + if ('<' == l[pos][0][0] && + '-' == l[pos][0][1] && + '>' == l[pos][0][2]) { return e = l[pos++], type = COIMPLIES, true; } // LEQ: recheck if '<' is going to make any issues (order/card is important) - // if (L'<' == l[pos][0][0] && L'=' == l[pos][0][1]) - if ((L'<' == l[pos][0][0]) && !(L'<' == l[pos][0][1])) { - if (L'=' == l[pos][0][1]) return e = l[pos++], type = LEQ, true; + // if ('<' == l[pos][0][0] && '=' == l[pos][0][1]) + if (('<' == l[pos][0][0]) && !('<' == l[pos][0][1])) { + if ('=' == l[pos][0][1]) return e = l[pos++], type = LEQ, true; return e = l[pos++], type = LT, true; } - if (L'>' == l[pos][0][0] && !(L'>' == l[pos][0][1])) { - if (L'=' == l[pos][0][1]) return e = l[pos++], type = GEQ, true; + if ('>' == l[pos][0][0] && !('>' == l[pos][0][1])) { + if ('=' == l[pos][0][1]) return e = l[pos++], type = GEQ, true; return e = l[pos++], type = GT, true; } // TODO: single = instead of == recheck if we're not messing up something? - if (L'=' == l[pos][0][0]) { - if (pos + 1 < l.size() && L'>' == l[pos+1][0][0]) return false; + if ('=' == l[pos][0][0]) { + if (pos + 1 < l.size() && '>' == l[pos+1][0][0]) return false; return e = l[pos++], type = EQ, true; } - if ((L'|' == l[pos][0][0]) && (L'|' == l[pos][0][1])) { + if (('|' == l[pos][0][0]) && ('|' == l[pos][0][1])) { return e = l[pos++], type = OR, true; } - if ((L'&' == l[pos][0][0]) && (L'&' == l[pos][0][1])) { + if (('&' == l[pos][0][0]) && ('&' == l[pos][0][1])) { return e = l[pos++], type = AND, true; } - if (L'+' == l[pos][0][0]) { + if ('+' == l[pos][0][0]) { return e = l[pos++], type = ARITH, arith_op = ADD, true; } - if (L'-' == l[pos][0][0]) { + if ('-' == l[pos][0][0]) { return e = l[pos++], type = ARITH, arith_op = SUB, true; } - if (L'*' == l[pos][0][0]) { + if ('*' == l[pos][0][0]) { return e = l[pos++], type = ARITH, arith_op = MULT, true; } //FIXME conflicting with ALT - if (L'|' == l[pos][0][0]) { + if ('|' == l[pos][0][0]) { return e = l[pos++], type = ARITH, arith_op = BITWOR, true; } - if (L'&' == l[pos][0][0]) { + if ('&' == l[pos][0][0]) { return e = l[pos++], type = ARITH, arith_op = BITWAND, true; } - if (L'^' == l[pos][0][0]) { + if ('^' == l[pos][0][0]) { return e = l[pos++], type = ARITH, arith_op = BITWXOR, true; } - if (L'>' == l[pos][0][0] && L'>' == l[pos][0][1]) { + if ('>' == l[pos][0][0] && '>' == l[pos][0][1]) { return e = l[pos++], type = ARITH, arith_op = SHR, true; } - if (L'<' == l[pos][0][0] && L'<' == l[pos][0][1]) { + if ('<' == l[pos][0][0] && '<' == l[pos][0][1]) { return e = l[pos++], type = ARITH, arith_op = SHL, true; } - if (!iswalnum(*l[pos][0]) && !wcschr(L"\"'-?", *l[pos][0])) return false; - if (e = l[pos], *l[pos][0] == L'\'') { + if (!isalnum(*l[pos][0]) && !strchr("\"'-?", *l[pos][0])) return false; + if (e = l[pos], *l[pos][0] == '\'') { type = CHR, e = { 0, 0 }; - if (l[pos][0][1] == L'\'') ch = 0; - else if (l[pos][0][1] != L'\\') ch = l[pos][0][1]; - else if (l[pos][0][2] == L'r') ch = L'\r'; - else if (l[pos][0][2] == L'n') ch = L'\n'; - else if (l[pos][0][2] == L't') ch = L'\t'; - else if (l[pos][0][2] == L'\\') ch = L'\\'; - else if (l[pos][0][2] == L'\'') ch = L'\''; + if (l[pos][0][1] == '\'') ch = 0; + else if (l[pos][0][1] != '\\') ch = l[pos][0][1]; + else if (l[pos][0][2] == 'r') ch = '\r'; + else if (l[pos][0][2] == 'n') ch = '\n'; + else if (l[pos][0][2] == 't') ch = '\t'; + else if (l[pos][0][2] == '\\') ch = '\\'; + else if (l[pos][0][2] == '\'') ch = '\''; else throw 0; } - else if (*l[pos][0] == L'?') type = VAR; - else if (iswalpha(*l[pos][0])) { + else if (*l[pos][0] == '?') type = VAR; + else if (isalpha(*l[pos][0])) { size_t len = l[pos][1]-l[pos][0]; - if( len == 6 && !wcsncmp(l[pos][0], L"forall", len )) + if( len == 6 && !strncmp(l[pos][0], "forall", len )) type = FORALL; - else if ( len == 6 && !wcsncmp(l[pos][0], L"exists", len ) ) + else if ( len == 6 && !strncmp(l[pos][0], "exists", len ) ) type = EXISTS; - else if ( len == 6 && !wcsncmp(l[pos][0], L"unique", len ) ) + else if ( len == 6 && !strncmp(l[pos][0], "unique", len ) ) type = UNIQUE; else type = SYM; } - else if (*l[pos][0] == L'"') type = STR; - else type = NUM, num = get_int_t(l[pos][0], l[pos][1]); + else if (*l[pos][0] == '"') type = STR; + else type = NUM, num = in.get_int_t(l[pos][0], l[pos][1]); return ++pos, true; } -bool raw_term::parse(const lexemes& l, size_t& pos, const raw_prog& prog, raw_term::rtextype pref_type) { +bool raw_term::parse(input& in, const raw_prog& prog, + raw_term::rtextype pref_type) +{ + const lexemes& l = in.l; + size_t& pos = in.pos; + const lexeme &s = l[pos]; size_t curr = pos; - lexeme s = l[pos]; - if ((neg = *l[pos][0] == L'~')) ++pos; + if ((neg = *l[pos][0] == '~')) ++pos; bool rel = false, noteq = false, eq = false, leq = false, gt = false, lt = false, geq = false, bltin = false, arith = false; @@ -297,20 +338,21 @@ bool raw_term::parse(const lexemes& l, size_t& pos, const raw_prog& prog, raw_te //XXX: review for "-" //FIXME: here we have conflict with LEC, ARITH and SOL(formula) parsing. // also eventually ARITH will become formula as well. - while (!wcschr(L".:,;{}-", *l[pos][0])) { // L".:,;{}|&-<" - if (e.emplace_back(), !e.back().parse(l, pos)) return false; + while (!strchr(".:,;{}-", *l[pos][0])) { // ".:,;{}|&-<" + if (e.emplace_back(), !e.back().parse(in)) return false; else if (pos == l.size()) - parse_error(input::source[1], err_eof, s[0]); + in.parse_error(l[pos-1][1], err_eof, s[0]); elem& el = e.back(); // TODO: , el = e.back(), !el.parse(l, pos) switch (el.type) { - case elem::EQ: eq = true; break;//TODO: review - for substraction + case elem::EQ: eq = true; break;//TODO: review - for substraction case elem::NEQ: noteq = true; break; - case elem::LEQ: leq = true; break; - case elem::GT: gt = true; break; - case elem::LT: lt = true; break; - case elem::GEQ: geq = true; break; - case elem::SYM: - if (prog.builtins.find(el.e) != prog.builtins.end()) { + case elem::LEQ: leq = true; break; + case elem::GT: gt = true; break; + case elem::LT: lt = true; break; + case elem::GEQ: geq = true; break; + case elem::SYM: if (prog.builtins.find(el.e) + != prog.builtins.end()) + { el.type = elem::BLTIN; bltin = true; } @@ -332,46 +374,46 @@ bool raw_term::parse(const lexemes& l, size_t& pos, const raw_prog& prog, raw_te if (bltin) { // similar as for SYM below (join?) but this format will expand. if (e[0].type != elem::BLTIN) - parse_error(l[pos][0], err_builtin_expected, l[pos]); + in.parse_error(l[pos][0], err_builtin_expected, l[pos]); if (e[1].type != elem::OPENP) - parse_error(l[pos][0], err_paren_expected, l[pos]); + in.parse_error(l[pos][0], err_paren_expected, l[pos]); if (e.back().type != elem::CLOSEP) - parse_error(e.back().e[0], err_paren, l[pos]); + in.parse_error(e.back().e[0], err_paren, l[pos]); extype = raw_term::BLTIN; // isbltin = true; - return calc_arity(), true; + return calc_arity(in), true; } if ( (noteq || eq) && !arith) { if (e.size() < 3) - parse_error(l[pos][0], err_3_els_expected, l[pos]); + in.parse_error(l[pos][0], err_3_els_expected, l[pos]); // only supporting smth != smthelse (3-parts) and negation in front (). if (e[1].type != elem::NEQ && e[1].type != elem::EQ) - parse_error(l[pos][0], err_eq_expected, l[pos]); + in.parse_error(l[pos][0], err_eq_expected, l[pos]); if (noteq) neg = !neg; // flip the neg as we have NEQ, don't do it for EQ ofc extype = raw_term::EQ; // iseq = true; - return calc_arity(), true; + return calc_arity(in), true; } if ((leq || gt) && !arith) { if (e.size() < 3) - parse_error(l[pos][0], err_3_els_expected, l[pos]); + in.parse_error(l[pos][0], err_3_els_expected, l[pos]); // only supporting smth != smthelse (3-parts) and negation in front (). if (e[1].type != elem::LEQ && e[1].type != elem::GT) - parse_error(l[pos][0], err_leq_expected, l[pos]); + in.parse_error(l[pos][0], err_leq_expected, l[pos]); if (gt) neg = !neg; extype = raw_term::LEQ; // isleq = true; - return calc_arity(), true; + return calc_arity(in), true; } if (lt || geq) { if (e.size() < 3) - parse_error(l[pos][0], err_3_els_expected, l[pos]); + in.parse_error(l[pos][0], err_3_els_expected, l[pos]); // only supporting smth != smthelse (3-parts) and negation in front (). if (e[1].type != elem::LT && e[1].type != elem::GEQ) - parse_error(l[pos][0], err_leq_expected, l[pos]); + in.parse_error(l[pos][0], err_leq_expected, l[pos]); // GEQ <==> LEQ + reverse args + !neg swap(e[2], e[0]); // e = { e[2], e[1], e[0] }; if (!geq) neg = !neg; extype = raw_term::LEQ; - return calc_arity(), true; + return calc_arity(in), true; } if (arith) { @@ -381,26 +423,26 @@ bool raw_term::parse(const lexemes& l, size_t& pos, const raw_prog& prog, raw_te // supported RELATIONSHIPs: = (TODO: add support for <= => < > != ) // TODO: improve checks here if (e.size() < 4) - parse_error(l[pos][0], err_term_or_dot, l[pos]); + in.parse_error(l[pos][0], err_term_or_dot, l[pos]); if (e[1].type != elem::ARITH || e[3].type != elem::EQ) - parse_error(l[pos][0], err_term_or_dot, l[pos]); + in.parse_error(l[pos][0], err_term_or_dot, l[pos]); //iseq = true; neg = false; arith_op = arith_op_aux; extype = raw_term::ARITH; - //return calc_arity(), true; + //return calc_arity(in), true; return true; } if (e[0].type != elem::SYM) - parse_error(l[curr][0], err_relsym_expected, l[curr]); - if (e.size() == 1) return calc_arity(), true; + in.parse_error(l[curr][0], err_relsym_expected, l[curr]); + if (e.size() == 1) return calc_arity(in), true; if (e[1].type != elem::OPENP) - parse_error(l[pos][0], err_paren_expected, l[pos]); + in.parse_error(l[pos][0], err_paren_expected, l[pos]); if (e.back().type != elem::CLOSEP) - parse_error(e.back().e[0], err_paren, l[pos]); - return calc_arity(), true; + in.parse_error(e.back().e[0], err_paren, l[pos]); + return calc_arity(in), true; } void raw_term::insert_parens(lexeme op, lexeme cl) { @@ -412,7 +454,7 @@ void raw_term::insert_parens(lexeme op, lexeme cl) { else k += arity[n]; } -void raw_term::calc_arity() { +void raw_term::calc_arity(input& in) { size_t dep = 0; arity = {0}; //if (iseq || isleq || islt || isarith) { @@ -426,81 +468,78 @@ void raw_term::calc_arity() { else if (e[n].type != elem::CLOSEP) { if (arity.back() < 0) arity.push_back(1); else ++arity.back(); - } else if (!dep--) parse_error(e[n].e[0], err_paren, e[n].e); + } else if (!dep--) in.parse_error(e[n].e[0], err_paren, e[n].e); else arity.push_back(-2); - if (dep) parse_error(e[0].e[0], err_paren, e[0].e); + if (dep) in.parse_error(e[0].e[0], err_paren, e[0].e); } -bool raw_rule::parse(const lexemes& l, size_t& pos, const raw_prog& prog) { - size_t curr = pos; - if (*l[pos][0] == L'!') { - if (*l[++pos][0] == L'!') ++pos, type = TREE; +bool raw_rule::parse(input& in, const raw_prog& prog) { + const lexemes& l = in.l; + size_t& pos = in.pos; size_t curr = pos; + if (*l[pos][0] == '!') { + if (*l[++pos][0] == '!') ++pos, type = TREE; else type = GOAL; } head: h.emplace_back(); - if (!h.back().parse(l, pos, prog)) return pos = curr, false; + if (!h.back().parse(in, prog)) return pos = curr, false; if (*l[pos][0] == '.') return ++pos, true; if (*l[pos][0] == ',') { ++pos; goto head; } - if (*l[pos][0] != ':' || (l[pos][0][1] != L'-' && l[pos][0][1] != L'=' )) - parse_error(l[pos][0], err_head, l[pos]); + if (*l[pos][0] != ':' || (l[pos][0][1] != '-' && l[pos][0][1] != '=' )) + in.parse_error(l[pos][0], err_head, l[pos]); ++pos; - if(l[pos-1][0][1] == L'=') { // formula + if(l[pos-1][0][1] == '=') { // formula curr = pos; raw_sof rsof(prog); raw_form_tree * root = NULL; - bool ret = rsof.parse(l, pos, root); + bool ret = rsof.parse(in, root); sprawformtree temp(root); this->prft = temp; if(ret) return true; - parse_error(l[pos][0], L"Formula has errors", l[pos]); + in.parse_error(l[pos][0], "Formula has errors", l[pos]); } else { b.emplace_back(); - for (b.back().emplace_back(); b.back().back().parse(l, pos, prog); + for (b.back().emplace_back(); b.back().back().parse(in, prog); b.back().emplace_back(), ++pos) { if (*l[pos][0] == '.') return ++pos, true; - else if (*l[pos][0] == L';') b.emplace_back(); - else if (*l[pos][0] != ',') - parse_error(l[pos][0], err_term_or_dot,l[pos]); + else if (*l[pos][0] == ';') b.emplace_back(); + else if (*l[pos][0] != ',') in + .parse_error(l[pos][0], err_term_or_dot,l[pos]); } - parse_error(l[pos][0], err_body, l[pos]); + in.parse_error(l[pos][0], err_body, l[pos]); } return false; } -bool raw_prefix::parse(const lexemes& l, size_t& pos) { - size_t curr = pos; +bool raw_prefix::parse(input& in) { + size_t curr = in.pos; isfod = false; - - if ( !qtype.parse(l, pos) ) return false; + if (!qtype.parse(in)) return false; if (qtype.type != elem::FORALL && qtype.type != elem::EXISTS && qtype.type != elem::UNIQUE) - return pos = curr, false; - - if (*l[pos][0] == L'?' ) isfod = true; - - if ( !ident.parse(l, pos) ) return false; - if ( ident.type != elem::VAR && ident.type != elem::SYM) - return pos = curr, false; - + return in.pos = curr, false; + if (*in.l[in.pos][0] == '?') isfod = true; + if (!ident.parse(in)) return false; + if (ident.type != elem::VAR && ident.type != elem::SYM) + return in.pos = curr, false; return true; } -bool raw_sof::parsematrix(const lexemes& l, size_t& pos, raw_form_tree *&matroot) { - +bool raw_sof::parsematrix(input& in, raw_form_tree *&matroot) { + const lexemes& l = in.l; + size_t& pos = in.pos; size_t curr = pos; raw_form_tree * root = NULL; bool isneg = false; - if ( pos == l.size() ) return NULL; - - if( *l[pos][0] == '~') isneg=true,++pos; - if( pos != l.size() && *l[pos][0] == '{') { + if (pos == l.size()) return NULL; + if (*l[pos][0] == '~') isneg=true,++pos; + if (pos != l.size() && *l[pos][0] == '{') { ++pos; - if( ! parseform(l, pos, root, 0) ) goto Cleanup; + if( ! parseform(in, root, 0) ) goto Cleanup; if( isneg) root = new raw_form_tree(elem::NOT, NULL, NULL, root); @@ -511,54 +550,50 @@ bool raw_sof::parsematrix(const lexemes& l, size_t& pos, raw_form_tree *&matroot return true; } else { - elem next; - next.peek(l, pos); - - if( next.type == elem::SYM ) { - + next.peek(in); + if (next.type == elem::SYM) { raw_term tm; - if( !tm.parse(l,pos, prog)) goto Cleanup; + if( !tm.parse(in, prog)) goto Cleanup; root = new raw_form_tree(elem::NONE, &tm); - if( isneg ) - root = new raw_form_tree(elem::NOT, NULL, NULL, root); + if (isneg) root = new raw_form_tree(elem::NOT, + NULL, NULL, root); matroot = root; return true; - } - else { + } else { raw_form_tree *cur = NULL; - while( next.type == elem::FORALL || - next.type == elem::UNIQUE || - next.type == elem::EXISTS ) { - + while(next.type == elem::FORALL || + next.type == elem::UNIQUE || + next.type == elem::EXISTS ) + { raw_prefix rpfx; - if( !rpfx.parse(l,pos) ) goto Cleanup; - - if(!cur) - root = cur = new raw_form_tree ( rpfx.qtype.type, NULL, &rpfx.qtype ); - else - cur->r = new raw_form_tree ( rpfx.qtype.type, NULL, &rpfx.qtype ), cur = cur->r; - - cur->l = new raw_form_tree ( rpfx.ident.type, NULL, &rpfx.ident ); + if( !rpfx.parse(in) ) goto Cleanup; - next.peek(l, pos); + if(!cur) root = cur = new raw_form_tree( + rpfx.qtype.type, NULL, &rpfx.qtype); + else cur->r = new raw_form_tree( + rpfx.qtype.type, NULL, &rpfx.qtype), + cur = cur->r; + cur->l = new raw_form_tree(rpfx.ident.type, + NULL, &rpfx.ident); + next.peek(in); } - if( cur == NULL || pos == l.size() || *l[pos][0] != '{') + if (cur == NULL || pos == l.size() || *l[pos][0] != '{') goto Cleanup; ++pos; - if(! parseform(l, pos, cur->r, 0)) goto Cleanup; + if (!parseform(in, cur->r, 0)) goto Cleanup; - if( pos == l.size() || *l[pos][0] != '}') goto Cleanup; + if (pos == l.size() || *l[pos][0] != '}') goto Cleanup; ++pos; - if(isneg) - root = new raw_form_tree(elem::NOT, NULL, NULL, root); + if (isneg) root = new raw_form_tree(elem::NOT, + NULL, NULL, root); matroot = root; return true; @@ -570,34 +605,36 @@ bool raw_sof::parsematrix(const lexemes& l, size_t& pos, raw_form_tree *&matroot matroot = root; return pos=curr, false; } -bool raw_sof::parseform(const lexemes& l, size_t& pos, raw_form_tree *&froot, int_t prec ) { +bool raw_sof::parseform(input& in, raw_form_tree *&froot, int_t prec ) { - size_t curr = pos; + size_t curr = in.pos; raw_form_tree* root = NULL; raw_form_tree* cur = NULL; - bool ret = parsematrix(l, pos, root); + bool ret = parsematrix(in, root); elem nxt; if ( !ret ) goto Cleanup; - nxt.peek(l, pos); - while( prec <=1 && (nxt.type == elem::IMPLIES || nxt.type == elem::COIMPLIES)) { - nxt.parse(l, pos); + nxt.peek(in); + while (prec <=1 && + (nxt.type == elem::IMPLIES || nxt.type == elem::COIMPLIES)) + { + nxt.parse(in); cur = new raw_form_tree(nxt.type, NULL, &nxt, root); root = cur; - if( !parseform(l, pos, root->r, 2) ) goto Cleanup ; - nxt.peek(l,pos); + if (!parseform(in, root->r, 2)) goto Cleanup ; + nxt.peek(in); } - nxt.peek(l, pos); + nxt.peek(in); while( prec <= 0 && (nxt.type == elem::AND || nxt.type == elem::ALT) ) { - nxt.parse(l, pos); - cur = new raw_form_tree( nxt.type, NULL, &nxt, root); + nxt.parse(in); + cur = new raw_form_tree(nxt.type, NULL, &nxt, root); root = cur; - if( ! parseform(l, pos, root->r, 1) ) goto Cleanup; - nxt.peek(l,pos); + if (!parseform(in, root->r, 1)) goto Cleanup; + nxt.peek(in); } froot = root; @@ -606,22 +643,22 @@ bool raw_sof::parseform(const lexemes& l, size_t& pos, raw_form_tree *&froot, in Cleanup: //if(root) delete root; froot = root; - return pos=curr, false; + return in.pos=curr, false; } /* Populates root argument by creeating a binary tree of formula. It is caller's responsibility to manage the memory of root. If the parse function, returns false or the root is not needed any more, the caller should delete the root pointer. */ -bool raw_sof::parse(const lexemes& l, size_t& pos, raw_form_tree *&root) { +bool raw_sof::parse(input& in, raw_form_tree *&root) { root = NULL; - bool ret = parseform(l, pos, root ); + bool ret = parseform(in, root ); - if( pos >= l.size() || *l[pos][0] != '.') ret = false; - else pos++; + if( in.pos >= in.l.size() || *in.l[in.pos][0] != '.') ret = false; + else in.pos++; - DBG(wprintf(L"\n cur = %d tot= %d \n ", pos, l.size())); + DBG(COUT << "\n cur = " << in.pos << " tot= " << in.l.size() << " \n ";) return ret; } @@ -629,31 +666,31 @@ bool raw_sof::parse(const lexemes& l, size_t& pos, raw_form_tree *&root) { { if( r ) r->printTree(level + 1) ; - wprintf(L"\n"); + COUT << '\n'; - for(int i=0;irt ) - for(elem &etemp: rt->e) - wprintf(L"%ls ", lexeme2str(etemp.e).c_str()); - else wprintf(L"%ls ", lexeme2str(el->e).c_str()); - if( l ) l->printTree( level +1 ); + if (type == elem::NOT ) COUT << '~'; + else if (this->rt) + for(elem &etemp: rt->e) COUT <e).c_str()<<" "; + if (l) l->printTree(level + 1); } -bool production::parse(const lexemes& l, size_t& pos, const raw_prog& prog) { +bool production::parse(input &in, const raw_prog& prog) { + const lexemes& l = in.l; + size_t& pos = in.pos; size_t curr2, curr = pos; elem e; - if (!e.parse(l, pos) || l.size() <= pos+1) goto fail; -/* if (*l[pos++][0] == L'<') { - if (l[pos++][0][0] != L'=') goto fail; + if (!e.parse(in) || l.size() <= pos+1) goto fail; +/* if (*l[pos++][0] == '<') { + if (l[pos++][0][0] != '=') goto fail; start = true; if (!t.parse(l, pos)) parse_error(err_start_sym, l[pos]); if (*l[pos++][0] != '.') parse_error(dot_expected, l[pos]); return true; }*/ - if (*l[pos++][0] != '=' || l[pos++][0][0] != L'>') goto fail; + if (*l[pos++][0] != '=' || l[pos++][0][0] != '>') goto fail; curr2 = pos; for (p.push_back(e);;) { elem e; @@ -663,33 +700,32 @@ bool production::parse(const lexemes& l, size_t& pos, const raw_prog& prog) { if(p.size() < 2 ) goto fail; // prod rhs atleast one non-terminal - for( ;*l[pos][0] == L',';) { + for (;*l[pos][0] == L','; ) { ++pos; raw_term rt; - if(!rt.parse(l, pos, prog, raw_term::CONSTRAINT)) goto fail; + if (!rt.parse(in, prog, raw_term::CONSTRAINT)) + goto fail; c.push_back(rt); } if (*l[pos][0] != '.') goto fail; return ++pos, true; - } - - - if (!e.parse(l, pos)) goto fail; + } + if (!e.parse(in)) goto fail; p.push_back(e); } - parse_error(l[curr2][0], err_prod, l[curr2]); + in.parse_error(l[curr2][0], err_prod, l[curr2]); fail: return pos = curr, false; } -bool raw_prog::parse(const lexemes& l, size_t& pos) { - while (pos < l.size() && *l[pos][0] != L'}') { +bool raw_prog::parse(input& in) { + while (in.pos < in.l.size() && *in.l[in.pos][0] != '}') { directive x; raw_rule y; production p; // TODO: temp. passing prog/context, make parse(s) prog static instead. - if (x.parse(l, pos, *this)) d.push_back(x); - else if (y.parse(l, pos, *this)) r.push_back(y); - else if (p.parse(l, pos, *this)) g.push_back(p); + if (x.parse(in, *this)) d.push_back(x); + else if (y.parse(in, *this)) r.push_back(y); + else if (p.parse(in, *this)) g.push_back(p); else return false; } return true; @@ -697,24 +733,26 @@ bool raw_prog::parse(const lexemes& l, size_t& pos) { raw_progs::raw_progs() { } // parse(s); -void raw_progs::parse(const std::wstring& s, dict_t& dict, bool newseq) { +void raw_progs::parse(input& in, dict_t& dict, bool newseq) { try { - if (s == L"") return; - size_t pos = 0; - lexemes l = prog_lex(wcsdup(s.c_str())); + if (!in.data_) return; + lexemes& l = in.l; + size_t& pos = in.pos; + in.prog_lex(); if (!l.size()) return; auto prepare_builtins = [&dict](raw_prog& x) { // BLTINS: prepare builtins (dict) - for (const wstring& s : str_bltins) - x.builtins.insert(dict.get_lexeme(s)); + for (const string& s : str_bltins) + x.builtins.insert( + dict.get_lexeme(s)); }; - if (*l[pos][0] != L'{') { + if (*l[pos][0] != '{') { raw_prog& x = !p.size() || newseq ? p.emplace_back() : p.back(); //raw_prog x; prepare_builtins(x); - if (!x.parse(l, pos)) - parse_error(l[pos][0], + if (!x.parse(in)) + in.parse_error(l[pos][0], err_rule_dir_prod_expected, l[pos]); //p.push_back(x); } else do { @@ -722,20 +760,22 @@ void raw_progs::parse(const std::wstring& s, dict_t& dict, bool newseq) { raw_prog& x = p.emplace_back(); // if needed on err: p.pop_back(); //raw_prog x; prepare_builtins(x); - if (++pos, !x.parse(l, pos)) - parse_error(l[pos][0], err_parse, l[pos]); - //if (p.push_back(x), pos==l.size() || *l[pos++][0]!=L'}') - if (pos == l.size() || *l[pos++][0] != L'}') - parse_error(l[pos-1][1], + if (++pos, !x.parse(in)) + in.parse_error(l[pos][0], err_parse, l[pos]); + //if (p.push_back(x), pos==l.size() || *l[pos++][0]!='}') + if (pos == l.size() || *l[pos++][0] != '}') + in.parse_error(l[pos-1][1], err_close_curly, l[pos-1]); } while (pos < l.size()); - } catch (std::exception &e) { - o::err() << s2ws(e.what()) << std::endl; + } catch (parse_error_exception &e) { + o::err() << e.what() << endl; + } catch (runtime_error_exception &e) { + o::err() << e.what() << endl; } } bool operator==(const lexeme& x, const lexeme& y) { - return x[1]-x[0] == y[1]-y[0] && !wcsncmp(x[0],y[0],x[1]-x[0]); + return x[1] - x[0] == y[1] - y[0] && !strncmp(x[0], y[0], x[1] - x[0]); } bool operator<(const raw_term& x, const raw_term& y) { @@ -768,27 +808,31 @@ bool operator<(const raw_rule& x, const raw_rule& y) { return false; } -bool operator==(const lexeme& l, const wstring& s) { - if ((size_t)(l[1]-l[0]) != s.size()) return false; - return !wcsncmp(l[0], s.c_str(), l[1]-l[0]); +bool operator==(const lexeme& l, const string& s) { + if ((size_t) (l[1] - l[0]) != s.size()) return false; + return !strncmp(l[0], s.c_str(), l[1] - l[0]); } -bool operator==(const lexeme& l, cws s) { - size_t n = wcslen(s); - return (size_t)(l[1] - l[0]) != n ? false : !wcsncmp(l[0], s, n); +bool operator==(const lexeme& l, const char* s) { + size_t n = strlen(s); + return (size_t) (l[1] - l[0]) != n + ? false : !strncmp(l[0], s, n); } bool lexcmp::operator()(const lexeme& x, const lexeme& y) const { + //COUT<<"" + // << "\tx: \t"<<&x[0]<<" - "<<&x[1]<<"\n" + // << "\ty: \t"<<&y[0]<<" - "<<&y[1]<<"\n"; if (x[1]-x[0] != y[1]-y[0]) return x[1]-x[0] < y[1]-y[0]; for (size_t n = 0; n != (size_t)(x[1]-x[0]); ++n) if (x[0][n] != y[0][n]) return x[0][n] < y[0][n]; return false; - // the following causes valgrind to complain about __wcsncmp_avx2: + // the following causes valgrind to complain about __STRNCMP_avx2: // return x[1]-x[0] != y[1]-y[0] ? x[1]-x[0] < y[1]-y[0] -// : (wcsncmp(x[0], y[0], x[1]-x[0]) < 0); +// : (STRNCMP(x[0], y[0], x[1]-x[0]) < 0); } -bool operator==(const std::vector& x, const std::vector& y){ +bool operator==(const vector& x, const vector& y){ if (x.size() != y.size()) return false; for (size_t n = 0; n != x.size(); ++n) if (!(x[n]==y[n])) return false; return true; @@ -799,23 +843,24 @@ off_t fsize(const char *fname) { return stat(fname, &s) ? 0 : s.st_size; } -off_t fsize(cws s, size_t len) { return fsize(ws2s(wstring(s, len)).c_str()); } +off_t fsize(ccs s, size_t len) { return fsize(string(s, len).c_str()); } -wstring file_read(wstring fname) { - wifstream s(ws2s(fname)); - wstringstream ss; +string input::file_read(string fname) { + ifstream s(fname); + stringstream ss; return (ss << s.rdbuf()), ss.str(); } -wstring file_read_text(FILE *f) { - wstringstream ss; - wchar_t buf[32], n, l, skip = 0; - wint_t c; +string input::file_read_text(::FILE *f) { + stringstream ss; + char buf[32]; + int_t c, n, l; + bool skip = false; *buf = 0; next: for (n = l = 0; n != 31; ++n) - if (WEOF == (c = getwc(f))) { skip = 0; break; } -// else if (c == L'#') skip = 1; - else if (c == L'\r' || c == L'\n') skip = 0, buf[l++] = c; + if (EOF == (c = getc(f))) { skip = 0; break; } +// else if (c == '#') skip = 1; + else if (c == '\r' || c == '\n') skip = 0, buf[l++] = c; else if (!skip) buf[l++] = c; if (n) { buf[l] = 0, ss << buf; @@ -824,49 +869,64 @@ next: for (n = l = 0; n != 31; ++n) return ss.str(); } -wstring file_read_text(wstring wfname) { - string fname(wfname.begin(), wfname.end()); - FILE *f = fopen(fname.c_str(), "r"); - if (!f) parse_error(err_fnf, wfname); - wstring r = file_read_text(f); +string input::file_read_text(string fname) { + ::FILE *f = fopen(fname.c_str(), "r"); + if (!f) throw_runtime_error(err_fnf, fname); + string r = file_read_text(f); fclose(f); return r; } +void input::count_pos(ccs o, long& l, long& ch) { + l = 1; + ccs c = beg_ ? beg_ : o, n = c - 1; + while (c < o) { + if (*c && *c == '\n') { n = c; ++l; } + ++c; + } + ch = o-n; +} -void parse_error(cws o, std::wstring e) { parse_error(o, e, o); } -void parse_error(wstring e, lexeme l) { parse_error(0, e, l); } -void parse_error(std::wstring e, std::wstring s) { parse_error(0, e, s); } +void throw_runtime_error(string err, string details) { + ostringstream msg; msg << "Runtime error: \"" << err << "\""; + if (details.size()) msg << " details: \"" << details << "\""; + throw runtime_error_exception(msg.str()); +} -void parse_error(cws o, std::wstring e, std::wstring s) { - parse_error(o, e, s.c_str()); +void parse_error(const char* e, lexeme l) { + input in((void*) 0, (size_t) 0); in.parse_error(0, e, l); } -void parse_error(cws o, std::wstring e, cws s, size_t len) { - parse_error(o, e, wstring(s, len).c_str()); +void parse_error(const char* e) { + input in((void*) 0, (size_t) 0); in.parse_error(0, e, 0); } -void parse_error(cws o, wstring e, lexeme l) { - parse_error(o, e, wstring(l[0], l[1]-l[0]).c_str()); +void parse_error(const char* e, std::string s) { + input in((void*) 0, (size_t) 0); in.parse_error(0, e, s.c_str()); } -void count_pos(const cws& s, const cws& o, long& l, long& ch) { - l = 1; - cws c = s, n = c - 1; - while (c < o) { - if (*c && *c == L'\n') { n = c; ++l; } - ++c; - } - ch = o-n; +void parse_error(ccs offset, const char* err) { + input in((void*) 0, (size_t) 0); in.parse_error(offset, err, offset); } -void parse_error(cws o, std::wstring e, cws s) { - std::wstringstream msg; msg << L"Parse error: \"" << e << L'"'; - cws p = s; - while (p && *p && *p != L'\n') ++p; - if (o != 0) { - long l, ch; count_pos(input::source[0], o, l, ch); - msg << L" at " << l << L':' << ch; +void input::parse_error(ccs offset, const char* err, lexeme close_to) { + parse_error(offset, err, close_to[0]); +} + +void input::parse_error(ccs offset, const char* err, ccs close_to) { + DBG(o::dbg() << "parse_error: in.data: " << &data_ << " '" << data_ + << "' offset: " << &offset << " '" << offset << "' " + << " error: '" << err << "' " + << " s: " << &close_to << " '" << close_to << "'" + << endl;) + + ostringstream msg; msg << "Parse error: \"" << err << '"'; + ccs p = close_to; + while (p && *p && *p != '\n') ++p; + if (offset != 0) { + long l, ch; count_pos(offset, l, ch); + msg << " at " << l << ':' << ch; } - if (s) msg << L" close to \"" << std::wstring(s, p-s) << L'"'; - throw parse_error_exception(ws2s(msg.str())); + if (close_to) msg << " close to \"" + << string(close_to, p - close_to) << '"'; + throw parse_error_exception(msg.str()); } diff --git a/src/input.h b/src/input.h index c43dd65b..f54890a4 100644 --- a/src/input.h +++ b/src/input.h @@ -13,18 +13,146 @@ #ifndef __INPUT_H__ #define __INPUT_H__ -#include "defs.h" -#include "dict.h" #include #include #include +#include #include #include +#include #include +#include + +#include "defs.h" +#include "dict.h" +#include "memory_map.h" + +class archive; + +uint_t file_size(const std::string &filename); + +struct input { + friend class archive; + enum type { STDIN, FILE, STRING } type_; + bool newseq = false; + memory_map mm_; + ccs beg_ = 0; + ccs data_ = 0; + size_t size_ = 0; + bool allocated_ = false; + int fd_ = -1; + size_t offset = 0; + size_t pos = 0; + lexemes l = {}; + std::unique_ptr next_ = 0; + lexeme lex(pccs s); + lexemes& prog_lex(); + // is l in this input? if true set l's offset into lr + bool lexeme_pos(size_t beg, lexeme l, lexeme_range& lr) { + if ((l[0] >= beg_ && l[0] < beg_ + size_) + || (l[1] >= beg_ && l[1] < beg_ + size_)) + return lr[0] = l[0] - beg_ + beg, + lr[1] = l[1] - beg_ + beg, true; + return false; + } + static std::string file_read(std::string fname); + static std::string file_read_text(::FILE *f); + static std::string file_read_text(std::string fname); + static off_t fsize(const char *fname); + static off_t fsize(ccs s, size_t len); + input(bool ns = false) : type_(STDIN), newseq(ns), beg_(0), data_(0), + size_(load_stdin()) + { + //COUT << "created stdin input *: " << beg_ << std::endl; + } + input(void* s, size_t sz, bool ns = false) : type_(STRING), newseq(ns), + beg_((ccs) s), data_(beg_), size_(sz), allocated_(false) + { + //COUT << "created pointer input: " << beg_ << std::endl; + } + input(ccs s, bool ns = false) : type_(STRING), newseq(ns), + beg_(strdup(s)),data_(beg_),size_(strlen(beg_)),allocated_(true) + { + //COUT << "created string input *: " << s << std::endl; + } + input(std::string f, bool ns = false); // FILE + ~input(); + struct input* next() { return next_.get(); } + ccs begin() { return beg_; } + ccs data() { return data_; } + size_t size() { return size_; } + void set_offset(size_t o) { offset = o; } + static int_t get_int_t(ccs from, ccs to); + void count_pos(ccs o, long& l, long& ch); + void parse_error(ccs offset, const char* err) { + return parse_error(offset, err, offset); + } + void parse_error(ccs offset, const char* err, ccs close_to); + void parse_error(ccs offset, const char* err, lexeme close_to); +private: + size_t load_stdin() { + ostringstream_t ss; ss << CIN.rdbuf(); + beg_ = strdup((ws2s(ss.str())).c_str()), data_ = beg_, + allocated_ = true; + return ss.str().size(); + } +}; + +class inputs { + friend class archive; + std::unique_ptr first_ = 0; + struct input *current_ = 0; + struct input *last_ = 0; + size_t size_ = 0; +public: + void add(std::unique_ptr in) { + input *inp = in.get(); + if (last_) last_->next_ = std::move(in); + else if (first_ == 0) first_ = std::move(in); + last_ = inp; + size_++; + } + void add_stdin() { + add(std::make_unique()); + } + void add_file(std::string filename) { + //COUT << "adding file input: " << filename << std::endl; + add(std::make_unique(filename)); + //COUT << "inputs size: " << size() << " this: " << this <(str.c_str())); + //COUT << "inputs size: " << size() << " this: " << this <next_) { + current_->next_->set_offset(current_->offset + + current_->size_); + return (current_ = current_->next_.get()); + } else return 0; + } + size_t size() const { return size_; } + bool lexeme_pos(size_t& beg, lexeme l, input** in, lexeme_range& lr) { + struct input* it = first_.get(); + while (it) { + beg += sizeof(size_t) + 1; + if (it->lexeme_pos(beg, l, lr)) return *in = it, true; + beg += it->size_ + 1; + it = it->next_.get(); + } + return *in = 0, false; + } +}; -namespace input { - extern cws_range source; -} struct raw_form_tree; typedef std::shared_ptr sprawformtree; @@ -32,10 +160,10 @@ struct raw_prog; bool operator==(const lexeme& x, const lexeme& y); -static const std::set str_bltins = - { L"alpha", L"alnum", L"digit", L"space", L"printable", L"count", - L"rnd", L"print", L"lprint", L"halt", L"fail", - L"bw_and", L"bw_or", L"bw_xor", L"bw_not", L"pw_add", L"pw_mult"}; +static const std::set str_bltins = + { "alpha", "alnum", "digit", "space", "printable", "count", + "rnd", "print", "lprint", "halt", "fail", + "bw_and", "bw_or", "bw_xor", "bw_not", "pw_add", "pw_mult"}; struct elem { enum etype { @@ -45,22 +173,22 @@ struct elem { t_arith_op arith_op = NOP; int_t num = 0; lexeme e; - wchar_t ch; + codepoint ch; elem() {} - elem(int_t num) : type(NUM), num(num) {} - elem(wchar_t ch) : type(CHR), ch(ch) {} + elem(int_t num) : type(NUM), num(num) {} + elem(codepoint ch) : type(CHR), ch(ch) {} elem(etype type, lexeme e) : type(type), e(e) { DBG(assert(type!=NUM&&type!=CHR&&(type!=SYM||(e[0]&&e[1])));) } - etype peek(const lexemes& l, size_t& pos); + etype peek(input& in); bool is_paren() const { return type == OPENP || type == CLOSEP; } - bool parse(const lexemes& l, size_t& pos); + bool parse(input& in); bool operator<(const elem& t) const { if (type != t.type) return type < t.type; if (type == NUM) return num < t.num; if (type == CHR) return ch < t.ch; if (e[1]-e[0] != t.e[1]-t.e[0]) return e[1]-e[0] e; ints arity; - - bool parse(const lexemes& l, size_t& pos, const raw_prog& prog, - rtextype pref_type = raw_term::REL ); - void calc_arity(); + bool parse(input& in, const raw_prog& prog, + rtextype pref_type = raw_term::REL); + void calc_arity(input& in); void insert_parens(lexeme op, lexeme cl); void clear() { e.clear(), arity.clear(); } bool operator==(const raw_term& t) const { @@ -103,16 +230,15 @@ struct directive { raw_term t; int_t n; enum etype { STR, FNAME, CMDLINE, STDIN, STDOUT, TREE, TRACE, BWD }type; - bool parse(const lexemes& l, size_t& pos, const raw_prog& prog); + bool parse(input& in, const raw_prog& prog); }; struct production { // bool start = false; // raw_term t; std::vector p; - std::vector c; // constraints after production - bool parse(const lexemes& l, size_t& pos, const raw_prog& prog); - + std::vector c{}; // constraints after production + bool parse(input& in, const raw_prog& prog); bool operator<(const production& t) const { return p < t.p && c < t.c; } }; @@ -125,7 +251,7 @@ struct raw_rule { enum etype { NONE, GOAL, TREE }; etype type = NONE; - bool parse(const lexemes& l, size_t& pos, const raw_prog& prog); + bool parse(input& in, const raw_prog& prog); void clear() { h.clear(), b.clear(), type = NONE; } raw_rule(){} raw_rule(etype type, const raw_term& t) : h({t}), type(type) {} @@ -145,11 +271,10 @@ struct raw_rule { }; struct raw_prefix { - elem qtype; - elem ident; - bool isfod =false; - - bool parse(const lexemes& l, size_t& pos); + elem qtype; + elem ident; + bool isfod =false; + bool parse(input& in); }; @@ -161,38 +286,32 @@ struct raw_form_tree { raw_form_tree *l; raw_form_tree *r; - raw_form_tree (elem::etype _type, raw_term* _rt = NULL, elem *_el= NULL, raw_form_tree *_l= NULL, raw_form_tree *_r= NULL ) { - + raw_form_tree (elem::etype _type, raw_term* _rt = NULL, elem *_el =NULL, + raw_form_tree *_l = NULL, raw_form_tree *_r = NULL) + { type = _type; - if(_rt) - rt = new raw_term(*_rt); + if(_rt) rt = new raw_term(*_rt); else rt = NULL; - - if(_el) - el = new elem(*_el); + if(_el) el = new elem(*_el); else el = NULL; - - l = _l; - r = _r; + l = _l, r = _r; } ~raw_form_tree() { - if( l ) delete l, l= NULL; - if (r ) delete r, r= NULL; - if (rt) delete rt,rt= NULL; - if (el) delete el, el= NULL; + if (l) delete l, l = NULL; + if (r) delete r, r = NULL; + if (rt) delete rt, rt = NULL; + if (el) delete el, el = NULL; } void printTree(int level =0 ); }; struct raw_sof { const raw_prog& prog; raw_sof(const raw_prog& prog) :prog(prog) {} - - private: - bool parseform(const lexemes& l, size_t& pos, raw_form_tree *&root, int precd= 0); - bool parsematrix(const lexemes& l, size_t& pos, raw_form_tree *&root); - - public: - bool parse(const lexemes& l, size_t& pos, raw_form_tree *&root); +private: + bool parseform(input& in, raw_form_tree *&root, int precd= 0); + bool parsematrix(input& in, raw_form_tree *&root); +public: + bool parse(input& in, raw_form_tree *&root); }; @@ -202,46 +321,49 @@ struct raw_prog { std::vector r; std::set builtins; // int_t delrel = -1; - bool parse(const lexemes& l, size_t& pos); + bool parse(input& in); }; struct raw_progs { std::vector p; raw_progs(); - void parse(const std::wstring& s, dict_t& dict, bool newseq = true); + void parse(input& in, dict_t& dict, bool newseq = true); }; -void parse_error(cws o, std::wstring e); -void parse_error(cws o, std::wstring e, cws s); -void parse_error(cws o, std::wstring e, lexeme l); -void parse_error(cws o, std::wstring e, std::wstring s); -void parse_error(cws o, std::wstring e, cws s, size_t len); -void parse_error(std::wstring e, lexeme l); -void parse_error(std::wstring e, std::wstring s); -std::wostream& operator<<(std::wostream& os, const directive& d); -std::wostream& operator<<(std::wostream& os, const elem& e); -std::wostream& operator<<(std::wostream& os, const raw_term& t); -std::wostream& operator<<(std::wostream& os, - const std::pair& p); -std::wostream& operator<<(std::wostream& os, const raw_rule& r); -std::wostream& operator<<(std::wostream& os, const raw_prog& p); -std::wostream& operator<<(std::wostream& os, const raw_progs& p); -std::wostream& operator<<(std::wostream& os, const lexeme& l); -std::wostream& operator<<(std::wostream& os, const production& p); -lexeme lex(pcws s); -lexemes prog_lex(cws s); -std::wstring file_read(std::wstring fname); -std::wstring file_read_text(FILE *f); -std::wstring file_read_text(std::wstring fname); -off_t fsize(cws s, size_t len); -bool operator==(const lexeme& l, cws s); +void throw_runtime_error(std::string err, std::string details = ""); + +void parse_error(const char* o, const char* e, ccs s); +void parse_error(const char* o, const char* e, lexeme l); +void parse_error(ccs o, const char* e, std::string s); +void parse_error(ccs o, const char* e); +void parse_error(const char* e, lexeme l); +void parse_error(const char* e); + +template +std::basic_ostream& operator<<(std::basic_ostream& os, const directive& d); +template +std::basic_ostream& operator<<(std::basic_ostream& os, const elem& e); +template +std::basic_ostream& operator<<(std::basic_ostream& os, const raw_term& t); +template +std::basic_ostream& operator<<(std::basic_ostream& os, const std::pair& p); +template +std::basic_ostream& operator<<(std::basic_ostream& os, const raw_rule& r); +template +std::basic_ostream& operator<<(std::basic_ostream& os, const raw_prog& p); +template +std::basic_ostream& operator<<(std::basic_ostream& os, const raw_progs& p); +template +std::basic_ostream& operator<<(std::basic_ostream& os, const lexeme& l); +template +std::basic_ostream& operator<<(std::basic_ostream& os, const production& p); + +bool operator==(const lexeme& l, std::string s); +bool operator==(const lexeme& l, const char* s); bool operator<(const raw_term& x, const raw_term& y); bool operator<(const raw_rule& x, const raw_rule& y); void parser_test(); -#define lexeme2str(l) wstring((l)[0], (l)[1]-(l)[0]) -struct parse_error_exception : public virtual std::runtime_error { - using std::runtime_error::runtime_error; -}; +#define lexeme2str(l) string_t((l)[0], (l)[1]-(l)[0]) #endif diff --git a/src/main.cpp b/src/main.cpp index 5f94a5ac..80404707 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,6 +16,7 @@ #include #endif #include "driver.h" +#include "err.h" #ifdef WITH_THREADS #include "repl.h" #endif @@ -25,35 +26,43 @@ using namespace std; int main(int argc, char** argv) { setlocale(LC_ALL, ""); + inputs ii; outputs oo; - options o(argc, argv, &oo); - //o.parse(wstrings{ L"-autotype" }, true); - bdd::init(o.enabled(L"bdd-mmap") ? MMAP_WRITE : MMAP_NONE, - o.get_int(L"bdd-max-size"), ws2s(o.get_string(L"bdd-file"))); + options o(argc, argv, &ii, &oo); + //o.parse({ "-autotype" }, true); + bdd::init(o.enabled("bdd-mmap") ? MMAP_WRITE : MMAP_NONE, + o.get_int("bdd-max-size"), o.get_string("bdd-file")); // read from stdin by default if no -i(e), -h, -v and no -repl/udp - if (o.disabled(L"i") && o.disabled(L"ie") + if (o.disabled("i") && o.disabled("ie") #ifdef WITH_THREADS - && o.disabled(L"repl") && o.disabled(L"udp") + && o.disabled("repl") && o.disabled("udp") #endif - && o.disabled(L"h") && o.disabled(L"v")) - o.parse(wstrings{ L"-i", L"@stdin" }, true); + && o.disabled("h") && o.disabled("v")) + o.parse(strings{ "-i", "@stdin" }, true); #ifdef WITH_THREADS - if (o.enabled(L"udp") && o.disabled(L"repl")) o.enable(L"repl"); - if (o.enabled(L"repl")) repl r(o); + if (o.enabled("udp") && o.disabled("repl")) o.enable("repl"); + if (o.enabled("repl")) repl r(o); else { #endif - driver d(o); - wstring archive_file = o.get_string(L"load"); - if (archive_file != L"") d.load(archive_file); - d.run((size_t)o.get_int(L"steps"), - (size_t)o.get_int(L"break"), - o.enabled(L"break-on-fp")); - archive_file = o.get_string(L"save"); - if (archive_file != L"") d.save(archive_file); - if (o.enabled(L"dump") && d.result && - !d.out_goals(o::dump())) d.dump(); - if (o.enabled(L"dict")) d.out_dict(o::inf()); - if (o.enabled(L"csv")) d.save_csv(); + try { + driver d(o); + string archive_file = o.get_string("load"); + if (archive_file != "") d.load(archive_file); + d.run((size_t)o.get_int("steps"), + (size_t)o.get_int("break"), + o.enabled("break-on-fp")); + archive_file = o.get_string("save"); + if (archive_file != "") d.save(archive_file); + if (o.enabled("dump") && d.result && + !d.out_goals(o::dump())) d.dump(); + if (o.enabled("dict")) d.out_dict(o::inf()); + if (o.enabled("csv")) d.save_csv(); + + } catch (parse_error_exception &e) { + o::err() << e.what() << endl; + } catch (runtime_error_exception &e) { + o::err() << e.what() << endl; + } #ifdef WITH_THREADS } #endif diff --git a/src/memory_map.h b/src/memory_map.h index 01e4cf12..ee01e927 100644 --- a/src/memory_map.h +++ b/src/memory_map.h @@ -31,36 +31,37 @@ enum mmap_mode { MMAP_NONE, MMAP_READ, MMAP_WRITE }; class memory_map { public: - bool silent = false; // true to disable printing messages to o::err() + bool silent = true; // true to disable printing messages to o::err() bool error = false; - std::wstring error_message = L""; + std::string error_message = ""; memory_map() : mode_(MMAP_NONE),state_(CLOSED),filename_(""),size_(0) {} memory_map(std::string filename, size_t s=0, mmap_mode m = MMAP_READ, bool do_open=1, bool do_map=1) : mode_(m), state_(CLOSED), filename_(filename), size_(s) { if (mode_ == MMAP_NONE) return; - //DBG(o::dbg()<& a) : fn(a.fn), m(a.m) { } T* allocate(size_t n, const void *hint=0) { - //DBG(o::dbg()< -void options::set(const wstring &name, T val) { +void options::set(const string &name, T val) { option o; if (!get(name, o)) return; o.v.set(val); set(name, o); } -template void options::set(const std::wstring&, int_t); -template void options::set(const std::wstring&, std::wstring); +template void options::set(const std::string&, int_t); +template void options::set(const std::string&, std::string); -void options::enable (const wstring &name) { set(name, true ); } -void options::disable(const wstring &name) { set(name, false); } +void options::enable (const string &name) { set(name, true ); } +void options::disable(const string &name) { set(name, false); } -bool options::enabled(const wstring &name) const { +bool options::enabled(const string &name) const { option o; if (!get(name, o)) return false; switch (o.get_type()) { @@ -82,44 +82,44 @@ bool options::enabled(const wstring &name) const { case option::type::INT: return o.get_int() > 0; case option::type::STRING: { output* t = outputs::get(o.name()); - return t ? !t->is_null() : o.get_string() != L""; + return t ? !t->is_null() : o.get_string() != ""; } default: ; } return false; } -bool options::is_value(const wstrings &wargs, const size_t &i) { - if (i >= wargs.size()) return false; - else return wargs[i] == L"-" || - (wargs[i].rfind(L"---", 0) == 0) || - wargs[i][0] != L'-'; +bool options::is_value(const strings &sargs, const size_t &i) { + if (i >= sargs.size()) return false; + else return sargs[i] == "-" || + (sargs[i].rfind("---", 0) == 0) || + sargs[i][0] != '-'; } -bool options::parse_option(const wstrings &wargs, const size_t &i) { +bool options::parse_option(const strings &sargs, const size_t &i) { option o; bool disabled = false; bool skip_next = false; size_t pos = 0; - const wstring &arg = wargs[i]; - //DBG(o::out()<add_stdin(); + else ii->add_file(v.get_string()); + }).description("input (@stdin by default)")); + add(option(option::type::STRING, { "input-eval", "ie" }, [this](const option::value& v) { - add_input_data(v.get_string()); - }).description(L"input string to evaluate")); + ii->add_string(v.get_string()); + //COUT << "inputs.size now: " << ii->size() + // << " this: " << this << std::endl; + }).description("input string to evaluate")); #ifdef WITH_THREADS - add_bool(L"udp", L"open REPL on udp socket"); - add(option(option::type::STRING, {L"udp-addr", L"ua"}) - .description(L"IP address (udp)")); - add(option(option::type::INT, { L"udp-port", L"up" }) - .description(L"port (udp)")); - add_bool(L"repl", L"run TML in REPL mode"); - add_output (L"repl-output", L"repl output"); + add_bool("udp", "open REPL on udp socket"); + add(option(option::type::STRING, {"udp-addr", "ua"}) + .description("IP address (udp)")); + add(option(option::type::INT, { "udp-port", "up" }) + .description("port (udp)")); + add_bool("repl", "run TML in REPL mode"); + add_output ("repl-output", "repl output"); #endif - add_bool(L"sdt", L"sdt transformation"); - add_bool(L"bin", L"bin transformation"); - add_bool(L"proof", L"extract proof"); - add_bool(L"run", L"run program (enabled by default)"); - add_bool(L"csv", L"save result into CSV files"); + add_bool("sdt", "sdt transformation"); + add_bool("bin", "bin transformation"); + add_bool("proof", "extract proof"); + add_bool("run", "run program (enabled by default)"); + add_bool("csv", "save result into CSV files"); - add_bool(L"bdd-mmap",L"use memory mapping for BDD database"); - add(option(option::type::INT, { L"bdd-max-size" }).description( - L"Maximum size of a bdd memory map (default: 128 MB)")); - add(option(option::type::STRING, { L"bdd-file" }) - .description(L"Memory map file used for BDD database")); + add_bool("bdd-mmap","use memory mapping for BDD database"); + add(option(option::type::INT, { "bdd-max-size" }).description( + "Maximum size of a bdd memory map (default: 128 MB)")); + add(option(option::type::STRING, { "bdd-file" }) + .description("Memory map file used for BDD database")); - add(option(option::type::INT, { L"steps", L"s" }) - .description(L"run N steps")); - add(option(option::type::INT, { L"break", L"b" }) - .description(L"break on the N-th step")); - add_bool2(L"break-on-fp", L"bfp", L"break on a fixed point"); + add(option(option::type::INT, { "steps", "s" }) + .description("run N steps")); + add(option(option::type::INT, { "break", "b" }) + .description("break on the N-th step")); + add_bool2("break-on-fp", "bfp", "break on a fixed point"); - add_bool2(L"populate-tml_update", L"tml_update", - L"populates relation tml_update(N_step add|delete fact)."); - add_bool2(L"print-steps", L"ps", L"print steps"); - add_bool2(L"print-updates", L"pu", L"print updates"); - add_bool2(L"print-dict", L"dict", L"print internal string dictionary"); + add_bool2("populate-tml_update", "tml_update", + "populates relation tml_update(N_step add|delete fact)."); + add_bool2("print-steps", "ps", "print steps"); + add_bool2("print-updates", "pu", "print updates"); + add_bool2("print-dict", "dict", "print internal string dictionary"); - add_bool(L"optimize",L"optimize and show more benchmarks"); - add(option(option::type::STRING, { L"name", L"n" }, + add_bool("optimize","optimize and show more benchmarks"); + add(option(option::type::STRING, { "name", "n" }, [](const option::value& v) { outputs::name(v.get_string()); - }).description(L"name used for @name output")); - add(option(option::type::STRING, { L"load", L"l" }) - .description(L"load database from file before start")); - add(option(option::type::STRING, { L"save", L"s" }) - .description(L"save database to file after finish")); - add_output (L"dump", L"dump output (@stdout by default)"); - add_output_alt(L"output", L"o",L"standard output (@stdout by default)"); - add_output (L"error", L"errors (@stderr by default)"); - add_output (L"info", L"info (@null by default)"); - add_output (L"debug", L"debug output"); - add_output (L"benchmarks", L"benchmarking results (@null by default)"); - add_output_alt(L"transformed", L"t", L"transformation into clauses"); - add_output(L"xsb", L"attempt to translate program into XSB"); - add_output(L"swipl", L"attempt to translate program into SWI-Prolog"); - add_output(L"souffle", L"attempt to translate program into Souffle"); + }).description("name used for @name output")); + add(option(option::type::STRING, { "load", "l" }) + .description("load database from file before start")); + add(option(option::type::STRING, { "save", "s" }) + .description("save database to file after finish")); + add_output ("dump", "dump output (@stdout by default)"); + add_output_alt("output", "o","standard output (@stdout by default)"); + add_output ("error", "errors (@stderr by default)"); + add_output ("info", "info (@null by default)"); + add_output ("debug", "debug output"); + add_output ("benchmarks", "benchmarking results (@null by default)"); + add_output_alt("transformed", "t", "transformation into clauses"); + add_output("xsb", "attempt to translate program into XSB"); + add_output("swipl", "attempt to translate program into SWI-Prolog"); + add_output("souffle", "attempt to translate program into Souffle"); init_defaults(); } @@ -233,57 +226,56 @@ void options::setup() { #undef add_output_alt void options::init_defaults() { - parse({ - L"--run", - L"--output", L"@stdout", - L"--dump", L"@stdout", - L"--error", L"@stderr", + parse(strings{ + "--run", + "--output", "@stdout", + "--dump", "@stdout", + "--error", "@stderr", #ifdef DEBUG - L"--info", L"@stderr", - L"--benchmarks", L"@stderr", + "--info", "@stderr", + "--benchmarks", "@stderr", #endif - L"--optimize", - L"--bdd-max-size",L"134217728", // 128 MB + "--optimize", + "--bdd-max-size","134217728", // 128 MB #ifdef WITH_THREADS - L"--repl-output", L"@stdout", - L"--udp-addr", L"127.0.0.1", - L"--udp-port", L"6283" + "--repl-output", "@stdout", + "--udp-addr", "127.0.0.1", + "--udp-port", "6283" #endif }, true); - DBG(parse(wstrings{ L"--debug", L"@stderr" }, true);) + DBG(parse(strings{ "--debug", "@stderr" }, true);) } -void options::help(wostream& os) const { - os< +void options::help(std::basic_ostream& os) const { + os<<"Usage:\n"; + os<<"\ttml [options]\n"; + os<<"\n"; + os<<"options:\n"; + os<<"\tOptions are preceded by one or two hyphens (--run/-run).\n"; + os<<"\tDisable option by prefixing it with disable-, no- or dont-\n"; + os<<"\t\t(--disable-run/--no-run/--dont-run).\n"; + os<<"\n"; + for (auto oit : opts) oit.second.help(os)<<"\n"; + os<<"\n"; + os<<"bool:\n"; + os<<"\tEnabled if 'true', 't', '1', 'yes', 'on', 'enabled' or " + <<"if no argument.\n"; + os<<"\n"; + os<<"input:\n"; + os<<"\t[FILENAME | @stdin | - ]\n"; + os<<"\n"; + os<<"\t@stdin (or -) reads input from stdin\n"; + os<<"\tFILENAME inputs can be used more than once to concatenate " + <<"multiple files\n"; + os<<"\t--input can be combined with --input-eval too\n"; + os<<"\n"; + os<<"output:\n"; + os<<"\t[FILENAME | @stdout | @stderr | @name | @null | @buffer]\n"; + os<<"\n"; + os<<"\t@null\tdisable output\n"; + os<<"\t@stdout\tredirect to stdout\n"; + os<<"\t@stderr\tredirect to stderr\n"; + os<<"\t@buffer\tredirect to buffer to be read through API later\n"; + os<<"\t@name\tredirect to a file named by --name (ext predefined)\n"; } diff --git a/src/options.h b/src/options.h index 038f8856..11d880a6 100644 --- a/src/options.h +++ b/src/options.h @@ -15,37 +15,35 @@ #include #include #include "defs.h" +#include "input.h" #include "output.h" class archive; -typedef std::vector strings; -typedef std::vector wstrings; - struct option { friend class archive; enum type { UNDEFINED, INT, BOOL, STRING }; struct value { friend class archive; - value() : t(UNDEFINED) {} - value(int i) : t(INT), v_i(i) {} - value(bool b) : t(BOOL), v_b(b) {} - value(std::wstring s) : t(STRING), v_s(s) {} - void set(int i) { t=INT; v_i = i; } - void set(bool b) { t=BOOL; v_b = b; } - void set(std::wstring s) { t=STRING; v_s = s; } + value() : t(UNDEFINED) {} + value(int i) : t(INT), v_i(i) {} + value(bool b) : t(BOOL), v_b(b) {} + value(std::string s) : t(STRING), v_s(s) {} + void set(int i) { t=INT; v_i = i; } + void set(bool b) { t=BOOL; v_b = b; } + void set(std::string s) { t=STRING; v_s = s; } void null() { switch (t) { - case INT: v_i = 0; break; + case INT: v_i = 0; break; case BOOL: v_b = false; break; - case STRING: v_s = L""; break; + case STRING: v_s = ""; break; default: ; } } type get_type() const { return t; } - int get_int() const { return v_i; } - bool get_bool() const { return v_b; } - const std::wstring& get_string() const { return v_s; } + int get_int() const { return v_i; } + bool get_bool() const { return v_b; } + const std::string& get_string() const { return v_s; } bool is_undefined() const { return t == UNDEFINED; } bool is_int() const { return t == INT; } bool is_bool() const { return t == BOOL; } @@ -60,66 +58,67 @@ struct option { } } private: - type t; - int v_i = 0; - bool v_b = false; - std::wstring v_s = L""; + type t; + int v_i = 0; + bool v_b = false; + std::string v_s = ""; } v; typedef std::function callback; option() {} - option(type t, wstrings n, callback e, option::value v={}) + option(type t, strings n, callback e, option::value v={}) : v(v), t(t), n(n), e(e) {} - option(type t, wstrings n, option::value v={}) + option(type t, strings n, option::value v={}) : v(v), t(t), n(n), e(0) {} - const std::wstring& name() const { return n[0]; } - const wstrings& names() const { return n; } + const std::string& name() const { return n[0]; } + const strings& names() const { return n; } type get_type() const { return t; } value get() const { return v; } bool is_output () const { return outputs::exists(name()); } - bool is_input () const { return n[0]==L"input"||n[0]==L"i"; } + bool is_input () const { return n[0]=="input" || n[0]=="i"; } int get_int () const { return v.get_int(); }; bool get_bool () const { return v.get_bool(); }; - std::wstring get_string() const { return v.get_string(); }; + std::string get_string() const { return v.get_string(); }; bool operator ==(const value& ov) const { return v == ov; } bool operator ==(const option& o) const { return n == o.names(); } bool operator <(const option& o) const { return n < o.names(); } - void parse_value(const std::wstring& s) { - //DBG(o::out() << L"option::parse_value(s=\"" << s << - // L"\") <" << (int)t << L'>' << std::endl;) + void parse_value(const std::string& s) { + //DBG(o::out() << "option::parse_value(s=\"" << s << + // "\") <" << (int)t << '>' << std::endl;) switch (t) { - case INT: if (s != L"") v.set(std::stoi(s)); break; + case INT: if (s != "") v.set(std::stoi(s)); break; case BOOL: parse_bool(s); break; - case STRING: if (s != L"") v.set(s); - else if (is_output()) v.set(L"@stdout"); + case STRING: if (s != "") v.set(s); + else if (is_output()) v.set("@stdout"); break; default: throw 0; } if (e) e(v); } - void parse_bool(const std::wstring& s) { - if (s==L"" || s==L"true" || s==L"t" || s==L"1" || s==L"on" || - s==L"enabled" || s==L"yes") + void parse_bool(const std::string& s) { + if (s=="" || s=="true" || s=="t" || s=="1" || s=="on" || + s=="enabled" || s=="yes") return v.set(true), (void)0; v.set(false); - if (!(s==L"false" || s==L"f" || s==L"0" || s==L"off" || - s==L"disabled" || s==L"no")) - o::err() << L"Wrong bool argument: " << s << std::endl; + if (!(s=="false" || s=="f" || s=="0" || s=="off" || + s=="disabled" || s=="no")) + o::err() << "Wrong bool argument: " << s << std::endl; } void disable() { - if (STRING == get_type() && is_output()) parse_value(L"@null"); + if (STRING == get_type() && is_output()) parse_value("@null"); else v.null(); } bool is_undefined() const { return v.is_undefined(); } - option &description(const std::wstring& d) { return desc = d, *this; } - std::wostream& help(std::wostream& os) const { - std::wstringstream ss; ss << L""; + option &description(const std::string& d) { return desc = d, *this; } + template + std::basic_ostream& help(std::basic_ostream& os) const { + std::basic_ostringstream ss; ss << ""; long pos = ss.tellp(); - ss << L"\t"; + ss << "\t"; for (size_t i = 0; i != n.size(); ++i) { - if (i) ss << L","; - ss << L"--" << n[i]; + if (i) ss << ","; + ss << "--" << n[i]; } - ss << L" ["; + ss << " ["; switch (t) { case INT: ss << "number"; break; case BOOL: ss << "bool"; break; @@ -130,70 +129,73 @@ struct option { break; default: throw 0; } - ss << L']'; + ss << "]"; if (desc.size() > 0) { const long indent = 28; long to_write = indent-(((long)ss.tellp())-pos); - if (to_write > 0) while (to_write-- > 0) ss << L' '; - ss << L' ' << desc; + if (to_write > 0) while (to_write-- > 0) ss << " "; + ss << ' ' << desc; } return os << ss.str(); } private: type t; - wstrings n; // vector of name and alternative names (shortcuts) + strings n; // vector of name and alternative names (shortcuts) callback e; // callback with value as argument, fired when option parsed - std::wstring desc = L""; + std::string desc = ""; }; class options { friend class archive; public: - options() : options(0) { } - options(outputs *oo) : oo(oo) { setup(); } - options(int argc, char** argv, outputs *oo = 0) : oo(oo) { - setup(); parse(argc, argv); } - options(strings args, outputs *oo = 0) : oo(oo) { - setup(); parse(args); } - options(wstrings args, outputs *oo = 0) : oo(oo) { - setup(); parse(args); } + options() : options(0, 0) {} + options(inputs *ii, outputs *oo) : ii(ii), oo(oo) { setup(); } + options(int argc, char** argv, inputs *ii = 0, outputs *oo = 0) : + ii(ii), oo(oo) { setup(); parse(argc, argv); } + options(strings args, inputs *ii = 0, outputs *oo = 0): + ii(ii), oo(oo){ setup(); parse(args); } + options(wstrings args, inputs *ii = 0, outputs *oo = 0): + ii(ii), oo(oo){ setup(); parse(args); } int argc() const { return args.size(); } - std::wstring argv(int n) const { if (n - void set(const std::wstring &name, T val); + void set(const std::string &name, T val); void set_outputs(outputs* oo); void parse(int argc, char** argv, bool internal = false); - void parse(strings sargs, bool internal = false); - void parse(wstrings wargs, bool internal = false); - void enable(const std::wstring &arg); - void disable(const std::wstring &arg); - bool enabled (const std::wstring &arg) const; - bool disabled(const std::wstring &arg) const { return !enabled(arg); } - int get_int (std::wstring name) const; - bool get_bool (std::wstring name) const; - std::wstring get_string(std::wstring name) const; - void help(std::wostream& os) const; - const std::wstring& input() const { return input_data; } - void add_input_data(const std::wstring& data) { input_data += data; } + void parse(strings sargs, bool internal = false); + void parse(wstrings wargs, bool internal = false); + void enable(const std::string &arg); + void disable(const std::string &arg); + bool enabled (const std::string &arg) const; + bool disabled(const std::string &arg) const { return !enabled(arg); } + int get_int (std::string name) const; + bool get_bool (std::string name) const; + std::string get_string(std::string name) const; + template void help(std::basic_ostream&) const; + inputs* get_inputs() const { return ii; } private: - friend std::wostream& operator<<(std::wostream&, const options&); + template friend std::basic_ostream& operator<<(std::basic_ostream&, const options&); + inputs* ii; outputs* oo; - std::map opts = {}; - std::map alts = {}; - std::vector args; - std::wstring input_data = L""; - bool parse_option(const wstrings &wargs, const size_t &i); - bool is_value(const wstrings &wargs, const size_t &i); + std::map opts = {}; + std::map alts = {}; + std::vector args; + std::string input_data = ""; + bool parse_option(const strings &sargs, const size_t &i); + bool is_value(const strings &sargs, const size_t &i); void setup(); void init_defaults(); }; -std::wostream& operator<<(std::wostream&, const std::map&); -std::wostream& operator<<(std::wostream&, const option&); -std::wostream& operator<<(std::wostream&, const options&); +template +std::basic_ostream& operator<<(std::basic_ostream&, const std::map&); +template +std::basic_ostream& operator<<(std::basic_ostream&, const option&); +template +std::basic_ostream& operator<<(std::basic_ostream&, const options&); #endif diff --git a/src/output.cpp b/src/output.cpp index c2a2e01d..7615ac98 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -21,55 +21,57 @@ using namespace std; wostream wcnull(0); -const std::map output::type_names_ = { - { NONE, L"@null" }, - { STDOUT, L"@stdout" }, - { STDERR, L"@stderr" }, - { BUFFER, L"@buffer" }, - { NAME, L"@name" } +ostream cnull(0); + +const map output::type_names_ = { + { NONE, "@null" }, + { STDOUT, "@stdout" }, + { STDERR, "@stderr" }, + { BUFFER, "@buffer" }, + { NAME, "@name" } }; outputs* outputs::o_ = 0; namespace o { void init_defaults(outputs* oo) { oo->init_defaults(); } void use (outputs* oo) { oo->use(); } - wostream& to(const wstring& n) { return outputs::to(n); } - wostream& out() { return outputs::out(); } - wostream& err() { return outputs::err(); } - wostream& inf() { return outputs::inf(); } - wostream& dbg() { return outputs::dbg(); } + ostream_t& to(const string& n) { return outputs::to(n); } + ostream_t& out() { return outputs::out(); } + ostream_t& err() { return outputs::err(); } + ostream_t& inf() { return outputs::inf(); } + ostream_t& dbg() { return outputs::dbg(); } #ifdef WITH_THREADS - wostream& repl() { return outputs::repl(); } + ostream_t& repl() { return outputs::repl(); } #endif - wostream& ms() { return outputs::ms(); } - wostream& dump() { return outputs::dump(); } + ostream_t& ms() { return outputs::ms(); } + ostream_t& dump() { return outputs::dump(); } } -output::type_t output::get_type(std::wstring t) { - t = t == L"" ? L"@stdout" : t; +output::type_t output::get_type(string t) { + t = t == "" ? "@stdout" : t; for (auto& it : output::type_names_) if (it.second == t) return it.first; return FILE; } -output::type_t output::target(const std::wstring t) { - type_ = t == L"" ? STDOUT : get_type(t); +output::type_t output::target(const string t) { + type_ = t == "" ? STDOUT : get_type(t); bool open_path_before_finish = false; switch (type_) { - case NONE: os(&wcnull); break; - case STDOUT: os(&std::wcout); break; - case STDERR: os(&std::wcerr); break; + case NONE: os(&CNULL); break; + case STDOUT: os(&COUT); break; + case STDERR: os(&CERR); break; case BUFFER: - buffer_.str(L""); os(&buffer_); break; + buffer_.str(EMPTY_STRING); os(&buffer_); break; case NAME: { - std::wstring name = outputs::named(); + string name = outputs::named(); if (!name.size()) - return o::err()<name(); + string n = out->name(); auto it = find(n); if (it != end()) { - wcout << L"already exists: " << n << L" target: " << out->target() << endl; + CERR << "already exists: " << n << " target: " + << out->target() << endl; it->second->target(out->target()); out = it->second; } else emplace(n, out); @@ -110,33 +113,42 @@ bool outputs::add(sp_output out) { return true; } -wostream& outputs::to(const std::wstring& n) { +ostream_t& outputs::to(const string& n) { output* o = get(n); if (!o) throw 0; return o->os(); } -void outputs::target(const std::wstring& n, const std::wstring& t) { +void outputs::target(const string& n, const string& t) { output* o = get(n); if (o) o->target(t); else { - wcout << L"target not exists: " << n << endl, + CERR << "target does not exist: " << n << endl, throw 0; } } -wostream& operator<<(wostream& os, const pair& p) { +template +basic_ostream& operator<<(basic_ostream& os, const pair& p) { for (size_t n = 0; n != p.second; ++n) os << p.first[n]; return os; } +template basic_ostream& operator<<(basic_ostream&, const pair&); +template basic_ostream& operator<<(basic_ostream&, const pair&); -wostream& operator<<(wostream& os, const lexeme& l) { - for (cws s = l[0]; s != l[1]; ++s) os << *s; + +template +basic_ostream& operator<<(basic_ostream& os, const lexeme& l) { + for (ccs s = l[0]; s != l[1]; ++s) os << *s; + //DBG(os << " (" << (void*)l[0] << " " << (void*)l[1] << ")";) return os; } +template basic_ostream& operator<<(basic_ostream&, const lexeme&); +template basic_ostream& operator<<(basic_ostream&, const lexeme&); #ifdef DEBUG -/*wostream& bdd_out_ite(wostream& os, spbdd x, size_t dep) { +/*template +basic_ostream& bdd_out_ite(basic_ostream& os, spbdd x, size_t dep) { for (size_t n = 0; n != dep; ++n) os << '\t'; if (x->leaf()) return os << (x->trueleaf() ? 'T' : 'F') << endl; bdd_out_ite(os << "if " << x->v() << endl, x->h(), dep+1); @@ -144,69 +156,83 @@ wostream& operator<<(wostream& os, const lexeme& l) { return bdd_out_ite(os << "else" << endl, x->l(), dep+1); } -wostream& operator<<(wostream& os, spbdd x) { +template +basic_ostream& operator<<(basic_ostream& os, spbdd x) { if (x->leaf()) return os << (x->trueleaf() ? 'T' : 'F'); return os << x->v() << " ? " << x->h() << " : " << x->l(); }*/ -wostream& operator<<(wostream& os, const bools& x) { +template +basic_ostream& operator<<(basic_ostream& os, const bools& x) { for (auto y:x) os << (y?1:0); return os; } +template basic_ostream& operator<<(basic_ostream&, const bools&); +template basic_ostream& operator<<(basic_ostream&, const bools&); -wostream& operator<<(wostream& os, const vbools& x) { +template +basic_ostream& operator<<(basic_ostream& os, const vbools& x) { for (auto y:x) os << y << endl; return os; } +template basic_ostream& operator<<(basic_ostream&, const vbools&); +template basic_ostream& operator<<(basic_ostream&, const vbools&); -wostream& operator<<(wostream& os, const term& t) { - os << t.tab << L' '; - if (t.neg) os << L'~'; +template +basic_ostream& operator<<(basic_ostream& os, const term& t) { + os << t.tab << ' '; + if (t.neg) os << '~'; for (size_t n = 0; n != t.size(); ++n) { os << t[n]; - if (n != t.size()-1) os << L' '; + if (n != t.size()-1) os << ' '; } return os; } +template basic_ostream& operator<<(basic_ostream&, const term&); +template basic_ostream& operator<<(basic_ostream&, const term&); -/*wostream& operator<<(wostream& os, const matrix& m) { +/*template +basic_ostream& operator<<(basic_ostream& os, const matrix& m) { for (const term& t : m) os << t << ','; return os; } -wostream& operator<<(wostream& os, const matrices& m) { +template +basic_ostream& operator<<(basic_ostream& os, const matrices& m) { for (const matrix& x : m) os << x << endl; return os; }*/ #endif -/*wostream& driver::print_term(wostream& os, const term& t) const { +/*template +basic_ostream& driver::print_term(basic_ostream& os, const term& t) const { if (xsb) return print_term_xsb(os, t); - if (t.neg()) os << L'~'; - os << dict.get_rel(t.rel()) << L'('; + if (t.neg()) os << '~'; + os << dict.get_rel(t.rel()) << '('; for (size_t ar = 0, n = 0; ar != t.arity().size();) { - while (t.arity()[ar] == -1) ++ar, os << L'('; + while (t.arity()[ar] == -1) ++ar, os << '('; for (int_t k = 0; k != t.arity()[ar]; ++k) { if (t.arg(n) < 0) throw 0;//os<>2; - if (c == L'\r') os << "'\\r'"; - else if (c == L'\n') os << "'\\n'"; - else if (c == L'\t') os << "'\\t'"; - else os << L'\'' << c << L'\''; + char_t c = t.arg(n)>>2; + if (c == '\r') os << "'\\r'"; + else if (c == '\n') os << "'\\n'"; + else if (c == '\t') os << "'\\t'"; + else os << '\'' << c << '\''; } else if (t.arg(n) & 2) os << (int_t)(t.arg(n)>>2); else if ((size_t)(t.arg(n)>>2) < dict.nsyms()) os << dict.get_sym(t.arg(n)); - else os << L'[' << (t.arg(n)>>2) << L']'; - if (++n != t.nargs()) os << L' '; + else os << '[' << (t.arg(n)>>2) << ']'; + if (++n != t.nargs()) os << ' '; } ++ar; - while (ar +basic_ostream& driver::printmat(basic_ostream& os, const matrix& t) const { set s; for (auto v : t) { wstringstream ss; @@ -219,36 +245,44 @@ wostream& driver::printmat(wostream& os, const matrix& t) const { #ifdef DEBUG driver* drv; -wostream& printdb(wostream& os, lp *p) { return drv->printdb(os, p); } -wostream& printbdd(wostream& os, spbdd t, size_t bits, const prefix& p) { +template +basic_ostream& printdb(basic_ostream& os, lp *p) { return drv->printdb(os, p); } + +template +basic_ostream& printbdd(basic_ostream& os, spbdd t, size_t bits, const prefix& p) { //bdd_out(os<bits), t)<printbdd(os, t, bits, p); } -wostream& printbdd_one(wostream& os, spbdd t, size_t bits, const prefix& p) { +template +basic_ostream& printbdd_one(basic_ostream& os, spbdd t, size_t bits, const prefix& p) { return drv->printbdd_one(os, t, bits, p); } -wostream& driver::printbdd(wostream& os, spbdd t, size_t bits, const prefix&p) +template +basic_ostream& driver::printbdd(basic_ostream& os, spbdd t, size_t bits, const prefix&p) const { from_bits(t,bits,p,[&os,this](const term&t){ print_term(os, t)< +basic_ostream& driver::printbdd_one(basic_ostream& os, spbdd t, size_t bits, const prefix& p) const { // os << "one of " << bdd_count(t, bits * arlen(ar)) << " results: "; return print_term(os, one_from_bits(t, bits, p)); } #endif -wostream& driver::printdb(wostream& os, lp *p) const { +template +basic_ostream& driver::printdb(basic_ostream& os, lp *p) const { return printdb(os, p->db, p->rng.bits); } -wostream& driver::printdb(wostream& os, const db_t& db, size_t bits) const { +template +basic_ostream& driver::printdb(basic_ostream& os, const db_t& db, size_t bits) const { for (auto x : db) if (builtin_rels.find(x.first.rel) == builtin_rels.end()) { from_bits(x.second,bits,x.first, @@ -258,55 +292,67 @@ wostream& driver::printdb(wostream& os, const db_t& db, size_t bits) const { return os; }*/ -wostream& operator<<(wostream& os, const directive& d) { - os << L'@'; - if (d.type == directive::BWD) return os << L"bwd."; - if (d.type == directive::TRACE) return os << L"trace." << endl; - if (d.type == directive::STDOUT) os << L"stdout "; - else os << L"string "; - if (d.type == directive::TREE) return os << d.t << L'.'; - return os << d.rel << L' ' << d.arg << L'.'; -} - -wostream& operator<<(wostream& os, const elem& e) { +template +basic_ostream& operator<<(basic_ostream& os, const directive& d) { + os << '@'; + if (d.type == directive::BWD) return os << "bwd."; + if (d.type == directive::TRACE) return os << "trace." << endl; + if (d.type == directive::STDOUT) os << "stdout "; + else os << "string "; + if (d.type == directive::TREE) return os << d.t << '.'; + return os << d.rel << ' ' << d.arg << '.'; +} +template basic_ostream& operator<<(basic_ostream&, const directive&); +template basic_ostream& operator<<(basic_ostream&, const directive&); + +template +basic_ostream& operator<<(basic_ostream& os, const elem& e) { switch (e.type) { case elem::CHR: return os << '\'' << - (e.ch=='\'' || e.ch=='\\' ? L"\\" : L"") << e.ch<<'\''; + (e.ch=='\'' || e.ch=='\\' ? "\\" : "") << e.ch<<'\''; case elem::OPENP: case elem::CLOSEP: return os<<*e.e[0]; case elem::NUM: return os << e.num; default: return os << e.e; } } +template basic_ostream& operator<<(basic_ostream&, const elem&); +template basic_ostream& operator<<(basic_ostream&, const elem&); -wostream& operator<<(wostream& os, const production& p) { - os << p.p[0] << L" => "; - for (size_t n = 1; n < p.p.size(); ++n) os << p.p[n] << L' '; - return os << L'.'; +template +basic_ostream& operator<<(basic_ostream& os, const production& p) { + os << p.p[0] << " => "; + for (size_t n = 1; n < p.p.size(); ++n) os << p.p[n] << ' '; + return os << '.'; } +template basic_ostream& operator<<(basic_ostream&, const production&); +template basic_ostream& operator<<(basic_ostream&, const production&); -wstring quote_sym(const elem& e) { - std::wstringstream os, ss; +string quote_sym(const elem& e) { + stringstream os, ss; if (e.type == elem::SYM) { bool q{false}; - for (cws s = e.e[0]; s != e.e[1]; ++s) { - if (!q && !iswalnum(*s) && *s != L'_') { + for (ccs s = e.e[0]; s != e.e[1]; ++s) { + if (!q && !isalnum(*s) && *s != '_') { q = true; - os << L'"'; + os.put('"'); } - if (q && (*s==L'"'|| *s==L'\\')) ss << L"\\"; + if (q && (*s=='"'|| *s=='\\')) ss << "\\"; ss << *s; } os << ss.str(); - if (q) os << L'"'; - else if (e.e[0] == e.e[1]) os << L"\"\""; - } else - os << e; // CHR, OPENP, CLOSEP or NUM = no quotes + if (q) os.put('"'); + else if (e.e[0] == e.e[1]) os << "\"\""; + } else { + ostringstream_t wss; wss << e; + os << ws2s(wss.str()); // CHR, OPENP, CLOSEP or NUM = no quotes + } return os.str(); } -wostream& operator<<(wostream& os, const raw_term& t) { - if (t.neg) os << L'~'; +template +basic_ostream& operator<<(basic_ostream& os, const raw_term& t) { + if (t.neg) os << '~'; if( t.extype == raw_term::ARITH || t.extype == raw_term::EQ || @@ -317,139 +363,176 @@ wostream& operator<<(wostream& os, const raw_term& t) { } os << t.e[0]; - os << L'('; + os << '('; for (size_t ar = 0, n = 1; ar != t.arity.size();) { - while (t.arity[ar] == -1) ++ar, os << L'('; + while (t.arity[ar] == -1) ++ar, os << '('; if (n >= t.e.size()) break; while (t.e[n].type == elem::OPENP) ++n; for (int_t k = 0; k != t.arity[ar];) if ((os << quote_sym(t.e[n++])), ++k != t.arity[ar]) - os << L' '; + os << ' '; while (n < t.e.size() && t.e[n].type == elem::CLOSEP) ++n; ++ar; - while (ar < t.arity.size() && t.arity[ar] == -2) ++ar, os<& operator<<(basic_ostream&, const raw_term&); +template basic_ostream& operator<<(basic_ostream&, const raw_term&); -wostream& operator<<(wostream& os, const std::pair& p) { +template +basic_ostream& operator<<(basic_ostream& os, const pair& p) { const raw_term& t = p.first; - //if (t.neg) os << L'~'; + //if (t.neg) os << '~'; //os << t.e[0]; - //os << L'('; + //os << '('; for (size_t ar = 0, n = 1; ar != t.arity.size();) { - while (t.arity[ar] == -1) ++ar, os << L'('; + while (t.arity[ar] == -1) ++ar, os << '('; if (n >= t.e.size()) break; while (t.e[n].type == elem::OPENP) ++n; for (int_t k = 0; k != t.arity[ar];) if ((os << quote_sym(t.e[n++])), ++k != t.arity[ar]) - os << L' '; + os << ' '; while (n < t.e.size() && t.e[n].type == elem::CLOSEP) ++n; ++ar; - while (ar < t.arity.size() && t.arity[ar] == -2) ++ar, os << L')'; + while (ar < t.arity.size() && t.arity[ar] == -2) ++ar, os << ')'; } - return os; // << L')'; + return os; // << ')'; } +template basic_ostream& operator<<(basic_ostream&, const pair&); +template basic_ostream& operator<<(basic_ostream&, const pair&); -wostream& operator<<(wostream& os, const raw_rule& r) { +template +basic_ostream& operator<<(basic_ostream& os, const raw_rule& r) { switch (r.type) { - case raw_rule::GOAL: os << L'!'; break; - case raw_rule::TREE: os << L"!!"; break; + case raw_rule::GOAL: os << '!'; break; + case raw_rule::TREE: os << "!!"; break; default: ; } for (size_t n = 0; n < r.h.size(); ++n) - if ((os << r.h[n]), n != r.h.size() - 1) os << L','; - if (!r.b.size()) return os << L'.'; - os << L" :- " << endl; + if ((os << r.h[n]), n != r.h.size() - 1) os << ','; + if (!r.b.size()) return os << '.'; + os << " :- " << endl; for (size_t n = 0; n < r.b.size(); ++n) { for (size_t k = 0; k < r.b[n].size(); ++k) if ((os << '\t' << r.b[n][k]), k != r.b[n].size() - 1) - os << L',' << endl; - if (n != r.b.size() - 1) os << L';' << endl; + os << ',' << endl; + if (n != r.b.size() - 1) os << ';' << endl; } - return os << L'.'; + return os << '.'; } +template basic_ostream& operator<<(basic_ostream&, const raw_rule&); +template basic_ostream& operator<<(basic_ostream&, const raw_rule&); -wostream& operator<<(wostream& os, const raw_prog& p) { +template +basic_ostream& operator<<(basic_ostream& os, const raw_prog& p) { for (auto x : p.d) os << x << endl; for (auto x : p.g) os << x << endl; for (auto x : p.r) os << x << endl; return os; } +template basic_ostream& operator<<(basic_ostream& os, const raw_prog& p); +template basic_ostream& operator<<(basic_ostream& os, const raw_prog& p); + -wostream& operator<<(wostream& os, const raw_progs& p) { +template +basic_ostream& operator<<(basic_ostream& os, const raw_progs& p) { if (p.p.size() == 1) os << p.p[0]; - else for (auto x : p.p) os << L'{' << endl << x << L'}' << endl; + else for (auto x : p.p) os << '{' << endl << x << '}' << endl; return os; } +template basic_ostream& operator<<(basic_ostream& os, const raw_progs& p); +template basic_ostream& operator<<(basic_ostream& os, const raw_progs& p); -wostream& operator<<(wostream& os, const output& o) { +template +basic_ostream& operator<<(basic_ostream& os, const output& o) { return os << o.target(); } +template basic_ostream& operator<<(basic_ostream&, const output&); +template basic_ostream& operator<<(basic_ostream&, const output&); -wostream& operator<<(wostream& os, const option& o) { +template +basic_ostream& operator<<(basic_ostream& os, const option& o) { if (o.is_undefined()) return os; - os << L"--" << o.name() << L' '; + os << "--" << o.name() << ' '; switch (o.get_type()) { case option::type::INT: { int i = o.get_int(); - return os << (i < 0 ? L"--":L"") << i; + return os << (i < 0 ? "--":"") << i; } case option::type::BOOL: - return os << (o.get_bool() ?L"":L"false"); + return os << (o.get_bool() ?"":"false"); case option::type::STRING: { - wstring s = o.get_string(); - if (s != L"-" && s.rfind(L"-", 0) == 0) os << L"--"; - os << L'"'; + string s = o.get_string(); + if (s != "-" && s.rfind("-", 0) == 0) os << "--"; + os << '"'; for (auto it = s.begin(); it < s.end(); ++it) - os << (*it == '\\' || *it == '"' ? L"\\" : L""), + os << (*it == '\\' || *it == '"' ? "\\" : ""), os << *it; - return os << L'"'; + return os << '"'; } break; default: ; } return os; } +template basic_ostream& operator<<(basic_ostream&, const option&); +template basic_ostream& operator<<(basic_ostream&, const option&); -wostream& operator<<(wostream& os, const std::map& opts) { +template +basic_ostream& operator<<(basic_ostream& os, const map& opts) { bool t = false; for (auto it : opts) { if (!it.second.is_undefined()) - os << (t ? L" " : L"") << it.second, t = true; + os << (t ? " " : "") << it.second, t = true; } return os; } +template basic_ostream& operator<<(basic_ostream&, const map&); +template basic_ostream& operator<<(basic_ostream&, const map&); -wostream& operator<<(wostream& os, const options& o) { return os << o.opts; } +template +basic_ostream& operator<<(basic_ostream& os, const options& o) { return os << o.opts; } +template basic_ostream& operator<<(basic_ostream&, const options&); +template basic_ostream& operator<<(basic_ostream&, const options&); -void tables::print(wostream& os, const tables::proof_elem& e) { - if (e.rl != (size_t)-1) os << L'[' << e.rl << L',' << e.al << L"] "; +template +void tables::print(basic_ostream& os, const tables::proof_elem& e) { + if (e.rl != (size_t)-1) os << '[' << e.rl << ',' << e.al << "] "; for (const auto& b : e.b) - os << b.first << L' ' << to_raw_term(b.second) << L' '; + os << b.first << ' ' << to_raw_term(b.second) << ' '; os << endl; } +template void tables::print(basic_ostream&, const tables::proof_elem&); +template void tables::print(basic_ostream&, const tables::proof_elem&); -void tables::print(wostream& os, const tables::proof& p) { +template +void tables::print(basic_ostream& os, const tables::proof& p) { for (size_t n = 0; n != p.size(); ++n) for (const auto& x : p[n]) { for (const auto& y : x.second) - (os<(basic_ostream&, const tables::proof&); +template void tables::print(basic_ostream&, const tables::proof&); #ifdef DEBUG -void tables::print(wostream& os, const tables::witness& w) { - os << L'[' << w.rl << L',' << w.al << L"] "; - for (const term& t : w.b) os << to_raw_term(t) << L", "; - os << L'.'; +template +void tables::print(basic_ostream& os, const tables::witness& w) { + os << '[' << w.rl << ',' << w.al << "] "; + for (const term& t : w.b) os << to_raw_term(t) << ", "; + os << '.'; } + +template void tables::print(basic_ostream&, const tables::witness&); +template void tables::print(basic_ostream&, const tables::witness&); #endif /*void tables::print_env(const env& e) const { for (auto x : e) { int_t arg = r[n - 1]; - if (arg & 1) rt.e[n]=elem((wchar_t)(arg>>2)); + if (arg & 1) rt.e[n]=elem((char_t)(arg>>2)); else if (arg & 2) rt.e[n]=elem((int_t)(arg>>2)); else rt.e[n]=elem(elem::SYM, dict.get_sym(arg)); o::out() << x.first << " = " << x.second << endl; @@ -458,29 +541,35 @@ void tables::print(wostream& os, const tables::witness& w) { }*/ // rule printer for --print_updates -wostream& tables::print(wostream& os, const rule& r) const { - os << to_raw_term(r.t) << L" :- "; +template +basic_ostream& tables::print(basic_ostream& os, const rule& r) const { + os << to_raw_term(r.t) << " :- "; for (auto it = r.begin(); it != r.end(); ++it) for (size_t n = 0; n != (*it)->t.size(); ++n) os << to_raw_term((*it)->t[n]) << (n==(*it)->t.size()-1 - ? it == r.end()-1 ? L"." : L"; " - : L", "); + ? it == r.end()-1 ? "." : "; " + : ", "); return os; } +template basic_ostream& tables::print(basic_ostream&, const rule&) const; +template basic_ostream& tables::print(basic_ostream&, const rule&) const; -wostream& operator<<(wostream& os, const dict_t& d) { - os << L"# nrels: " << d.nrels() << L'\t'; +template +basic_ostream& operator<<(basic_ostream& os, const dict_t& d) { + os << "# nrels: " << d.nrels() << '\t' << flush; for (size_t i = 0; i != d.nrels(); ++i) - os << i << L":" << d.get_rel(i) - << (i != d.nrels() - 1 ? L", " : L""); - os << L"\n# nsyms: " << d.nsyms() << L'\t' << std::flush; + os << i << ":" << d.get_rel(i) + << (i != d.nrels() - 1 ? ", " : ""); + os << "\n# nsyms: " << d.nsyms() << '\t' << flush; for (size_t i = 0; i != d.nsyms(); ++i) - os << i << L":" << d.get_sym(i<<2) - << (i != d.nsyms() - 1 ? L", " : L""); - os << L"\n# nvars: " << d.nvars() << L'\t'; - os << L"\n# nbltins: " << d.nbltins() << L'\t'; + os << i << ":" << d.get_sym(i<<2) + << (i != d.nsyms() - 1 ? ", " : ""); + os << "\n# nvars: " << d.nvars() << '\t'; + os << "\n# nbltins: " << d.nbltins() << '\t' << flush; for (size_t i = 0; i != d.nbltins(); ++i) - os << i << L":" << d.get_bltin(i) - << (i != d.nbltins() - 1 ? L", " : L""); + os << i << ":" << d.get_bltin(i) + << (i != d.nbltins() - 1 ? ", " : ""); return os << endl; } +template basic_ostream& operator<<(basic_ostream&, const dict_t&); +template basic_ostream& operator<<(basic_ostream&, const dict_t&); diff --git a/src/output.h b/src/output.h index e2d33570..2eede147 100644 --- a/src/output.h +++ b/src/output.h @@ -19,114 +19,112 @@ #include #include "defs.h" -extern std::wostream wcnull; - class output { public: enum type_t { NONE, STDOUT, STDERR, FILE, BUFFER, NAME }; - output(std::wstring n, std::wstring t = L"", std::wstring e = L"") - : os_(&wcnull), file_(), buffer_(L""), - name_(n), ext_(e), path_(L""), type_(target(t)) { } - std::wstring name() const { return name_; } - std::wstring path() const { return path_; } + output(const std::string n, const std::string t = "", std::string e = "") + : os_(&CNULL), file_(), buffer_(), + name_(n), ext_(e), path_(""), type_(target(t)) { } + std::string name() const { return name_; } + std::string path() const { return path_; } type_t type() const { return type_; } - std::wostream& os() { return *os_; } - std::wstring target() const { + ostream_t& os() { return *os_; } + std::string target() const { return (type_ == FILE) ? path_ : type_name(type_); } - type_t target(const std::wstring t); - std::wstring read() { - return type_ == BUFFER ? buffer_.str() : L""; } + type_t target(const std::string t); + sysstring_t read() { + return type_ == BUFFER ? buffer_.str() : sysstring_t(); } bool is_null() const { return type_ == NONE; } template output& operator<<(const T& value) { *os_ << value; return *this; } - static type_t get_type(std::wstring t); - static std::wstring type_name(type_t t) { return type_names_.at(t); } - static std::shared_ptr create(std::wstring n, - std::wstring t = L"", std::wstring e = L"") { + static type_t get_type(std::string t); + static std::string type_name(type_t t) { return type_names_.at(t); } + static std::shared_ptr create(std::string n, + std::string t = "", std::string e = "") { return std::make_shared(n, t, e); } private: - std::wostream* os_; // output stream - std::wofstream file_; // file stream output - std::wostringstream buffer_; // buffer stream output - std::wstring name_; // name of the output stream - std::wstring ext_; // filename extension - std::wstring path_; // file path + ostream_t* os_; // output stream + ofstream_t file_; // file stream output + ostringstream_t buffer_; // buffer stream output + std::string name_; // name of the output stream + std::string ext_; // filename extension + std::string path_; // file path type_t type_ = NONE; - std::wostream& os(std::wostream* s) { os_ = s; return *os_; } - static const std::map type_names_; + ostream_t& os(ostream_t* s) { os_ = s; return *os_; } + static const std::map type_names_; }; using p_output = output*; using sp_output = std::shared_ptr; -using outputmap = std::map; +using outputmap = std::map; class outputs : public outputmap { public: outputs() : outputmap() { if (!o_) { o_ = this; init_defaults(); } } bool add(sp_output o); void use() { o_ = this; } - void update_pointers(const std::wstring& n, output* o); - void create(std::wstring n, std::wstring e, std::wstring t = L"@null") { + void update_pointers(const std::string& n, output* o); + void create(std::string n, std::string e, std::string t = "@null") { add(output::create(n, t, e)); } void init_defaults() { - create(L"output", L".out.tml"); - create(L"error", L".error.log"); - create(L"info", L".info.log"); - create(L"debug", L".debug.log"); - create(L"dump", L".dump.tml"); - create(L"benchmarks", L".bench.log"); - create(L"transformed", L".trans.tml"); + create("output", ".out.tml"); + create("error", ".error.log"); + create("info", ".info.log"); + create("debug", ".debug.log"); + create("dump", ".dump.tml"); + create("benchmarks", ".bench.log"); + create("transformed", ".trans.tml"); #ifdef WITH_THREADS - create(L"repl-output", L".repl.out.log"); + create("repl-output", ".repl.out.log"); #endif - create(L"xsb", L".P"); - create(L"swipl", L".pl"); - create(L"souffle", L".souffle"); + create("xsb", ".P"); + create("swipl", ".pl"); + create("souffle", ".souffle"); } static outputs* in_use() { return o_; } - static std::wostream& out() { return o_to(o_->out_); } - static std::wostream& err() { return o_to(o_->err_); } - static std::wostream& inf() { return o_to(o_->inf_); } - static std::wostream& dbg() { return o_to(o_->dbg_); } + static ostream_t& out() { return o_to(o_->out_); } + static ostream_t& err() { return o_to(o_->err_); } + static ostream_t& inf() { return o_to(o_->inf_); } + static ostream_t& dbg() { return o_to(o_->dbg_); } #ifdef WITH_THREADS - static std::wostream& repl() { return o_to(o_->repl_); } + static ostream_t& repl() { return o_to(o_->repl_); } #endif - static std::wostream& ms() { return o_to(o_->ms_); } - static std::wostream& dump() { return o_to(o_->dump_); } - static output* get(const std::wstring& n) { return o_->o_get(n); } - static std::wostream& to(const std::wstring& n); - static bool exists(const std::wstring& n) { return o_->o_exists(n); } - static std::wstring read(const std::wstring& n) {return get(n)->read();} - static void target(const std::wstring& n, const std::wstring& t); - static void name(std::wstring n) { o_->name_ = n; } - static std::wstring named() { return o_->name_; } + static ostream_t& ms() { return o_to(o_->ms_); } + static ostream_t& dump() { return o_to(o_->dump_); } + static output* get(const std::string& n) { return o_->o_get(n); } + static ostream_t& to(const std::string& n); + static bool exists(const std::string& n) { return o_->o_exists(n); } + static sysstring_t read(const std::string& n) { return get(n)->read();} + static void target(const std::string& n, const std::string& t); + static void name(std::string n) { o_->name_ = n; } + static std::string named() { return o_->name_; } private: output *out_=0, *err_=0, *inf_=0, *dbg_=0, *ms_=0, *dump_=0; #ifdef WITH_THREADS output *repl_=0; #endif - std::wstring name_ = L""; + std::string name_ = ""; static outputs* o_; // global outputs - p_output o_get(std::wstring n) { + p_output o_get(std::string n) { auto it = find(n); return it != end() ? it->second.get() : 0; } - bool o_exists(const std::wstring nam) { return find(nam) != end(); } - static std::wostream& o_to(output* x) { return x ? x->os() : wcnull; } + bool o_exists(const std::string nam) { return find(nam) != end(); } + static ostream_t& o_to(output* x) { return x ? x->os() : CNULL; } }; namespace o { // o:: namespace shortcuts void init_defaults(outputs* oo); void use (outputs* oo); - std::wostream& to(const std::wstring& n); - std::wostream& out(); - std::wostream& err(); - std::wostream& inf(); - std::wostream& dbg(); + ostream_t& to(const std::string& n); + ostream_t& out(); + ostream_t& err(); + ostream_t& inf(); + ostream_t& dbg(); #ifdef WITH_THREADS - std::wostream& repl(); + ostream_t& repl(); #endif - std::wostream& ms(); - std::wostream& dump(); + ostream_t& ms(); + ostream_t& dump(); } #endif diff --git a/src/print_prolog.cpp b/src/print_prolog.cpp index 14382d16..f40d9c71 100644 --- a/src/print_prolog.cpp +++ b/src/print_prolog.cpp @@ -14,75 +14,91 @@ #include "driver.h" using namespace std; -typedef pair relarity; +typedef pair relarity; typedef set relarities; relarity get_relarity(const raw_term& t); void get_relarities(const raw_prog& p, relarities& ras); -wostream& output_prolog_rule(wostream& os, const raw_rule& r); -wostream& output_prolog_term(wostream& os, const raw_term& t); -wostream& output_prolog_elem(wostream& os, const elem& e); +template +std::basic_ostream& output_prolog_rule(std::basic_ostream&, const raw_rule& r); +template +std::basic_ostream& output_prolog_term(std::basic_ostream&, const raw_term& t); +template +std::basic_ostream& output_prolog_elem(std::basic_ostream&, const elem& e); -#define output_lexeme_adjust_first(os, l, fn) (os) << (wchar_t)fn(*((l)[0])) <<\ +#define output_lexeme_adjust_first(os, l, fn) (os) << (syschar_t)fn(*((l)[0])) <<\ ((l)[1]-((l)[0]+1)>0 ? lexeme{(l)[0]+1,(l)[1]} : lexeme{(l)[0], (l)[0]}) -wostream& driver::print_xsb(wostream& os, const raw_prog& rp) const { +template +std::basic_ostream& driver::print_xsb(std::basic_ostream& os, + const raw_prog& rp) const +{ return print_prolog(os, rp, XSB); } +template ostream_t& driver::print_xsb(ostream_t& os, const raw_prog&) const; -wostream& driver::print_swipl(wostream& os, const raw_prog& rp) const { +template +std::basic_ostream& driver::print_swipl(std::basic_ostream& os, + const raw_prog& rp) const +{ return print_prolog(os, rp, SWIPL); } +template ostream_t& driver::print_swipl(ostream_t& os, const raw_prog&) const; -wostream& driver::print_prolog(wostream& os, const raw_prog& p, - const prolog_dialect d) const { +template +std::basic_ostream& driver::print_prolog(std::basic_ostream& os, + const raw_prog& p, prolog_dialect d) const +{ relarities ras; get_relarities(p, ras); - wstring name = d == SWIPL ? L"SWI Prolog" : L"XSB"; - os << L"% start of " << name << " program" << endl; + string name = d == SWIPL ? "SWI Prolog" : "XSB"; + os << "% start of " << name << " program" << endl; os << endl; - os << L"% enable tabling to avoid inf. loops" << endl; - for (auto ra : ras) os << L":- table " << ra.first << - L'/' << ra.second << L'.' << endl; + os << "% enable tabling to avoid inf. loops" << endl; + for (auto ra : ras) os << ":- table " << ra.first << + '/' << ra.second << '.' << endl; os << endl; if (d == SWIPL) { - os << L"% suppress singleton warnings" << endl; - os << L":- style_check(-singleton)." << endl; + os << "% suppress singleton warnings" << endl; + os << ":- style_check(-singleton)." << endl; os << endl; - os << L"% enable discontiguation" << endl; - for (auto ra : ras) os << L":- discontiguous " << ra.first << - L'/' << ra.second << L'.' << endl, + os << "% enable discontiguation" << endl; + for (auto ra : ras) os << ":- discontiguous " << ra.first << + '/' << ra.second << '.' << endl, //for (auto ra : ras) - os << L":- discontiguous '" << ra.first << - L" tabled'" << L'/' << ra.second << L'.' << endl; + os << ":- discontiguous '" << ra.first << + " tabled'" << '/' << ra.second << '.' << endl; os << endl; - os << L"% declare dynamic predicates" << endl; - for (auto ra : ras) os << L":- dynamic '" << ra.first << - L" tabled'" << L'/' << ra.second << L'.' << endl; + os << "% declare dynamic predicates" << endl; + for (auto ra : ras) os << ":- dynamic '" << ra.first << + " tabled'" << '/' << ra.second << '.' << endl; os << endl; } - os << L"% {" << endl; + os << "% {" << endl; for (auto x : p.r) output_prolog_rule(os, x) << endl; - os << L"% }" << endl; + os << "% }" << endl; os << endl; - os << L"% find all and dump to stdout" << endl; - os << L"dump_list([])." << endl; - os << L"dump_list([H|T]) :- writeln(H), dump_list(T)."<< endl; - os << L"dump(Q) :- findall(Q, Q, X), dump_list(X)." << endl; + os << "% find all and dump to stdout" << endl; + os << "dump_list([])." << endl; + os << "dump_list([H|T]) :- writeln(H), dump_list(T)."<< endl; + os << "dump(Q) :- findall(Q, Q, X), dump_list(X)." << endl; for (auto ra : ras) { - os << L":- dump(" << ra.first << L'('; - for(int_t i = 0; i != ra.second; ++i) os << (i ? L",_" : L"_"); - os << L"))." << endl; + os << ":- dump(" << ra.first << '('; + for(int_t i = 0; i != ra.second; ++i) os << (i ? ",_" : "_"); + os << "))." << endl; } os << endl; - os << L":- halt." << endl; + os << ":- halt." << endl; os << endl; - os << L"% end of "<< name << " program" << endl; + os << "% end of "<< name << " program" << endl; return os; } +template ostream_t& driver::print_prolog(ostream_t& os, const raw_prog&, + prolog_dialect) const; + relarity get_relarity(const raw_term& t) { - wstring rel = lexeme2str(t.e[0].e); + string rel = lexeme2str(t.e[0].e); rel[0] = towlower(rel[0]); int_t depth = 0, ar = t.arity[0]; if (ar == 0) @@ -102,60 +118,63 @@ void get_relarities(const raw_prog& p, relarities& ras) { } } -wostream& output_prolog_rule(wostream& os, const raw_rule& r) { +template +std::basic_ostream& output_prolog_rule(std::basic_ostream& os, const raw_rule& r) { switch (r.type) { - case raw_rule::GOAL: os << L"% !" << endl; break; - case raw_rule::TREE: os << L"% !!" << endl; break; + case raw_rule::GOAL: os << "% !" << endl; break; + case raw_rule::TREE: os << "% !!" << endl; break; default: ; } for (size_t n = 0; n < r.h.size(); ++n) if (output_prolog_term(os, r.h[n]), n != r.h.size() - 1) - os << L','; - if (!r.b.size()) return os << L'.'; - os << L" :- "; + os << ','; + if (!r.b.size()) return os << '.'; + os << " :- "; for (size_t m = 0; m < r.b.size(); ++m) { for (size_t n = 0; n < r.b[m].size(); ++n) if (output_prolog_term(os, r.b[m][n]), - n != r.b[m].size() - 1) os << L','; - if (m != r.b.size() - 1) os << L';'; + n != r.b[m].size() - 1) os << ','; + if (m != r.b.size() - 1) os << ';'; } - return os << L'.'; + return os << '.'; } -wostream& output_prolog_term(wostream& os, const raw_term& t) { - if (t.neg) os << L'~'; +template +std::basic_ostream& output_prolog_term(std::basic_ostream& os, const raw_term& t) { + if (t.neg) os << '~'; output_prolog_elem(os, t.e[0]); - os << L'('; + os << '('; for (size_t ar = 0, n = 1; ar != t.arity.size();) { - while (t.arity[ar] == -1) ++ar, os << L'('; + while (t.arity[ar] == -1) ++ar, os << '('; if (n >= t.e.size()) break; while (t.e[n].type == elem::OPENP) ++n; for (int_t k = 0; k != t.arity[ar];) if (output_prolog_elem(os,t.e[n++]), ++k != t.arity[ar]) - os << L", "; + os << ", "; while (n < t.e.size() && t.e[n].type == elem::CLOSEP) ++n; ++ar; while (ar < t.arity.size() && t.arity[ar] == -2) - ++ar, os << L')'; + ++ar, os << ')'; if (ar > 0 && t.arity[ar-1] == -2 && ar != t.arity.size()) os << ", "; } - return os << L')'; + return os << ')'; } -wostream& output_prolog_elem(wostream& os, const elem& e) { +template +std::basic_ostream& output_prolog_elem(std::basic_ostream& os, const elem& e) { switch (e.type) { case elem::CHR: os << '\''; switch (e.ch) { - case L'\'': - case L'\\': os << L'\\' << e.ch; break; - case L'\r': os << L"\\r"; break; - case L'\n': os << L"\\n"; break; - case L'\t': os << L"\\t"; break; + case '\'': + case '\\': os << '\\' << e.ch; break; + case '\r': os << "\\r"; break; + case '\n': os << "\\n"; break; + case '\t': os << "\\t"; break; default: os << e.ch; } - return os << L'\''; + return os << '\''; case elem::VAR: return output_lexeme_adjust_first(os, (lexeme{ e.e[0]+1, e.e[1] }), towupper); case elem::OPENP: diff --git a/src/print_souffle.cpp b/src/print_souffle.cpp index f2857777..b9a5a4f7 100644 --- a/src/print_souffle.cpp +++ b/src/print_souffle.cpp @@ -14,60 +14,66 @@ #include "driver.h" using namespace std; -typedef pair relation_info; +typedef pair relation_info; typedef set relations_info; -map default_type_signatures; +map default_type_signatures; -wstring souffle_rel_name(wstring rel, bools p); +string souffle_rel_name(string rel, bools p); relation_info get_rel_info(const raw_term& t); relations_info get_rels_info(const raw_prog& p); -wostream& output_souffle_rule(wostream& os, const raw_rule& r); -wostream& output_souffle_term(wostream& os, const raw_term& t); -wostream& output_souffle_elem(wostream& os, const elem& e); +template +std::basic_ostream& output_souffle_rule(std::basic_ostream&, const raw_rule& r); +template +std::basic_ostream& output_souffle_term(std::basic_ostream&, const raw_term& t); +template +std::basic_ostream& output_souffle_elem(std::basic_ostream&, const elem& e); -wostream& driver::print_souffle(wostream& os, const raw_prog& p) const { +template +std::basic_ostream& driver::print_souffle(std::basic_ostream& os, const raw_prog& p) const { relations_info rels_info = get_rels_info(p); - os << L"// start of Souffle program" << endl; + os << "// start of Souffle program" << endl; os << endl; - os << L"// Following declaration types are autodetected!" << endl; - os << L"// Please review and correct declaration of your model:" < +std::basic_ostream& output_souffle_rule(std::basic_ostream& os, const raw_rule& r) { switch (r.type) { - case raw_rule::GOAL: os << L"// !" << endl; break; - case raw_rule::TREE: os << L"// !!" << endl; break; + case raw_rule::GOAL: os << "// !" << endl; break; + case raw_rule::TREE: os << "// !!" << endl; break; default: ; } for (size_t n = 0; n < r.h.size(); ++n) if (output_souffle_term(os, r.h[n]), n != r.h.size() - 1) - os << L','; - if (!r.b.size()) return os << L'.'; - os << L" :- "; + os << ','; + if (!r.b.size()) return os << '.'; + os << " :- "; for (size_t m = 0; m < r.b.size(); ++m) { for (size_t n = 0; n < r.b[m].size(); ++n) if (output_souffle_term(os, r.b[m][n]), - n != r.b[m].size() - 1) os << L','; - if (m != r.b.size() - 1) os << L';'; + n != r.b[m].size() - 1) os << ','; + if (m != r.b.size() - 1) os << ';'; } - return os << L'.'; + return os << '.'; } -wostream& output_souffle_term(wostream& os, const raw_term& t) { - if (t.neg) os << L'!'; +template +std::basic_ostream& output_souffle_term(std::basic_ostream& os, const raw_term& t) { + if (t.neg) os << '!'; relation_info ri = get_rel_info(t); - os << ri.first << L'('; + os << ri.first << '('; for (size_t ar = 0, n = 1; ar != t.arity.size();) { - while (t.arity[ar] == -1) ++ar, os << L'('; + while (t.arity[ar] == -1) ++ar, os << '('; if (n >= t.e.size()) break; while (t.e[n].type == elem::OPENP) ++n; for (int_t k = 0; k != t.arity[ar];) { if (output_souffle_elem(os,t.e[n++]), - ++k != t.arity[ar]) os << L", "; + ++k != t.arity[ar]) os << ", "; } while (n < t.e.size() && t.e[n].type == elem::CLOSEP) ++n; ++ar; - while (ar < t.arity.size() && t.arity[ar] == -2) ++ar, os< 0 && t.arity[ar-1] == -2 && ar != t.arity.size()) os << ", "; } - return os << L')'; + return os << ')'; } -wostream& output_souffle_elem(wostream& os, const elem& e) { +template +std::basic_ostream& output_souffle_elem(std::basic_ostream& os, const elem& e) { switch (e.type) { case elem::CHR: - os << L'"'; + os << '"'; switch (e.ch) { - case L'"': - case L'\\': os << L'\\' << e.ch; break; - case L'\r': os << L"\\r"; break; - case L'\n': os << L"\\n"; break; - case L'\t': os << L"\\t"; break; + case '"': + case '\\': os << '\\' << e.ch; break; + case '\r': os << "\\r"; break; + case '\n': os << "\\n"; break; + case '\t': os << "\\t"; break; default: os << e.ch; } - return os << L'"'; + return os << '"'; case elem::VAR: return os << lexeme{ e.e[0]+1, e.e[1] }; case elem::OPENP: case elem::CLOSEP: return os << *e.e[0]; case elem::NUM: return os << e.num; default: - return os << L'"' << e.e << L'"'; - // wstring el = lexeme2str(e.e); - // array symbols = { - // L"alpha", L"alnum", L"digit", L"space", - // L"printable" }; - // for (const wstring &symbol : symbols) + return os << '"' << e.e << '"'; + // string el = lexeme2str(e.e); + // array symbols = { + // "alpha", "alnum", "digit", "space", + // "printable" }; + // for (const string &symbol : symbols) // if (el.compare(symbol) == 0) - // return os << L'"' << e.e << L'"'; + // return os << '"' << e.e << '"'; // return os << e.e; } } diff --git a/src/proof.cpp b/src/proof.cpp index 4b01f1a2..236d67e4 100644 --- a/src/proof.cpp +++ b/src/proof.cpp @@ -97,7 +97,7 @@ const set& tables::explain(const term& q, proof& p, size_t level) { while ((s = get_witnesses(q, level)).empty()) if (!level--) return 0; bool f; for (const witness& w : s) { -// DBG(o::out()< +bool tables::get_goals(std::basic_ostream& os) { proof p(levels.size()); set s; for (const term& t : goals) @@ -153,7 +154,9 @@ bool tables::get_goals(wostream& os) { [&s](const term& t) { s.insert(t); }, t.size()); for (const term& g : s) if (bproof) get_proof(g, p, levels.size() - 1); - else os << to_raw_term(g) << L'.' << endl; + else os << to_raw_term(g) << '.' << endl; if (bproof) print(os, p); return goals.size() || bproof; } +template bool tables::get_goals(std::basic_ostream&); +template bool tables::get_goals(std::basic_ostream&); diff --git a/src/repl.cpp b/src/repl.cpp index 28e4aaed..956afcaf 100644 --- a/src/repl.cpp +++ b/src/repl.cpp @@ -17,14 +17,14 @@ using namespace std; -repl::repl(options &o, wostream& os) : o(o), os(os) { - os<(ws2s(addr), port); +repl::repl(options &o, ostream_t& os) : o(o), os(os) { + os<<"# TML REPL ("<(addr, port); if (up_udp->error()) { o::err() << up_udp->error_message() << endl; up_udp = 0; @@ -33,182 +33,247 @@ repl::repl(options &o, wostream& os) : o(o), os(os) { loop(); } -void repl::prompt(wostream& os) { - os << L"\n?- " << std::flush; +template +void repl::prompt(basic_ostream& os) { + os << "\n?- " << flush; } +template void repl::prompt(basic_ostream&); +template void repl::prompt(basic_ostream&); -void repl::redrive(wstring src) { +void repl::redrive(const string& src) { fin = false; - d = src == L"" - ? std::make_unique(o) - : std::make_unique(src, o); + d = src == "" + ? make_unique(o) + : make_unique(src, o); } -void repl::restart(wostream& os) { +template +void repl::restart(basic_ostream& os) { d->restart(); - os << L"# Restarted" << endl; + os << "# Restarted" << endl; } +template void repl::restart(basic_ostream& os); +template void repl::restart(basic_ostream& os); -void repl::reparse(wostream& os) { - wstringstream ss; +template +void repl::reparse(basic_ostream& os) { + ostringstream_t ss; d->list(ss); - redrive(ss.str()); - os << L"# Reparsed" << endl; + redrive(ws2s(ss.str())); + os << "# Reparsed" << endl; } +template void repl::reparse(basic_ostream&); +template void repl::reparse(basic_ostream&); -void repl::reset(wostream& os) { - redrive(); - os << L"# Reset" << endl; +template +void repl::reset(basic_ostream& os) { + redrive(""); + os << "# Reset" << endl; } +template void repl::reset(basic_ostream&); +template void repl::reset(basic_ostream&); -void repl::run(wostream& os, size_t steps, size_t break_on_step, +template +void repl::run(basic_ostream& os, size_t steps, size_t break_on_step, bool break_on_fp) { - os << L"# Running"; - if (steps) os << L" " << steps << L" step" << (steps==1?L"":L"s"); - if (break_on_step) os << L", break on step: "<run(steps, break_on_step, break_on_fp); if (ap) d->out(os); } +template void repl::run(basic_ostream&, size_t, size_t, bool); +template void repl::run(basic_ostream&, size_t, size_t, bool); -void repl::add(wostream& os, wstring line) { - os< +void repl::add(basic_ostream& os, string line) { + os<<"# Adding '"<add(line, ils); + inputs *ii = d->get_inputs(); + ii->add_string(line); + while (input *in = ii->next()) { + in->newseq = true; + d->add(*in); + } if (ar) run(os); } +template void repl::add(basic_ostream&, string); +template void repl::add(basic_ostream&, string); void repl::dump() { - os< +void repl::dump(basic_ostream& os) { d->out(os); } +template void repl::dump(basic_ostream& os); +template void repl::dump(basic_ostream& os); -void repl::info(wostream& os) { +template +void repl::info(basic_ostream& os) { d->info(os); - os<&); +template void repl::info(basic_ostream&); -void repl::print(wostream& os) { - d->out(os << L"# Printing database content:" << endl); +template +void repl::print(basic_ostream& os) { + d->out(os << "# Printing database content:" << endl); } +template void repl::print(basic_ostream&); +template void repl::print(basic_ostream&); -void repl::list(wostream&os, size_t p) { +template +void repl::list(basic_ostream& os, size_t p) { d->list(os, p); } +template void repl::list(basic_ostream&, size_t); +template void repl::list(basic_ostream&, size_t); -size_t parse_size_t(wstring l, wstring cmd) { +size_t parse_size_t(string l, string cmd) { try { - if (l.rfind(cmd, 0) == 0 && l[cmd.size()] == L' ') - return stoi(wstring(l.begin()+cmd.size()+1, l.end())); - } catch (...) { } + if (l.rfind(cmd, 0) == 0 && l[cmd.size()] == ' ') + return stoi(string(l.begin() + cmd.size() +1, l.end())); + } catch (...) { } // TODO FIX return 0; } -wstring parse_string(wstring l, wstring cmd) { +string parse_string(string l, string cmd) { try { if (l.rfind(cmd, 0) == 0 && l[cmd.size()] == ' ') - return (wstring(l.begin()+cmd.size()+1, l.end())); - } catch (...) { } - return L""; + return (string(l.begin() + cmd.size() + 1, l.end())); + } catch (...) { } // TODO FIX + return ""; } -bool repl::eval_input(wostream& os, wstring &l) { - static wstring ll = L""; - wstring f; - if (l == L"") os<out_dict(ss); +#ifdef WITH_WCHAR + os << ss.str(); +#else + os << s2ws(ss.str()); +#endif +} + +void repl::out_dict(ostream& os) { + ostringstream_t ss; + d->out_dict(ss); +#ifdef WITH_WCHAR + os << ws2s(ss.str()); +#else + os << ss.str(); +#endif +} + +template +bool repl::eval_input(basic_ostream& os, string l) { + static string ll = ""; + string f; + if (l == "") os<<"# Repeating: '"<<(l = ll)<<"'"<out_dict(os); return false; } - else if (l == L"q") return true; // quit - else if ((l == L"?") || - (l == L"h")) help(os); - else if (l == L"p") print(os); - else if (l == L"i") { info(os); return false; } - else if (l == L"ar") toggle(os, L"auto run", ar); - else if (l == L"ap") toggle(os, L"auto print", ap); - else if (l == L"ai") toggle(os, L"auto info", ai); - else if (l == L"ils") toggle(os, L"input line sequencing", ils); - else if (l == L"gc") bdd::gc(); - else if (l == L"d") dump(os); - else if ((l == L"c") || - (l == L"r")) run(os); - else if (l == L"l") list(os); - else if (size_t p = parse_size_t(l, L"l")) list(os, p); - else if (l == L"s") step(os); - else if (size_t s = parse_size_t(l, L"s")) step(os, s); - else if (l == L"b") break_on_fp(os); - else if (size_t s = parse_size_t(l, L"b")) break_on_step(os, s); - else if ((f = parse_string(l, L"load")) != L"") + if (l == "restart") restart(os); + else if (l == "reparse") reparse(os); + else if (l == "reset") reset(os); + else if (l == "dict") { out_dict(os); return false; } + else if (l == "q") return true; // quit + else if ((l == "?") || + (l == "h")) help(os); + else if (l == "p") print(os); + else if (l == "i") { info(os); return false; } + else if (l == "ar") toggle(os, "auto run", ar); + else if (l == "ap") toggle(os, "auto print", ap); + else if (l == "ai") toggle(os, "auto info", ai); + else if (l == "ils") toggle(os, "input line sequencing", ils); + else if (l == "gc") bdd::gc(); + else if (l == "d") dump(os); + else if ((l == "c") || + (l == "r")) run(os); + else if (l == "l") list(os); + else if (size_t p = parse_size_t(l, "l")) list(os, p); + else if (l == "s") step(os); + else if (size_t s = parse_size_t(l, "s")) step(os, s); + else if (l == "b") break_on_fp(os); + else if (size_t s = parse_size_t(l, "b")) break_on_step(os, s); + else if ((f = ws2s(parse_string(l, "load"))) != "") d->load(f); - else if ((f = parse_string(l, L"save")) != L"") + else if ((f = ws2s(parse_string(l, "save"))) != "") d->save(f); - else if (l == L"ps") - d->set_print_step(toggle(os, L"print steps", ps)); - else if (l == L"pu") - d->set_print_updates(toggle(os, L"print updates", pu)); - else if (l == L"cu") + else if (l == "ps") + d->set_print_step(toggle(os, "print steps", ps)); + else if (l == "pu") + d->set_print_updates(toggle(os, "print updates", pu)); + else if (l == "cu") d->set_populate_tml_update( - toggle(os, L"collect updates into tml_update", cu)); + toggle(os, "collect updates into tml_update", cu)); else add(os, l); if (ai) info(os); - os << L"# " << (fin ? L"finished " : L"") << L"ok" << endl; + os << "# " << (fin ? "finished " : "") << "ok" << endl; fin = false; return false; } +template bool repl::eval_input(basic_ostream&, string); +template bool repl::eval_input(basic_ostream&, string); + + +template +void repl::help(basic_ostream& os) const { + os << "# Commands:\n" + << "#\t?, h - help\n" + << "#\ti - info\n" + << "#\tp - print database\n" + << "#\tl - list programs\n" + << "#\tl NUM - list program NUM (1st program = 1)\n" + << "#\tr, c - run/continue\n" + << "#\ts - run pfp step\n" + << "#\ts NUM - run NUM pfp steps\n" + << "#\td - dump db (to the dump output)\n" + << "#\tdict - print internal string dictionary\n" + << "#\tgc - bdd garbage collection\n" + << "#\tcu - toggle collect updates\n" + << "#\tps - toggle print steps\n" + << "#\tpu - toggle print updates\n" + << "#\tar - toggle auto run\n" + << "#\tap - toggle auto print\n" + << "#\tai - toggle auto info\n" + << "#\tils - toggle input line sequencing\n" + << "#\tb - run and break on fixed point\n" + << "#\tb NUM - run and break on NUM step\n" + << "#\treparse - reparses the program\n" + << "#\trestart - restarts the program\n" + << "#\treset - resets repl (clears the entered program)\n" + << "#\tq - quit" << endl; +} +template void repl::help(basic_ostream&) const; +template void repl::help(basic_ostream&) const; -void repl::help(wostream& os) const { - os << L"# Commands:\n" - << L"#\t?, h - help\n" - << L"#\ti - info\n" - << L"#\tp - print database\n" - << L"#\tl - list programs\n" - << L"#\tl NUM - list program NUM (1st program = 1)\n" - << L"#\tr, c - run/continue\n" - << L"#\ts - run pfp step\n" - << L"#\ts NUM - run NUM pfp steps\n" - << L"#\td - dump db (to the dump output)\n" - << L"#\tdict - print internal string dictionary\n" - << L"#\tgc - bdd garbage collection\n" - << L"#\tcu - toggle collect updates\n" - << L"#\tps - toggle print steps\n" - << L"#\tpu - toggle print updates\n" - << L"#\tar - toggle auto run\n" - << L"#\tap - toggle auto print\n" - << L"#\tai - toggle auto info\n" - << L"#\tils - toggle input line sequencing\n" - << L"#\tb - run and break on fixed point\n" - << L"#\tb NUM - run and break on NUM step\n" - << L"#\treparse - reparses the program\n" - << L"#\trestart - restarts the program\n" - << L"#\treset - resets repl (clears the entered program)\n" - << L"#\tq - quit" << endl; -} - -bool repl::toggle(wostream& os, const wstring& name, bool &setting) { +template +bool repl::toggle(basic_ostream& os, const string& name, bool &setting) { setting = !setting; - os << L"# Changed '" << name << "' to " + os << "# Changed '" << name << "' to " << (setting ? "true" : "false") << endl; return setting; } +template bool repl::toggle(basic_ostream&, const string&, bool &); +template bool repl::toggle(basic_ostream&, const string&, bool &); void repl::loop() { - wstring input; + string input; prompt(os); for (;;) { input = {}; - if (wcin && wcin_reader.readable()) { - input = wcin_reader.read(); + if (CIN && in_reader.readable()) { + input = ws2s(in_reader.read()); if (input.size()) { if (eval_input(input)) break; prompt(os); @@ -216,9 +281,9 @@ void repl::loop() { } if (up_udp && up_udp->readable()) { udp_message msg = up_udp->read(); - input = s2ws(msg.second); + input = msg.second; if (!input.empty()) input.pop_back(); // remove \n - wstringstream ss; + stringstream ss; bool br = eval_input(ss, input); // TODO split responses bigger than BUFLEN if (ss.str().size()) { @@ -231,6 +296,6 @@ void repl::loop() { if (br) break; } - std::this_thread::sleep_for(std::chrono::milliseconds(20)); + this_thread::sleep_for(chrono::milliseconds(20)); } } diff --git a/src/repl.h b/src/repl.h index 455425fa..96c2e7f4 100644 --- a/src/repl.h +++ b/src/repl.h @@ -16,13 +16,13 @@ #include "udp.h" #include "async_reader.h" -class wistream_async_reader : public async_reader { +class istream_async_reader : public async_reader { public: - wistream_async_reader(std::wistream* is) : async_reader(), is(is) { } + istream_async_reader(istream_t* is) : async_reader(), is(is) { } protected: - std::wistream* is; + istream_t* is; void read_in_thread() { - std::wstring l; + sysstring_t l; while (std::getline(*is, l)) { std::lock_guard lk(m); q.push(std::move(l)); @@ -33,10 +33,10 @@ class wistream_async_reader : public async_reader { class repl { options& o; - std::wostream& os; + ostream_t& os; std::unique_ptr d = 0; std::unique_ptr up_udp; - wistream_async_reader wcin_reader{&std::wcin}; + istream_async_reader in_reader{&CIN}; bool fin = false; bool ar = true; // auto run bool ap = true; // auto print @@ -47,28 +47,44 @@ class repl { bool ils = false; // input line sequencing: is each input line a newseq? void loop(); - bool eval_input(std::wostream& os, std::wstring &l); - void prompt(std::wostream& os); - void redrive(const std::wstring src = L""); + template + bool eval_input(std::basic_ostream&, std::string l); + template + void prompt(std::basic_ostream&); + void redrive(const std::string& src); - void help(std::wostream& os) const; - void print(std::wostream& os); - void list(std::wostream& os, size_t p = 0); - void restart(std::wostream& os); - void reparse(std::wostream& os); - void reset(std::wostream& os); - void dump(std::wostream& os); - void info(std::wostream& os); - bool toggle(std::wostream& os, const std::wstring& name, bool &setting); - void add(std::wostream& os, std::wstring line); - void run(std::wostream& os, size_t steps = 0, size_t break_on_step=0, + template + void help(std::basic_ostream&) const; + template + void print(std::basic_ostream&); + template + void list(std::basic_ostream&, size_t p = 0); + template + void restart(std::basic_ostream&); + template + void reparse(std::basic_ostream&); + template + void reset(std::basic_ostream&); + template + void dump(std::basic_ostream&); + template + void info(std::basic_ostream&); + template + bool toggle(std::basic_ostream&, const std::string& name, bool &setting); + template + void add(std::basic_ostream&, std::string line); + template + void run(std::basic_ostream&, size_t steps = 0, size_t break_on_step=0, bool break_on_fp=0); - void step(std::wostream& os, size_t steps = 1) { run(os, steps); }; - void break_on_fp(std::wostream& os) { run(os,0,0,true); }; - void break_on_step(std::wostream& os, size_t brs) { run(os, 0, brs); }; - - // default os - bool eval_input(std::wstring &l) { return eval_input(os, l); } + template + void step(std::basic_ostream&, size_t steps = 1) { run(os, steps); } + template + void break_on_fp(std::basic_ostream&) { run(os, 0, 0, true); } + template + void break_on_step(std::basic_ostream&, size_t brs) { run(os, 0, brs); } + void out_dict(std::wostream& os); + void out_dict(std::ostream& os); + bool eval_input(const std::string &l) { return eval_input(os, l); } void help() const { help(os); } void print() { print(os); } void list(size_t p = 0) { list(os, p); } @@ -77,10 +93,10 @@ class repl { void reset() { reset(os); } void dump(); void info() { info(os); } - bool toggle(const std::wstring& name, bool &setting) { + bool toggle(const std::string& name, bool &setting) { return toggle(os, name, setting); } - void add(std::wstring line) { add(os, line); } + void add(const std::string& line) { add(os, line); } void run(size_t steps, size_t break_on_step = 0, bool break_on_fp = 0) { run(os, steps, break_on_step, break_on_fp); } @@ -88,7 +104,7 @@ class repl { void break_on_fp() { run(0, 0, true); }; void break_on_step(size_t brs) { run(0, brs); }; public: - repl(options &o, std::wostream& os = o::repl()); + repl(options &o, ostream_t& os = o::repl()); }; #endif diff --git a/src/save_csv.cpp b/src/save_csv.cpp index 48fb8b95..1387103d 100644 --- a/src/save_csv.cpp +++ b/src/save_csv.cpp @@ -15,29 +15,30 @@ using namespace std; void driver::save_csv() const { - map files; + map files; tbl->out([&files](const raw_term& t) { auto it = files.find(t.e[0]); if (it == files.end()) { - wstring wfname = lexeme2str(t.e[0].e) + L".csv"; - o::inf() << L"Saving " << wfname << endl; - files.emplace(t.e[0], - wofstream(ws2s(wfname))); + std::string fname = ws2s(lexeme2str(t.e[0].e)) + ".csv"; + o::inf() << "Saving " << fname << endl; + files.emplace(t.e[0], ofstream(fname)); it = files.find(t.e[0]); } - wofstream& os = it->second; - if (t.neg) os << L'~'; + std::ostream& os = it->second; + auto elem2str = [](const elem&e) { return lexeme2str(e.e); }; + if (t.neg) os << '~'; for (size_t ar = 0, n = 1; ar != t.arity.size();) { while (t.arity[ar] == -1) ++ar; if (n >= t.e.size()) break; while (t.e[n].type == elem::OPENP) ++n; for (int_t k = 0; k != t.arity[ar];) - if ((os< 1 && t.arity[ar-1] == -2 && - ar != t.arity.size()) os << L'\t'; + ar != t.arity.size()) os << '\t'; } os << endl; }); diff --git a/src/tables.cpp b/src/tables.cpp index 871d7ebe..17e390d7 100644 --- a/src/tables.cpp +++ b/src/tables.cpp @@ -29,12 +29,12 @@ size_t sig_len(const sig& s) { return r; } -void unquote(wstring& str) { +void unquote(string& str) { for (size_t i = 0; i != str.size(); ++i) - if (str[i] == L'\\') str.erase(str.begin() + i); + if (str[i] == '\\') str.erase(str.begin() + i); } -wstring _unquote(wstring str) { unquote(str); return str; } +string _unquote(string str) { unquote(str); return str; } #ifdef DEBUG vbools tables::allsat(spbdd_handle x, size_t args) const { @@ -51,7 +51,8 @@ vbools tables::allsat(spbdd_handle x, size_t args) const { #endif spbdd_handle tables::leq_const(int_t c, size_t arg, size_t args, size_t bit) - const { + const +{ if (!--bit) return (c & 1) ? htrue : ::from_bit(pos(0, arg, args), false); @@ -78,7 +79,8 @@ spbdd_handle tables::leq_var(size_t arg1, size_t arg2, size_t args) const { } spbdd_handle tables::leq_var(size_t arg1, size_t arg2, size_t args, size_t bit) - const { + const +{ if (!--bit) return bdd_ite(::from_bit(pos(0, arg2, args), true), htrue, @@ -398,7 +400,7 @@ bool pull_quantifier::dosubstitution(form *phi, form * prefend){ subst.add( temp->l->arg, fresh_int ); - wprintf(L"\nNew fresh: %d --> %d ", temp->l->arg, fresh_int); + COUT << "\nNew fresh: "<l->arg<<" --> "<r; } @@ -427,9 +429,8 @@ bool pull_quantifier::apply( form *&root) { rprefend->r = curr; root = lprefbeg; changed = true; - wprintf(L"\nPulled both: "); - wprintf(L"%d %d , ", lprefbeg->type, lprefbeg->arg ); - wprintf(L"%d %d\n", rprefbeg->type, rprefbeg->arg ); + COUT<<"\nPulled both: "<type<<" "<arg<< + " , "<< rprefbeg->type << " " << rprefbeg->arg<< "\n"; } else if(lprefbeg) { if(!dosubstitution(lprefbeg, lprefend)) @@ -438,8 +439,8 @@ bool pull_quantifier::apply( form *&root) { lprefend->r = curr; root = lprefbeg; changed = true; - wprintf(L"\nPulled left: "); - wprintf(L"%d %d\n", lprefbeg->type, lprefbeg->arg ); + COUT<<"\nPulled left: "<type<<" "<arg<< + "\n"; } else if (rprefbeg) { if(!dosubstitution(rprefbeg, rprefend)) @@ -448,14 +449,13 @@ bool pull_quantifier::apply( form *&root) { rprefend->r = curr; root = rprefbeg; changed = true; - wprintf(L"\nPulled right: "); - wprintf(L"%d %d\n", rprefbeg->type, rprefbeg->arg ); + COUT <<"\nPulled right: "<type<<" "<arg<< + "\n"; } return changed; } -bool pull_quantifier::traverse( form *&root ) { - +bool pull_quantifier::traverse(form *&root) { bool changed = false; if( root == NULL ) return false; if( root->l ) changed |= traverse( root->l ); @@ -555,31 +555,34 @@ bool tables::from_raw_form(const raw_form_tree *rfm, form *&froot, bool &is_sol) } void form::printnode(int lv) { - if(r) r->printnode(lv+1); - for( int i=0; i printnode(lv+1); + if (r) r->printnode(lv+1); + for (int i = 0; i < lv; i++) COUT << '\t'; + COUT << " " << type << " " << arg; + if (l) l->printnode(lv+1); } //--------------------------------------------------------- - -void tables::out(wostream& os) const { +template +void tables::out(basic_ostream& os) const { strs_t::const_iterator it; for (ntable tab = 0; (size_t)tab != tbls.size(); ++tab) // if ((it = strs.find(dict.get_rel(tab))) == strs.end()) out(os, tbls[tab].t, tab); -// else os << it->first << L" = \"" << it->second << L'"' << endl; +// else os << it->first << " = \"" << it->second << '"' << endl; } +template void tables::out(ostream& os) const; +template void tables::out(wostream& os) const; + void tables::out(const rt_printer& f) const { for (ntable tab = 0; (size_t)tab != tbls.size(); ++tab) out(tbls[tab].t, tab, f); } -void tables::out(wostream& os, spbdd_handle x, ntable tab) const { - out(x, tab, [&os](const raw_term& rt) { os << rt << L'.' << endl; }); +template +void tables::out(basic_ostream& os, spbdd_handle x, ntable tab) const { + out(x, tab, [&os](const raw_term& rt) { os << rt << '.' << endl; }); } #ifdef __EMSCRIPTEN__ @@ -588,27 +591,27 @@ void tables::out(wostream& os, spbdd_handle x, ntable tab) const { // - set(relation_name, row, col, value) - sets value of the cell of a table void tables::out(emscripten::val o) const { out([&o](const raw_term& t) { - wstring relation = lexeme2str(t.e[0].e); - int row = o.call("length", ws2s(relation)); + string relation = lexeme2str(t.e[0].e); + int row = o.call("length", relation); int col = 0; for (size_t ar = 0, n = 1; ar != t.arity.size();) { - wstringstream es; - while (t.arity[ar] == -1) ++ar, es << L'('; + stringstream es; + while (t.arity[ar] == -1) ++ar, es << '('; if (n >= t.e.size()) break; while (t.e[n].type == elem::OPENP) ++n; for (int_t k = 0; k != t.arity[ar];) if ((es<("set", relation, row,col++, - ws2s(es.str())); - es.str(L""); + es.str()); + es.str(""); } while (n("set", relation, row, col++, - ws2s(es.str())); + es.str()); } }); } @@ -641,17 +644,17 @@ set tables::decompress() { // D: TODO: just a quick & dirty fix, get_elem, to_raw_term (out etc.) is const #define rdict() ((dict_t&)dict) -//#define get_var_lexeme(v) dict.get_lexeme(wstring(L"?v") + to_wstring(-v)) -#define get_var_lexeme(v) rdict().get_lexeme(wstring(L"?v") + to_wstring(-v)) //#define get_var_lexeme(v) rdict().get_var_lexeme_from(v) +//#define get_var_lexeme(v) dict.get_lexeme(string("?v") + to_string_(-v)) +#define get_var_lexeme(v) rdict().get_lexeme(string("?v")+to_string_(-v)) elem tables::get_elem(int_t arg) const { if (arg < 0) return elem(elem::VAR, get_var_lexeme(arg)); if (arg & 1) { - const wchar_t ch = arg >> 2; - if (iswprint(ch)) return elem(ch); - return elem(elem::SYM, rdict().get_lexeme(wstring(L"\"#") + - to_wstring_((unsigned char)(ch)) + L"\"")); + const int_t ch = arg >> 2; + if (ch > 31) return elem((const codepoint) ch); // is printable + return elem(elem::SYM, rdict().get_lexeme("\"#" + + to_string_((ch)) + "\"")); } if (arg & 2) return elem((int_t)(arg>>2)); return elem(elem::SYM, rdict().get_sym(arg)); @@ -661,34 +664,32 @@ raw_term tables::to_raw_term(const term& r) const { raw_term rt; rt.neg = r.neg; size_t args; - if (r.extype == term::EQ) {//r.iseq) { - args = 2, rt.e.resize(args + 1), rt.e[0] = get_elem(r[0]), - rt.e[1] = elem(elem::SYM, rdict().get_lexeme(r.neg ? L"!=" : L"=")), + if (r.extype == term::EQ) {//r.iseq) + args = 2, rt.e.resize(args + 1), rt.e[0] = get_elem(r[0]), + rt.e[1] = elem(elem::SYM, rdict().get_lexeme(r.neg ? "!=" : "=")), rt.e[2] = get_elem(r[1]), rt.arity = {2}, rt.extype = raw_term::EQ; - return rt ; - } - else if (r.extype == term::LEQ) { //r.isleq) + return rt; + } else if (r.extype == term::LEQ) {//r.isleq) args = 2, rt.e.resize(args + 1), rt.e[0] = get_elem(r[0]), // D: TODO: is this a bug (never used)? for neg it should be > not <= ? - rt.e[1] = elem(elem::SYM, rdict().get_lexeme(r.neg ? L"<=" : L">")), + rt.e[1] = elem(elem::SYM, rdict().get_lexeme(r.neg ? "<=" : ">")), rt.e[2] = get_elem(r[1]), rt.arity = {2}, rt.extype = raw_term::LEQ; return rt; - } // TODO: BLTINS: add term::BLTIN handling - else if( r.tab == -1 && r.extype == term::ARITH ) { + } else if( r.tab == -1 && r.extype == term::ARITH ) { rt.e.resize(5); elem elp; elp.arith_op = r.arith_op; elp.type = elem::ARITH; switch ( r.arith_op ) { - case t_arith_op::ADD: elp.e = rdict().get_lexeme(L"+");break; - case t_arith_op::MULT: elp.e = rdict().get_lexeme(L"*");break; - case t_arith_op::SUB: elp.e = rdict().get_lexeme(L"-");break; + case t_arith_op::ADD: elp.e = rdict().get_lexeme("+");break; + case t_arith_op::MULT: elp.e = rdict().get_lexeme("*");break; + case t_arith_op::SUB: elp.e = rdict().get_lexeme("-");break; default: __throw_runtime_error( "to_raw_term to support other operator "); } elem elq; elq.type = elem::EQ; - elq.e = rdict().get_lexeme(L"="); + elq.e = rdict().get_lexeme("="); rt.e[0] = get_elem(r[0]); rt.e[1] = elp; @@ -758,7 +759,7 @@ varmap tables::get_varmap(const term& h, const T& b, size_t &varslen) { spbdd_handle tables::get_alt_range(const term& h, const term_set& a, const varmap& vm, size_t len) { set pvars, nvars, eqvars, leqvars, arithvars; - std::vector eqterms, leqterms, arithterms; + vector eqterms, leqterms, arithterms; // first pass, just enlist eq terms (that have at least one var) for (const term& t : a) { bool haseq = false, hasleq = false, hasarith = false; @@ -777,7 +778,7 @@ spbdd_handle tables::get_alt_range(const term& h, const term_set& a, for (const term* pt : eqterms) { const term& t = *pt; bool noeqvars = true; - std::vector tvars; + vector tvars; for (size_t n = 0; n != t.size(); ++n) if (t[n] >= 0) continue; // nvars add range already, so skip all in that case... @@ -895,7 +896,7 @@ void tables::get_facts(const flat_prog& m) { tbls[x.first].t = r; } if (optimize) - (o::ms() << L"# get_facts: "), + (o::ms() << "# get_facts: "), measure_time_end(); } @@ -905,7 +906,7 @@ void tables::get_nums(const raw_term& t) { else if (e.type == elem::CHR) chars = 255; } -bool tables::to_pnf( form *&froot) { +bool tables::to_pnf(form *&froot) { implic_removal impltrans; demorgan demtrans(true); @@ -914,11 +915,10 @@ bool tables::to_pnf( form *&froot) { bool changed = false; changed = impltrans.traverse(froot); changed |= demtrans.traverse(froot); - - wprintf(L"\n ........... \n"); + COUT << "\n ........... \n"; froot->printnode(); changed |= pullquant.traverse(froot); - wprintf(L"\n ........... \n"); + COUT << "\n ........... \n"; froot->printnode(); return changed; @@ -947,12 +947,13 @@ flat_prog tables::to_terms(const raw_prog& p) { else if(r.prft != NULL) { bool is_sol = false; form* froot = NULL; + from_raw_form(r.prft.get(), froot, is_sol); - DBG(wprintf(L"\n ........... \n")); - DBG(r.prft.get()->printTree()); - DBG(wprintf(L"\n ........... \n")); - DBG(froot->printnode()); + DBG(COUT << "\n ........... \n";) + DBG(r.prft.get()->printTree();) + DBG(COUT << "\n ........... \n";) + DBG(froot->printnode();) term::textype extype = term::FORM1; if(is_sol) to_pnf(froot), extype = term::FORM2; @@ -969,8 +970,9 @@ flat_prog tables::to_terms(const raw_prog& p) { //delete froot; } else { for (const raw_term& x : r.h) - t = from_raw_term(x, true), t.goal = r.type == raw_rule::GOAL, - m.insert({t}), get_nums(x); + t = from_raw_term(x, true), + t.goal = r.type == raw_rule::GOAL, + m.insert({t}), get_nums(x); } return m; @@ -1096,7 +1098,7 @@ void tables::create_tmp_head(vector& x) { return { x }; return { x, y }; // if (has(r, y[0])) -// return print(print(o::out(),x)<& v) const { if (!cqc(v1, v)) v.insert(v.begin() + n, t); } DBG(if (v.size() != v1.size()) - print(print(o::err()<&,// r, return x[0].tab;*/ } -wostream& tables::print(wostream& os, const vector& v) const { +template +basic_ostream& tables::print(basic_ostream& os, const vector& v) const { os << to_raw_term(v[0]); - if (v.size() == 1) return os << L'.'; - os << L" :- "; + if (v.size() == 1) return os << '.'; + os << " :- "; for (size_t n = 1; n != v.size(); ++n) { - if (v[n].goal) os << L'!'; - os << to_raw_term(v[n]) << (n == v.size() - 1 ? L"." : L", "); + if (v[n].goal) os << '!'; + os << to_raw_term(v[n]) << (n == v.size() - 1 ? "." : ", "); } return os; } -wostream& tables::print(wostream& os, const flat_prog& p) const { +template +basic_ostream& tables::print(basic_ostream& os, const flat_prog& p) const{ for (const auto& x : p) print(os << (x[0].tab == -1 ? 0 : tbls[x[0].tab].priority) << - L'\t', x) << endl; + '\t', x) << endl; /* map m; for (const auto& x : p) m[tbls[x[0].tab].priority].insert(x); size_t n = m.rbegin()->first; @@ -1175,13 +1179,16 @@ wostream& tables::print(wostream& os, const flat_prog& p) const { for (const auto& x : m) v[n--] = move(x.second); for (n = 0; n != v.size(); ++n) for (const vector& y : v[n]) - print(os << n << L'\t', y) << endl;*/ + print(os << n << '\t', y) << endl;*/ return os; } -wostream& tables::print_dict(wostream& os) const { +template +basic_ostream& tables::print_dict(basic_ostream& os) const { return os << dict; } +template basic_ostream& tables::print_dict(basic_ostream&) const; +template basic_ostream& tables::print_dict(basic_ostream&) const; void tables::get_alt(const term_set& al, const term& h, set& as) { alt a; @@ -1256,7 +1263,7 @@ void tables::get_alt(const term_set& al, const term& h, set& as) { // order to work feature. // Will be combined with a query method // on the execution stage - o::dbg()< LEQ + reversed args + !neg @@ -1277,10 +1284,10 @@ void tables::get_alt(const term_set& al, const term& h, set& as) { lexeme tables::get_new_rel() { static size_t last = 1; - wstring s = L"r"; + string s = "r"; size_t sz; lexeme l; -retry: sz = dict.nrels(), l = dict.get_lexeme(s + to_wstring_(last)); +retry: sz = dict.nrels(), l = dict.get_lexeme(s + to_string_(last)); dict.get_rel(l); if (dict.nrels() == sz) { ++last; goto retry; } return l; @@ -1385,7 +1392,7 @@ void tables::transform_bin(flat_prog& p) { } p.insert(move(x)), vars.clear(); } - if (print_transformed) print(o::out()<& x : p) if (x.size() > 1) exts.erase(x[0].tab);*/ - if (bcqc) print(o::out()< r; for (const auto& x : q) prog_add_rule(p, r, x); replace_rel(move(r), p); - if (bcqc) print(o::out()< tbls[y.tab].priority; }); } -void tables::load_string(lexeme r, const wstring& s) { +void tables::load_string(lexeme r, const string& s) { int_t rel = dict.get_rel(r); str_rels.insert(rel); -// const ints ar = {0,-1,-1,1,-2,-2,-1,1,-2,-1,-1,1,-2,-2}; - const int_t sspace = dict.get_sym(dict.get_lexeme(L"space")), - salpha = dict.get_sym(dict.get_lexeme(L"alpha")), - salnum = dict.get_sym(dict.get_lexeme(L"alnum")), - sdigit = dict.get_sym(dict.get_lexeme(L"digit")), - sprint = dict.get_sym(dict.get_lexeme(L"printable")); - term t,tb; + //const ints ar = {0,-1,-1,1,-2,-2,-1,1,-2,-1,-1,1,-2,-2}; + const int_t sspace = dict.get_sym(dict.get_lexeme("space")), + salpha = dict.get_sym(dict.get_lexeme("alpha")), + salnum = dict.get_sym(dict.get_lexeme("alnum")), + sdigit = dict.get_sym(dict.get_lexeme("digit")), + sprint = dict.get_sym(dict.get_lexeme("printable")); + term t, tb; bdd_handles b1, b2; b1.reserve(s.size()), b2.reserve(s.size()), t.resize(2), tb.resize(3); for (int_t n = 0; n != (int_t)s.size(); ++n) { @@ -1575,20 +1582,21 @@ void to_nums(flat_prog& m) { ntable tables::get_new_tab(int_t x, ints ar) { return get_table({ x, ar }); } -bool tables::get_substr_equality(const raw_term &rt, size_t &n, std::map &refs, - std::vector &v, std::set &done){ +bool tables::get_substr_equality(const raw_term &rt, size_t &n, + std::map &refs, std::vector &v, std::set &/*done*/) +{ //format : substr(1) = substr(2) term svalt; svalt.resize(4); - int_t relp = dict.get_rel(dict.get_lexeme(L"equals")); + int_t relp = dict.get_rel(dict.get_lexeme("equals")); svalt.tab = get_table({relp, {(int_t)svalt.size()}}); svalt.extype = term::textype::REL; for( int i=0; i<2 ; i++) { if( n >= rt.e.size() || rt.e[n].type != elem::SYM ) return false; - wstring attrib = lexeme2str( rt.e[n].e); - if( !(!std::wcscmp(attrib.c_str() , L"substr") + string attrib = lexeme2str(rt.e[n].e); + if( !(!std::strcmp(attrib.c_str() , "substr") && (n+3) < rt.e.size() && rt.e[n+1].type == elem::OPENP && rt.e[n+2].type == elem::NUM @@ -1597,10 +1605,10 @@ bool tables::get_substr_equality(const raw_term &rt, size_t &n, std::map= (int_t)refs.size()) - parse_error(L"Wrong symbol index in substr", rt.e[n+2].e ); + parse_error("Wrong symbol index in substr", rt.e[n+2].e ); if( refs[pos].size() <= 1 ) // has to be size 2 , e.g. S( 0 1) - parse_error(L"Incorrect term size for substr(index)", L"" ); + parse_error("Incorrect term size for substr(index)", "" ); svalt[i*2] = refs[pos][0]; //normal S( i j ) term, but for str relation, get the var by decrementing that at pos0 @@ -1608,9 +1616,9 @@ bool tables::get_substr_equality(const raw_term &rt, size_t &n, std::map &refs, - std::vector &v, std::set &done){ + std::vector &v, std::set &/*done*/){ int_t lopd=0; if( n < rt.e.size() && rt.e[n].type == elem::SYM ) { - wstring attrib = lexeme2str( rt.e[n].e); - if( ! std::wcscmp(attrib.c_str() , L"len") + string attrib = lexeme2str(rt.e[n].e); + if( ! std::strcmp(attrib.c_str() , "len") && (n+3) < rt.e.size() && rt.e[n+1].type == elem::OPENP && rt.e[n+2].type == elem::NUM && rt.e[n+3].type == elem::CLOSEP ) { int_t pos = rt.e[n+2].num; if( pos <0 || pos >= (int_t)refs.size()) - parse_error(L"Wrong symbol index in len", rt.e[n+2].e ); + parse_error("Wrong symbol index in len", rt.e[n+2].e ); if( refs[pos].size() > 1 ) { @@ -1642,20 +1650,20 @@ int_t tables::get_factor(raw_term &rt, size_t &n, std::map &refs, if( refs[pos][1] < 0 ) lent[2] = refs[pos][1]; else lent[2] = refs[pos][0] -1; // so len(i) refers to str relation - lent[1] = dict.get_var(dict.get_lexeme(L"?len"+to_wstring(pos))); + lent[1] = dict.get_var(dict.get_lexeme(string("?len")+to_string_(pos))); lopd = lent[1]; n += 4; //if(!done.insert(lent).second) v.push_back(lent); } - else er(L"Wrong term for ref."); + else er("Wrong term for ref."); } } else if( n < rt.e.size() && rt.e[n].type == elem::NUM ) { lopd = mknum(rt.e[n].num); n += 1; } - else er(L"Invalid start of constraint."); + else er("Invalid start of constraint."); return lopd; } @@ -1667,7 +1675,7 @@ bool tables::get_rule_substr_equality(vector> &eqr ){ for(size_t r = 0; r < eqr.size(); r++) { int_t var = 0; int_t i= --var, j= --var , k=--var, n= --var; - ntable nt = get_table({dict.get_rel(dict.get_lexeme(L"equals")), {4}}); + ntable nt = get_table({dict.get_rel(dict.get_lexeme("equals")), {4}}); // making head equals( i j k n) :- eqr[r].emplace_back(false, term::textype::REL, t_arith_op::NOP, nt, std::initializer_list{i, j, k, n}, 0 ); @@ -1707,8 +1715,8 @@ void tables::transform_grammar(vector g, flat_prog& p) { size_t n = 0; while (n < g[k].p.size() && g[k].p[n].type != elem::ALT) ++n; if (n == g[k].p.size()) { ++k; continue; } - g.push_back({vector(g[k].p.begin(), g[k].p.begin()+n)}); - g.push_back({vector(g[k].p.begin()+n+1, g[k].p.end())}); + g.push_back({ vector(g[k].p.begin(), g[k].p.begin()+n) }); + g.push_back({ vector(g[k].p.begin()+n+1, g[k].p.end()) }); g.back().p.insert(g.back().p.begin(), g[k].p[0]); g.erase(g.begin() + k); } @@ -1720,19 +1728,19 @@ void tables::transform_grammar(vector g, flat_prog& p) { lexeme l = p.p[n].e; p.p.erase(p.p.begin() + n); bool esc = false; - for (cws s = l[0]+1; s != l[1]-1; ++s) - if (*s == L'\\' && !esc) esc = true; + for (ccs s = l[0]+1; s != l[1]-1; ++s) + if (*s == '\\' && !esc) esc = true; else p.p.insert(p.p.begin() + n++, elem(*s)), esc = false; } vector v; - static const set b = - { L"alpha", L"alnum", L"digit", L"space", L"printable" }; + static const set b = + { "alpha", "alnum", "digit", "space", "printable" }; set builtins; - for (const wstring& s : b) builtins.insert(dict.get_lexeme(s)); + for (const string& s : b) builtins.insert(dict.get_lexeme(s)); for (const production& x : g) { - if (x.p.size() == 2 && x.p[1].e == L"null") { + if (x.p.size() == 2 && x.p[1].e == "null") { term t; t.resize(2); t[0] = t[1] = -1; @@ -1775,7 +1783,7 @@ void tables::transform_grammar(vector g, flat_prog& p) { t[1] = mkchr((unsigned char)(x.p[n].ch)); term plus1; plus1.resize(3); - //int_t relp = dict.get_rel(dict.get_lexeme(L"plus1")); + //int_t relp = dict.get_rel(dict.get_lexeme("plus1")); plus1.tab = -1; // get_table({relp, {3}}); plus1.extype = term::textype::ARITH; plus1.arith_op = t_arith_op::ADD; @@ -1824,7 +1832,7 @@ void tables::transform_grammar(vector g, flat_prog& p) { int_t ropd = get_factor(rt, n, refs, v, done); if( rt.e[n].type != elem::EQ) - parse_error(L"Only EQ supported in len constraints. ", rt.e[n].e); + parse_error("Only EQ supported in len constraints. ", rt.e[n].e); n++; // assignment aritht[0] = lopd; @@ -1833,7 +1841,7 @@ void tables::transform_grammar(vector g, flat_prog& p) { aritht[2] = oside; //if(!done.insert(aritht).second) if(n == rt.e.size()) v.push_back(aritht); - else er(L" Only simple binary operation allowed." ); + else er(" Only simple binary operation allowed." ); } else if( n < rt.e.size() && (rt.e[n].type == elem::EQ || rt.e[n].type == elem::LEQ)) { @@ -1868,27 +1876,27 @@ void tables::transform_grammar(vector g, flat_prog& p) { aritht[2] = lopd; //if(!done.insert(aritht).second) if(n == rt.e.size()) v.push_back(aritht); - else er(L"Only simple binary operation allowed."); + else er("Only simple binary operation allowed."); - } else parse_error(err_constraint_syntax, L""); + } else parse_error(err_constraint_syntax, ""); } else parse_error(err_constraint_syntax, rt.e[n].e); } p.insert(move(v)); } - DBG(print(o::dbg() << L"transformed grammar: " << endl, p);) - DBG(print(o::dbg() << L"run after transform: " << endl, prog_after_fp);) + DBG(print(o::dbg() << "transformed grammar: " << endl, p);) + DBG(print(o::dbg() << "run after transform: " << endl, prog_after_fp);) } void tables::add_prog(const raw_prog& p, const strs_t& strs_) { strs = strs_; if (!strs.empty()) chars = 255, - dict.get_sym(dict.get_lexeme(L"space")), - dict.get_sym(dict.get_lexeme(L"alpha")), - dict.get_sym(dict.get_lexeme(L"alnum")), - dict.get_sym(dict.get_lexeme(L"digit")), - dict.get_sym(dict.get_lexeme(L"printable")); + dict.get_sym(dict.get_lexeme("space")), + dict.get_sym(dict.get_lexeme("alpha")), + dict.get_sym(dict.get_lexeme("alnum")), + dict.get_sym(dict.get_lexeme("digit")), + dict.get_sym(dict.get_lexeme("printable")); for (auto x : strs) nums = max(nums, (int_t)x.second.size()+1); add_prog(to_terms(p), p.g); @@ -1925,7 +1933,7 @@ bool tables::run_nums(flat_prog m, set& r, size_t nsteps) { x.erase(x.begin() + 1, x.end()), x.insert(x.begin() + 1, s.begin(), s.end()), p.insert(x); } -// DBG(print(o::out()< "; +template +basic_ostream& tables::decompress_update(basic_ostream& os, spbdd_handle& x, const rule& r) { + if (print_updates) print(os << "# ", r) << "\n# \t-> "; decompress(x, r.tab, [&os, &r, this](const term& x) { if (print_updates) - os << (r.neg ? L"~" : L"") << to_raw_term(x) << L". "; + os << (r.neg ? "~" : "") << to_raw_term(x) << ". "; if (populate_tml_update) add_tml_update(x, r.neg); }); if (print_updates) os << endl; @@ -1956,9 +1965,9 @@ wostream& tables::decompress_update(wostream& os, spbdd_handle& x, const rule& r } void tables::init_tml_update() { - rel_tml_update = dict.get_rel(dict.get_lexeme(L"tml_update")); - sym_add = dict.get_sym(dict.get_lexeme(L"add")); - sym_del = dict.get_sym(dict.get_lexeme(L"delete")); + rel_tml_update = dict.get_rel(dict.get_lexeme("tml_update")); + sym_add = dict.get_sym(dict.get_lexeme("add")); + sym_del = dict.get_sym(dict.get_lexeme("delete")); } void tables::add_prog(flat_prog m, const vector& g, bool mknums) { @@ -2022,9 +2031,7 @@ auto handle_cmp = [](const spbdd_handle& x, const spbdd_handle& y) { return x->b < y->b; }; - - -spbdd_handle tables::alt_query_bltin(alt& a, bdd_handles& v1) { +void tables::alt_query_bltin(alt& a, bdd_handles& v1) { spbdd_handle x; @@ -2038,8 +2045,7 @@ spbdd_handle tables::alt_query_bltin(alt& a, bdd_handles& v1) { if (a.bltinargs[i] < 0) bltininputs.push_back(a.bltinargs[i]); } - - if (bltintype == L"count") { + if (bltintype == "count") { body& b = *a[a.size() - 1]; // old, official satcount algorithm, phased out int_t cnt0 = bdd::satcount_k(x->b, b.ex, b.perm); @@ -2051,11 +2057,11 @@ spbdd_handle tables::alt_query_bltin(alt& a, bdd_handles& v1) { x = from_sym(a.vm.at(bltinout), a.varslen, mknum(cnt)); v1.push_back(x); - o::dbg() << L"alt_query (cnt):" << cnt << L"" << endl; + o::dbg() << "alt_query (cnt):" << cnt << "" << endl; if (cnt != cnt0) - o::dbg() << L"(cnt0 != cnt):" << cnt0 << L", " << cnt << endl; + o::dbg() << "(cnt0 != cnt):" << cnt0 << ", " << cnt << endl; } - else if (bltintype == L"rnd") { + else if (bltintype == "rnd") { DBG(assert(a.bltinargs.size() == 3);); // TODO: check that it's num const int_t arg0 = int_t(a.bltinargs[0] >> 2); @@ -2070,15 +2076,15 @@ spbdd_handle tables::alt_query_bltin(alt& a, bdd_handles& v1) { x = from_sym(a.vm.at(bltinout), a.varslen, mknum(rnd)); v1.push_back(x); - o::dbg() << L"alt_query (rnd):" << rnd << L"" << endl; + o::dbg() << "alt_query (rnd):" << rnd << "" << endl; } - else if (bltintype == L"print") { - wstring ou{L"output"}; + else if (bltintype == "print") { + string ou{"output"}; size_t n{0}; // D: args are now [0,1,...] (we no longer have the bltin as 0 arg) if (a.bltinargs.size() >= 2) ++n, ou = lexeme2str(dict.get_sym(a.bltinargs[0])); - wostream& os = output::to(ou); + ostream_t& os = o::to(ou); do { int_t arg = a.bltinargs[n++]; if (arg < 0) os << get_var_lexeme(arg) << endl; @@ -2174,7 +2180,7 @@ bool table::commit(DBG(size_t /*bits*/)) { } char tables::fwd() noexcept { -// DBG(out(o::out()< rtp{ to_raw_term(t), L"p:"}; - os << L"printing: " << rtp << L'.' << endl; + pair rtp{ to_raw_term(t), "p:" }; + os << "printing: " << rtp << '.' << endl; } - else if (bltintype == L"halt") { + else if (bltintype == "halt") { ishalt = true; - wostream& os = o::dbg() << endl; - pair rtp{ to_raw_term(t), L"p:" }; - os << L"program halt: " << rtp << L'.' << endl; + ostream_t& os = o::dbg() << endl; + pair rtp{ to_raw_term(t), "p:" }; + os << "program halt: " << rtp << '.' << endl; } - else if (bltintype == L"fail") { + else if (bltintype == "fail") { ishalt = isfail = true; - wostream& os = o::dbg() << endl; - pair rtp{ to_raw_term(t), L"p:" }; - os << L"program fail: " << rtp << L'.' << endl; + ostream_t& os = o::dbg() << endl; + pair rtp{ to_raw_term(t), "p:" }; + os << "program fail: " << rtp << '.' << endl; } } }, 0, true); @@ -2253,7 +2259,7 @@ bool tables::pfp(size_t nsteps, size_t break_on_step) { level l; for (;;) { if (print_steps || optimize) - o::inf() << L"# step: " << nstep << endl; + o::inf() << "# step: " << nstep << endl; ++nstep; if (!fwd()) return true; // FP found if (unsat) throw contradiction_exception(); @@ -2276,14 +2282,14 @@ bool tables::run_prog(const raw_prog& p, const strs_t& strs, size_t steps, add_prog(p, strs); if (optimize) { end = clock(), t = double(end - start) / CLOCKS_PER_SEC; - o::ms() << L"# pfp: "; + o::ms() << "# pfp: "; measure_time_start(); } bool r = pfp(steps ? nstep + steps : 0, break_on_step); if (r && prog_after_fp.size()) add_prog(move(prog_after_fp), {}, false), r = pfp(); if (optimize) - (o::ms() < env; typedef bdd_handles level; typedef std::set> flat_prog; -std::wostream& operator<<(std::wostream& os, const env& e); +template +std::basic_ostream& operator<<(std::basic_ostream& os, const env& e); template struct ptrcmp { bool operator()(const T* x, const T* y) const { return *x < *y; } @@ -183,16 +184,24 @@ class tables { }; typedef std::vector>> proof; - void print(std::wostream&, const proof_elem&); - void print(std::wostream&, const proof&); - void print(std::wostream&, const witness&); - std::wostream& print(std::wostream& os, const std::vector& b) + template + void print(std::basic_ostream&, const proof_elem&); + template + void print(std::basic_ostream&, const proof&); + template + void print(std::basic_ostream&, const witness&); + template + std::basic_ostream& print(std::basic_ostream&, const std::vector& b) const; - std::wostream& print(std::wostream& os, const std::set& b) const; - std::wostream& print(std::wostream& os, const term& h, + template + std::basic_ostream& print(std::basic_ostream&, const std::set& b) const; + template + std::basic_ostream& print(std::basic_ostream&, const term& h, const std::set& b) const; - std::wostream& print(std::wostream& os, const flat_prog& p) const; - std::wostream& print(std::wostream& os, const rule& r) const; + template + std::basic_ostream& print(std::basic_ostream&, const flat_prog& p) const; + template + std::basic_ostream& print(std::basic_ostream&, const rule& r) const; nlevel nstep = 0; std::vector tbls; @@ -278,7 +287,7 @@ class tables { spbdd_handle addtail(cr_spbdd_handle x, size_t len1, size_t len2) const; spbdd_handle body_query(body& b, size_t); spbdd_handle alt_query(alt& a, size_t); - spbdd_handle alt_query_bltin(alt& a, bdd_handles& v1); //XXX review + void alt_query_bltin(alt& a, bdd_handles& v1); //XXX review DBG(vbools allsat(spbdd_handle x, size_t args) const;) void decompress(spbdd_handle x, ntable tab, const cb_decompress&, size_t len = 0, bool allowbltins = false) const; @@ -296,7 +305,8 @@ class tables { void print_env(const env& e) const; struct elem get_elem(int_t arg) const; raw_term to_raw_term(const term& t) const; - void out(std::wostream&, spbdd_handle, ntable) const; + template + void out(std::basic_ostream&, spbdd_handle, ntable) const; void out(spbdd_handle, ntable, const rt_printer&) const; void get_nums(const raw_term& t); flat_prog to_terms(const raw_prog& p); @@ -307,7 +317,7 @@ class tables { void set_priorities(const flat_prog&); ntable get_new_tab(int_t x, ints ar); lexeme get_new_rel(); - void load_string(lexeme rel, const std::wstring& s); + void load_string(lexeme rel, const std::string& s); lexeme get_var_lexeme(int_t i); void add_prog(flat_prog m, const std::vector&, bool mknums = false); @@ -343,7 +353,8 @@ class tables { int_t rel_tml_update, sym_add, sym_del; void init_tml_update(); void add_tml_update(const term& rt, bool neg); - std::wostream& decompress_update(std::wostream& os, spbdd_handle& x, + template + std::basic_ostream& decompress_update(std::basic_ostream&, spbdd_handle& x, const rule& r); // decompress for --print-updates and tml_update bool from_raw_form(const raw_form_tree *rs, form *&froot, bool &is_sol); @@ -410,16 +421,19 @@ class tables { size_t break_on_step = 0); bool run_nums(flat_prog m, std::set& r, size_t nsteps); bool pfp(size_t nsteps = 0, size_t break_on_step = 0); - void out(std::wostream&) const; + template + void out(std::basic_ostream&) const; void out(const rt_printer&) const; #ifdef __EMSCRIPTEN__ void out(emscripten::val o) const; #endif void set_proof(bool v) { bproof = v; } - bool get_goals(std::wostream& os); + template + bool get_goals(std::basic_ostream&); dict_t& get_dict() { return dict; } - std::wostream& print_dict(std::wostream& os) const; + template + std::basic_ostream& print_dict(std::basic_ostream&) const; bool populate_tml_update = false; bool print_updates = false; bool print_steps = false; @@ -523,7 +537,8 @@ struct substitution: public transformer { }; -std::wostream& operator<<(std::wostream& os, const vbools& x); +template +std::basic_ostream& operator<<(std::basic_ostream& os, const vbools& x); struct unsat_exception : public std::exception { virtual const char* what() const noexcept { return "unsat."; } diff --git a/src/tables_ext.cpp b/src/tables_ext.cpp index 53887b5b..d6f6eb84 100644 --- a/src/tables_ext.cpp +++ b/src/tables_ext.cpp @@ -81,7 +81,7 @@ spbdd_handle tables::fol_eval(form *f) { //set_constants(t,a,q); //b.perm = get_perm(t, vm, len), //check get_body ex_typebits(q, nvars); - o::dbg() << L" ------------------- " << ::bdd_root(q) << L" :\n"; + o::dbg() << " ------------------- " << ::bdd_root(q) << " :\n"; ::out(wcout, q)<l), fol_eval(f->r)); ex_typebits(q, nvars); - o::dbg() << L" implies ------------------- " << ::bdd_root(q) << L" :\n"; + o::dbg() << " implies ------------------- " << ::bdd_root(q) << " :\n"; ::out(wcout, q)<r); //TOO: permute according to: f->l->arg - o::dbg() << L" in forall ------------------- " << ::bdd_root(q) << L" :\n"; + o::dbg() << " in forall ------------------- " << ::bdd_root(q) << " :\n"; ::out(wcout, q)< bsize) bsize = elem; count++; - //o::dbg() << elem << L" , "; + //o::dbg() << elem << " , "; } - o::dbg() << L" BDD size for adder bit " << b-2 << L" : " - << bsize << L" , " << count << endl; + o::dbg() << " BDD size for adder bit " << b-2 << " : " + << bsize << " , " << count << endl; */ } @@ -390,9 +390,9 @@ spbdd_handle tables::add_var_eq(size_t var0, size_t var1, size_t var2, { if (elem > bsize) bsize = elem; count++; - //o::dbg() << elem << L" , "; + //o::dbg() << elem << " , "; } - o::dbg() << L" BDD size for adder eq : " << bsize << L" , " \ + o::dbg() << " BDD size for adder eq : " << bsize << " , " \ << count << endl; */ bdd::gc(); @@ -411,7 +411,7 @@ spbdd_handle tables::add_ite_carry(size_t var0, size_t var1, size_t n_vars, if ((it = carrymemo.find(x = { var0, var1, n_vars, bits, i, j })) != carrymemo.end()) { - //o::dbg() << L" [ memo carry]: " << i << L" -- " << j << endl; + //o::dbg() << " [ memo carry]: " << i << " -- " << j << endl; return it->second; } @@ -443,12 +443,12 @@ spbdd_handle tables::add_ite_carry(size_t var0, size_t var1, size_t n_vars, spbdd_handle tables::add_ite(size_t var0, size_t var1, size_t n_vars, uint_t i, uint_t j) { - //o::dbg() << L" [ ADDITE : " << bits << L" ]: " << i << L" -- " << j << endl; + //o::dbg() << " [ ADDITE : " << bits << " ]: " << i << " -- " << j << endl; static alumemo x; static map::const_iterator it; if ((it = addermemo.find(x = { var0, var1, n_vars, bits, i, j })) != addermemo.end()) { - //o::dbg() << L" [adder memo]: " << i << L" -- " << j << endl; + //o::dbg() << " [adder memo]: " << i << " -- " << j << endl; return it->second; } @@ -460,7 +460,7 @@ spbdd_handle tables::add_ite(size_t var0, size_t var1, size_t n_vars, uint_t i, } //-- - //o::dbg() << L" [ ADDITE ]: " << i << L" -- " << j << endl; + //o::dbg() << " [ ADDITE ]: " << i << " -- " << j << endl; else if (i == 2 || j == 2) { r = ::from_bit(pos(j, var0, n_vars),true) && @@ -540,9 +540,9 @@ spbdd_handle tables::mul_var_eq(size_t var0, size_t var1, size_t var2, { if (elem > bsize) bsize = elem; count++; - o::dbg() << elem << L" , "; + o::dbg() << elem << " , "; } - o::dbg() << L" BDD size for " << bits-2 << L" : " << bsize << L" , " << count << endl; + o::dbg() << " BDD size for " << bits-2 << " : " << bsize << " , " << count << endl; */ //*sizes.end() bdd::gc(); @@ -657,7 +657,7 @@ spbdd_handle tables::shl(size_t var0, size_t n, size_t var2, if (j == var0 ) perm1[i*n_vars+j] = perm1[(i+n)*n_vars+j]; - wcout << i*n_vars+j+1 << L"--" << perm1[i*n_vars+j]+1 << endl; + COUT << i*n_vars+j+1 << "--" << perm1[i*n_vars+j]+1 << endl; } @@ -678,22 +678,22 @@ spbdd_handle tables::shl(size_t var0, size_t n, size_t var2, //----------------------------------------------------------------------------- // bitwise operators t_arith_op tables::get_bwop(lexeme l) { - if (l == L"bw_and") + if (l == "bw_and") return BITWAND; - else if (l == L"bw_or") + else if (l == "bw_or") return BITWOR; - else if (l == L"bw_xor") + else if (l == "bw_xor") return BITWXOR; - else if (l == L"bw_not") + else if (l == "bw_not") return BITWNOT; else return NOP; } // pairwise operators t_arith_op tables::get_pwop(lexeme l) { - if (l == L"pw_add") + if (l == "pw_add") return ADD; - else if (l == L"pw_mult") + else if (l == "pw_mult") return MULT; else return NOP; } @@ -731,7 +731,7 @@ spbdd_handle tables::perm_from_to(size_t from, size_t to, spbdd_handle in, size_ for (size_t i = 0; i < n_bits; i++) { for (size_t j = 0; j < n_vars; ++j) { if (j == from ) { - //wcout << perm1[i*n_vars+j] << L" ** " << perm1[i*n_vars+to] << endl; + //COUT << perm1[i*n_vars+j] << " ** " << perm1[i*n_vars+to] << endl; perm1[i*n_vars+j] = perm1[i*n_vars+to]; } } @@ -901,7 +901,7 @@ spbdd_handle tables::bdd_mult_test(size_t n_vars) { //XXX: check need of gc here bdd::gc(); - //wcout << L" ------------------- bdd mult :\n"; + //COUT << " ------------------- bdd mult :\n"; spbdd_handle test = bdd_mult_dfs(s0, s1, bits-2, n_args); //bit reverse and append type bits @@ -914,7 +914,7 @@ spbdd_handle tables::bdd_mult_test(size_t n_vars) { spbdd_handle tables::bdd_add_test(size_t n_vars) { - o::dbg() << L" ------------------- bdd adder :\n"; + o::dbg() << " ------------------- bdd adder :\n"; spbdd_handle s0 = bdd_handle::F; s0 = s0 || from_sym(0,3,mknum(2)); @@ -964,7 +964,7 @@ spbdd_handle tables::bdd_test(size_t n_vars) { s0 = s0 || from_sym( 0, 3, mknum(6)); s0 = s0 || from_sym( 0, 3, mknum(7)); //s0 = s0 || from_sym( 0, 3, mknum(1)); - o::dbg() << L" ------------------- S0 " << L":\n"; + o::dbg() << " ------------------- S0 " << ":\n"; ::out(o::dbg(), s0)<& m); }; -std::wostream& operator<<(std::wostream& os, const term& t); +template +std::basic_ostream& operator<<(std::basic_ostream& os, const term& t); std::vector to_vec(const term& h, const std::set& b); template std::set vec2set(const std::vector& v, size_t n = 0); diff --git a/src/transform.cpp b/src/transform.cpp index bbebfc10..84600393 100644 --- a/src/transform.cpp +++ b/src/transform.cpp @@ -10,11 +10,12 @@ // from the Author (Ohad Asor). // Contact ohad@idni.org for requesting a permission. This license may be // modified over time by the Author. +#include #include "driver.h" #include "err.h" using namespace std; -/*lexeme driver::get_char_lexeme(wchar_t c) { +/*lexeme driver::get_char_lexeme(char_t c) { wstring s; return dict.get_lexeme(s += c); } @@ -22,19 +23,20 @@ using namespace std; lexeme driver::get_num_lexeme(int_t n) { return dict.get_lexeme(to_wstring(n));} */ -lexeme driver::get_lexeme(const wstring& s) { - cws w = s.c_str(); - auto it = strs_extra.find({w, w + s.size()}); +lexeme driver::get_lexeme(const string& s) { + ccs w = s.c_str(); + auto it = strs_extra.find({ w, w + s.size() }); if (it != strs_extra.end()) return *it; - wstr r = wcsdup(s.c_str()); - lexeme l = {r, r + s.size()}; + cstr r = strdup(s.c_str()); + strs_allocated.push_back(r); + lexeme l = { r, r + s.size() }; strs_extra.insert(l); return l; } lexeme driver::get_var_lexeme(int_t i) { - wstring s = L"?v"; - return get_lexeme(s += to_wstring_(i)); + std::string s = "?v"; + return get_lexeme(s += to_string_(i)); } #define get_var_elem(i) elem(elem::VAR, get_var_lexeme(i)) @@ -83,7 +85,7 @@ set driver::refresh_vars(raw_rule& r) { /*struct lexemecmp { bool operator()(const lexeme& x, const lexeme& y) const { return x[1]-x[0] != y[1]-y[0] ? x[1]-x[0] < y[1]-y[0] : - (wcsncmp(x[0], y[0], x[1]-x[0]) < 0); + (STRNCMP(x[0], y[0], x[1]-x[0]) < 0); } };*/ @@ -106,10 +108,10 @@ raw_term driver::from_grammar_elem_nt(const lexeme& r, const elem& c, t.e.emplace_back(get_var_elem(v2)), t.e.emplace_back(elem_closep), t.e.emplace_back(elem_closep), t.e.emplace_back(elem_closep); - return t.calc_arity(), t; + return t.calc_arity(*(ii->current())), t; } -raw_term driver::from_grammar_elem_builtin(const lexeme& r, const wstring& b, +raw_term driver::from_grammar_elem_builtin(const lexeme& r, const string& b, int_t v){ return { false, raw_term::REL, NOP, { elem(elem::SYM, r), @@ -120,7 +122,7 @@ raw_term driver::from_grammar_elem_builtin(const lexeme& r, const wstring& b, /*#define from_string_lex(rel, lex, n) raw_rule({ false, { \ elem(elem::SYM, rel), \ elem_openp, \ - elem(elem::SYM, dict.get_lexeme(lex)), \ + elem(elem::SYM, dict.get_lexeme(to_string_t(lex))), \ elem(n), elem(n+1), \ elem_closep},{3}}) @@ -134,21 +136,21 @@ void driver::transform_string(const wstring& s, raw_prog& r, int_t rel) { elem_closep, elem_openp, elem_openp, elem(n+1), elem_closep, elem_closep, elem_closep},{}})); r.r.back().h[0].calc_arity(); - if (iswspace(s[n])) + if (ISSPACE(s[n])) r.r.push_back(from_string_lex( - dict.get_rel(rel), L"space", n)); - if (iswdigit(s[n])) + dict.get_rel(rel), "space", n)); + if (ISDIGIT(s[n])) r.r.push_back(from_string_lex( - dict.get_rel(rel), L"digit", n)); - if (iswalpha(s[n])) + dict.get_rel(rel), "digit", n)); + if (ISALPHA(s[n])) r.r.push_back(from_string_lex( - dict.get_rel(rel), L"alpha", n)); - if (iswalnum(s[n])) + dict.get_rel(rel), "alpha", n)); + if (ISALNUM(s[n])) r.r.push_back(from_string_lex( - dict.get_rel(rel), L"alnum", n)); - if (iswprint(s[n])) + dict.get_rel(rel), "alnum", n)); + if (ISPRINT(s[n])) r.r.push_back(from_string_lex( - dict.get_rel(rel), L"printable", n)); + dict.get_rel(rel), "printable", n)); } }*/ @@ -166,7 +168,7 @@ void elim_nullables(set& s) { loop1: size_t sz = nullables.size(); for (const production& p : s) { bool null = true; - if (p.p.size() != 2 || !(p.p[1].e == L"null")) + if (p.p.size() != 2 || !(p.p[1].e == "null")) for (size_t n = 1; null && n != p.p.size(); ++n) null &= has(nullables, p.p[n]); if (null) nullables.insert(p.p[0]); @@ -174,7 +176,7 @@ loop1: size_t sz = nullables.size(); if (sz != nullables.size()) goto loop1; set t; for (auto p : s) - if (p.p.size() == 2 && p.p[1].e == L"null") + if (p.p.size() == 2 && p.p[1].e == "null") t.insert(p); for (auto x : t) s.erase(x); t.clear(); @@ -197,17 +199,17 @@ loop2: sz = s.size(); void driver::transform_grammar(raw_prog& r, lexeme rel, size_t len) { if (r.g.empty()) return; - static const set b = - { L"alpha", L"alnum", L"digit", L"space", L"printable"}; + static const set b = + { "alpha", "alnum", "digit", "space", "printable" }; for (size_t k = 0; k != r.g.size();) { if (r.g[k].p.size()<2)parse_error(err_empty_prod,r.g[k].p[0].e); size_t n = 0; while (n(r.g[k].p.begin(), r.g[k].p.begin() + n)}); - r.g.push_back( - {vector(r.g[k].p.begin()+n+1, r.g[k].p.end())}); + r.g.push_back({ + vector(r.g[k].p.begin(), r.g[k].p.begin() + n) }); + r.g.push_back({ + vector(r.g[k].p.begin()+n+1, r.g[k].p.end()) }); r.g.back().p.insert(r.g.back().p.begin(), r.g[k].p[0]); r.g.erase(r.g.begin() + k); } @@ -217,8 +219,8 @@ void driver::transform_grammar(raw_prog& r, lexeme rel, size_t len) { lexeme l = p.p[n].e; p.p.erase(p.p.begin() + n); bool esc = false; - for (cws s = l[0]+1; s != l[1]-1; ++s) - if (*s == L'\\' && !esc) esc=true; + for (ccs s = l[0]+1; s != l[1]-1; ++s) + if (*s == '\\' && !esc) esc=true; else p.p.insert(p.p.begin()+n++, elem(*s)),esc=false; } @@ -232,7 +234,7 @@ void driver::transform_grammar(raw_prog& r, lexeme rel, size_t len) { #endif raw_rule l; /* raw_term m; - m = fro_grammar_elem({elem::SYM,0,dict.get_lexeme(L"null")},1,1); + m = fro_grammar_elem({elem::SYM,0,dict.get_lexeme("null")},1,1); l.add_head(m); l.add_body(from_grammar_elem_nt(r.d[0].rel.e, {elem::VAR,0,get_var_lexeme(2)},1,3)); @@ -243,7 +245,7 @@ void driver::transform_grammar(raw_prog& r, lexeme rel, size_t len) { for (production& p : r.g) { if (p.p.size() < 2) continue; l.clear(); - if (p.p.size() == 2 && p.p[1].e == L"null") { + if (p.p.size() == 2 && p.p[1].e == "null") { #ifndef ELIM_NULLS raw_term t = from_grammar_elem(p.p[0], 1, 1); l.h.push_back(t); @@ -267,10 +269,11 @@ void driver::transform_grammar(raw_prog& r, lexeme rel, size_t len) { rel, p.p[n], n, n+1)); continue; } - wstring str = lexeme2str(p.p[n].e); + std::string str = lexeme2str(p.p[n].e); if (has(b, str)) - l.b.back().push_back(from_grammar_elem_builtin( - rel, str,n)), ++v; + l.b.back().push_back( + from_grammar_elem_builtin( + rel, str,n)), ++v; else l.b.back().push_back( from_grammar_elem(p.p[n],n,n+1)); } @@ -278,24 +281,24 @@ void driver::transform_grammar(raw_prog& r, lexeme rel, size_t len) { r.r.push_back(l); } raw_term t; - append_sym_elem(t.e, get_lexeme(L"S")), append_openp(t.e), + append_sym_elem(t.e, get_lexeme("S")), append_openp(t.e), t.e.push_back(elem((int_t)0)), t.e.push_back(elem((int_t)len)), - append_closep(t.e), t.calc_arity(); + append_closep(t.e), t.calc_arity(*(ii->current())); raw_rule rr; rr.type = raw_rule::GOAL, rr.h = {t}, r.r.push_back(rr); - DBG(o::out()<<"transformed grammar:"<{ r, _r }; } /*void driver::insert_goals(raw_prog& r, const std::vector& g) { for (const raw_rule& t : g) { raw_term gg; - cat_relsym_openp(gg, L"G"), cat(gg.e, t.head(0).e), + cat_relsym_openp(gg, "G"), cat(gg.e, t.head(0).e), term_close(gg), r.r.emplace_back(gg, t.head(0)); } } @@ -322,7 +325,7 @@ nexthead: const raw_term &head = x.head(n); }*/ /*raw_term driver::get_try_pred(const raw_term& x) { - static elem tr(elem::SYM, dict.get_lexeme(L"try")); + static elem tr(elem::SYM, dict.get_lexeme("try))); raw_term t; return t.e.push_back(tr), append_openp(t.e), t.e.insert(t.e.begin()+2, x.e.begin(), x.e.end()), @@ -394,7 +397,7 @@ raw_term sub(const raw_term& x, map& m) { bool specialize(const raw_rule& r, const raw_term& t, raw_rule& res) { if (r.b.empty()) return res.h = r.h, true; -// DBG(o::out() << L"specializing" << endl << r << "wrt" << endl << t < m; if (!unify(h, t, m)) continue; @@ -406,9 +409,9 @@ bool specialize(const raw_rule& r, const raw_term& t, raw_rule& res) { } } if (res.h.size()) goto pass; -// DBG(o::out() << L" failed " << endl;) +// DBG(o::out() << " failed " << endl;) return false; -pass: //DBG(o::out() << L" returned " << res << endl;) +pass: //DBG(o::out() << " returned " << res << endl;) return true; }*/ @@ -436,7 +439,8 @@ struct flat_rules : public vector { } }; -wostream& operator<<(wostream& os, const flat_rules& f) { +template +std::basic_ostream& operator<<(std::basic_ostream& os, const flat_rules& f) { for (auto x : f) os << raw_rule(x.first, x.second) << endl; return os; } @@ -557,11 +561,11 @@ set driver::get_queries(const raw_prog& p) { }*/ /*lexeme driver::get_demand_lexeme(elem e, const ints& i, const bools& b) { - wstring s; - for (int_t j : i) s += to_wstring(j); - s += L'_'; - for (bool x : b) s += x ? L'b' : L'f'; - return dict.get_lexeme(wstring(L"d_") + lexeme2str(e.e) + s); + sysstring_t s; + for (int_t j : i) s += to_string_t(j); + s += '_'; + for (bool x : b) s += x ? 'b' : 'f'; + return dict.get_lexeme(to_string_t("d_") + lexeme2str(e.e) + s); } #define get_demand_elem(t, b)\ @@ -594,10 +598,10 @@ raw_prog driver::transform_sdt(const raw_prog& p) { #ifdef TRANSFORM_BIN_DRIVER lexeme driver::get_new_rel() { static size_t last = 1; - wstring s = L"r"; + string s = "r"; size_t sz; lexeme l; -retry: sz = rels.size(), l = get_lexeme(s + to_wstring(last)); +retry: sz = rels.size(), l = get_lexeme(s + to_string_(last)); rels.insert(l); if (rels.size() == sz) { ++last; goto retry; } return l; @@ -661,10 +665,10 @@ void driver::transform_bin(raw_prog& p) { for (const raw_term& y : x) rels.emplace(x.e[0]); } - elem relname = elem(elem::SYM, dict.get_lexeme(L"relname")); - elem fact = elem(elem::SYM, dict.get_lexeme(L"fact")); - elem rule = elem(elem::SYM, dict.get_lexeme(L"rule")); - lexeme op = dict.get_lexeme(L"("), cp = dict.get_lexeme(L")"); + elem relname = elem(elem::SYM, dict.get_lexeme(Lrelname")); + elem fact = elem(elem::SYM, dict.get_lexeme("fact")); + elem rule = elem(elem::SYM, dict.get_lexeme("rule")); + lexeme op = dict.get_lexeme("("), cp = dict.get_lexeme(")"); raw_term t; for (const lexeme& l : rels) t.e = { r, elem_openp, l, elem_closep }, diff --git a/src/tree.cpp b/src/tree.cpp index dcfa42ab..acee2686 100644 --- a/src/tree.cpp +++ b/src/tree.cpp @@ -75,10 +75,10 @@ void driver::get_trees(wostream& os, const term& root, const map>& m, set& done) { if (!done.emplace(root).second) return; for (int_t i : root.args()) - if (i & 1) os << (wchar_t)(i>>2); + if (i & 1) os << (char)(i>>2); else if (i & 2) os << (int_t)(i>>2); else if ((size_t)(i>>2) < dict.nsyms()) os << dict.get_sym(i); - else os << L'[' << (i>>2) << L']'; + else os << '[' << (i>>2) << ']'; auto it = m.find(root); if (it == m.end()) return; for (auto x : it->second) get_trees(os, x, m, done); @@ -97,5 +97,5 @@ wstring driver::get_trees(const term& root, const db_t& t, size_t bits) { wstringstream ss; return get_trees(ss, root, m, done), ss.str(); -// o::out() << L"get_trees: " << ss.str() << endl; +// o::out() << "get_trees: " << ss.str() << endl; } diff --git a/src/udp.h b/src/udp.h index 5589895e..e0ff2204 100644 --- a/src/udp.h +++ b/src/udp.h @@ -39,13 +39,13 @@ class udp : public async_reader { // size_t buflen = BUFLEN; bool closed=true; bool error_=false; - std::wstring error_message_; + std::string error_message_; int s, b; bool create_socket() { s = socket(family, SOCK_DGRAM, IPPROTO_UDP); if (s == -1) { error_ = true; - error_message_ = L"socket_error"; + error_message_ = "socket_error"; return false; } fcntl(s, F_SETFL, fcntl(s, F_GETFL, 0) | O_NONBLOCK); @@ -62,7 +62,7 @@ class udp : public async_reader { b = bind(s, (struct sockaddr*) &sin, sizeof(sin)); if (b == -1) { error_ = true; - error_message_ = L"bind error"; + error_message_ = "bind error"; return false; } closed = false; @@ -81,7 +81,7 @@ class udp : public async_reader { // std::lock_guard lk(m); if (!create_socket()) return; if (!bind_socket()) return; - // std::wcout< { to, sizeof(struct sockaddr)); if (sent_len == -1) return false; // std::lock_guard lk(m); - // std::wcout << L"sent: " << sent_len << L" bytes to: " << - // inet_ntoa(((struct sockaddr_in *)&to)->sin_addr) << L':' << + // COUT << "sent: " << sent_len << " bytes to: " << + // inet_ntoa(((struct sockaddr_in *)&to)->sin_addr) << ':' << // ntohs(((struct sockaddr_in *)&to)->sin_port) << std::endl; return true; } void close() { if (!closed) ::close(s), eof = closed = true; } bool error() { return error_; } - std::wstring error_message() { return error_message_; } + std::string error_message() { return error_message_; } ~udp() { close(); } private: socklen_t clen = sizeof(struct sockaddr *); @@ -114,8 +114,8 @@ class udp : public async_reader { recv_len = recvfrom(s, buf, BUFLEN, 0, client.get(), &clen); if (recv_len == -1) goto skip; - // m.lock(); std::wcout << L"received: " << recv_len << L" bytes from: " << - // inet_ntoa(((struct sockaddr_in *)&client)->sin_addr) << L':' << + // m.lock(); COUT << "received: " << recv_len << " bytes from: " << + // inet_ntoa(((struct sockaddr_in *)&client)->sin_addr) << ':' << // ntohs(((struct sockaddr_in *)&client)->sin_port) << std::endl; if (recv_len > 0) { m.lock(); diff --git a/src/utils.cpp b/src/utils.cpp index 25ff31e4..fca34a30 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -20,25 +20,21 @@ using namespace std; -wstring s2ws(const std::string& s) { +wstring s2ws(const string& s) { return wstring_convert>().from_bytes(s); } - string ws2s(const wstring& s) { return wstring_convert>().to_bytes(s); } +wstring s2ws(const wstring& s) { return s; } +string ws2s(const string& s) { return s; } -#ifdef _WIN32 - -// to_string and to_wstring is not available under mingw gcc compiler -std::string to_string_(int_t v) { - std::stringstream ss; ss << v; return ss.str(); -} +std::wostream& operator<<(wostream& os, const string& s){ return os << s2ws(s);} +std::ostream& operator<<(ostream& os, const char c) { return os.put(c); } -std::wstring to_wstring_(int_t v) { - std::wstringstream ss; ss << v; return ss.str(); -} +std::string to_string_(int_t v) { stringstream ss; ss << v; return ss.str(); } +#ifdef _WIN32 std::string temp_filename() { TCHAR name[MAX_PATH], path[MAX_PATH]; DWORD r = GetTempPath(MAX_PATH, path); @@ -46,19 +42,11 @@ std::string temp_filename() { !GetTempFileName(path, TEXT("TMLXXXX"), 0, name)) return ""; return std::string(name); } - #else - -std::string to_string_(int_t v) { return to_string(v); } - -std::wstring to_wstring_(int_t v) { return to_wstring(v); } - int temp_fileno() { return fileno(std::tmpfile()); } - std::string filename(int fd) { return std::filesystem::read_symlink( std::filesystem::path("/proc/self/fd") / std::to_string(fd)); } - #endif diff --git a/tests/archive.test.cpp b/tests/archive.test.cpp index e67395e4..0e457997 100644 --- a/tests/archive.test.cpp +++ b/tests/archive.test.cpp @@ -22,25 +22,24 @@ using namespace std; dict_t test_dict; template -test write_test(const T& value, const char* expected, size_t s) { - //wcout << L"creating write test value: " << value << endl; - return [value, expected, s] { - //wcout << L"writing: " << value << L" size: " << s << endl; +test write_test(const T& value, const char* expected, size_t expected_s) { + return [value, expected, expected_s] { + size_t s = archive::size(value); archive a(TF1, s, true); a << value; - if (file_and_mem_cmp(TF1, expected, s)) - return fail(L"write: failed"); + if (file_and_mem_cmp(TF1, expected, expected_s)) + return fail("write: failed"); + if (s != expected_s) + return fail("write: failed (expected size)"); return ok(); }; } template test write_test_ref(const T& value, const char* expected, size_t s) { - //wcout << L"creating write test value: " << value << endl; return [&value, expected, s] { - //wcout << L"writing: " << value << L" size: " << s << endl; archive a(TF1, s, true); a << value; if (file_and_mem_cmp(TF1, expected, s)) - return fail(L"write: failed"); + return fail("write: failed"); return ok(); }; } @@ -50,7 +49,7 @@ test read_test(function ok_cond) { return [ok_cond] { T value; archive a(TF1, 0, false); a >> value; - if (!ok_cond(value)) return fail(L"read: failed"); + if (!ok_cond(value)) return fail("read: failed"); return ok(); }; }; @@ -59,7 +58,7 @@ template test read_test_ref(T& value, function ok_cond) { return [ok_cond, &value] { archive a(TF1, 0, false); a >> value; - if (!ok_cond(value)) return fail(L"read: failed"); + if (!ok_cond(value)) return fail("read: failed"); return ok(); }; }; @@ -86,42 +85,37 @@ test read_unsigned_char = read_test([](const unsigned char& v){ return v == 250; }); test write_string = write_test(string("Hello World!"), - "\x0c\0\0\0\0\0\0\0Hello World!", 20); + "\x0c\0\0\0\0\0\0\0Hello World!\0", 21); test read_string = read_test( [](const string& val){ return val == string("Hello World!"); }); -test write_wstring = write_test(wstring(L"Hello World!"), - "\x0c\0\0\0\0\0\0\0Hello World!", 20); -test read_wstring = read_test( - [](const wstring& val){ return val == wstring(L"Hello World!"); }); - dict_t& data_dict_input() { static dict_t d; if (d.nsyms() == 0) { - d.get_rel(d.get_lexeme(L"rel1")); - d.get_rel(d.get_lexeme(L"rel2")); - d.get_sym(d.get_lexeme(L"symbol1")); - d.get_sym(d.get_lexeme(L"symbol2")); - d.get_sym(d.get_lexeme(L"symbol3")); - d.get_bltin(d.get_lexeme(L"bltin1")); - d.get_bltin(d.get_lexeme(L"bltin2")); + d.get_rel(d.get_lexeme("rel1")); + d.get_rel(d.get_lexeme("rel2")); + d.get_sym(d.get_lexeme("symb`ol1")); + d.get_sym(d.get_lexeme("symb`ol2")); + d.get_sym(d.get_lexeme("symbol3`")); + d.get_bltin(d.get_lexeme("blt`in1")); + d.get_bltin(d.get_lexeme("blt`in2")); } return d; } -test write_dict = write_test_ref(data_dict_input(), - data_dict_expected, data_dict_expected_length); -test read_dict = read_test([](dict_t& d) { - return d.nrels() == 2 && - d.nsyms() == 3 && - d.nbltins() == 2 && - d.get_rel(d.get_lexeme(L"rel2")) == 1 && - d.get_rel(d.get_lexeme(L"rel1")) == 0 && - d.get_sym(d.get_lexeme(L"symbol3")) == 2 && - d.get_sym(d.get_lexeme(L"symbol2")) == 1 && - d.get_sym(d.get_lexeme(L"symbol1")) == 0 && - d.get_bltin(d.get_lexeme(L"bltin2")) == 1 && - d.get_bltin(d.get_lexeme(L"bltin1")) == 0; -}); +//test write_dict = write_test_ref(data_dict_input(), +// data_dict_expected, data_dict_expected_length); +//test read_dict = read_test([](dict_t& d) { +// return d.nrels() == 2 && +// d.nsyms() == 3 && +// d.nbltins() == 2 && +// d.get_rel(1) == "rel2" && +// d.get_rel((int_t)0) == "rel1" && +// d.get_sym(2) == "symbol3" && +// d.get_sym(1) == "symbol2" && +// d.get_sym((int_t)0) == "symbol1" && +// d.get_bltin(1) == "bltin2" && +// d.get_bltin((int_t)0) == "bltin1"; +//}); test write_sig = write_test({ 3000, ints{ -500, 256, 0 } }, "\xb8\x0b\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00" @@ -132,14 +126,15 @@ test read_sig = read_test([] (sig& s) { }); test write_bdd_test = [] { + inputs ii; outputs oo; oo.use(); oo.init_defaults(); bdd::init(); - driver d(L"a(x). b(y) :- a(x).", - options({ "--no-info", "--no-debug", "--no-benchmarks" }, &oo)); + driver d("a(x). b(y) :- a(x).", options({ "--no-info", "--no-debug", + "--no-benchmarks" }, &ii, &oo)); d.run(); { archive a(TF1, archive::bdd_size(), true); a.write_bdd(); } if (file_and_mem_cmp(TF1, data_bdd_expected, data_bdd_expected_length)) - return fail(L"write bdd: failed"); + return fail("write bdd: failed"); return ok(); }; @@ -147,61 +142,61 @@ test read_bdd_test = [] { V->clear(); { archive a(TF1, 0, false); a.read_bdd(); } bdd_mmap& pV = *V; - if (pV.size()!=5) return fail(L"bdd read failed, size does not match"); - for (size_t i = 0; i != 5; ++i) + if (pV.size()!=8) return fail("bdd read failed, size does not match"); + for (size_t i = 0; i != 8; ++i) if (!(pV[i]==(data_bdd_read_expected[i]))) - return fail(L"bdd read failed"); + return fail("bdd read failed"); return ok(); }; test write_tables = [] { + inputs ii; outputs oo; oo.use(); oo.init_defaults(); bdd::init(); - driver d(L"a(x). b(y) :- a(x).", - options({ "--no-info", "--debug", "archive.test.debug", - "--no-benchmarks" }, &oo)); + driver d("a(x). b(y) :- a(x).", options({ "--no-info", "--debug", + "archive.test.debug", "--no-benchmarks" }, &ii, &oo)); d.run(); { archive a(TF1, archive::tables_size(d), true); a.write_tables(d); } if (file_and_mem_cmp(TF1, data_tables_expected, data_tables_expected_length)) - return fail(L"write tables: failed"); + return fail("write tables: failed"); return ok(); }; test write_driver = [] { + inputs ii; outputs oo; oo.use(); oo.init_defaults(); bdd::init(); - driver d(L"a(x). b(y) :- a(x). c(z) :- b(y).", + driver d("a(x). b(y) :- a(x). c(z) :- b(y).", options({ "--no-info", "--debug", "archive.test.debug", - "--no-benchmarks" }, &oo)); + "--no-benchmarks" }, &ii, &oo)); d.step(); - size_t s = archive::size(d); - { archive a(archive::type::DRIVER, TF1, s, true); a << d; } + + COUT << "d.out:" << endl; + d.out(COUT); + + d.save(TF1); + if (file_and_mem_cmp(TF1, data_driver_expected, data_driver_expected_length)) - //wcout << L"write driver: failed\n"; - return fail(L"write driver: failed"); + //COUT << "write driver: failed\n"; + return fail("write driver: failed"); return ok(); }; test read_driver = [] { - { - outputs oo; oo.use(); oo.init_defaults(); - driver d(options(strings{}, &oo)); - archive a(archive::type::DRIVER, TF1, 0, false); - a >> d; + inputs ii; + outputs oo; oo.use(); oo.init_defaults(); + driver d(options(strings{}, &ii, &oo)); - size_t s = archive::size(d); - wcout << L"archive::size(d): " << s << endl; + d.load(TF1); - archive b(archive::type::DRIVER, TF2, s, true); - b << d; + //d.save(TF2); - d.run(); + d.run(); - wcout << L"d.out:" << endl; - d.out(wcout); - } + COUT << "d.out:" << endl; + d.out(COUT); return ok(); }; @@ -209,14 +204,14 @@ test read_driver = [] { test no_mmap_write_int = [] { char data[4], expected[4] = { '\xbd', '\xd0', '\0', '\0' }; archive a(data, 4); a << 53437; - if (memcmp(data, expected, 4)) return fail(L"no mmap write int_t"); + if (memcmp(data, expected, 4)) return fail("no mmap write int_t"); return ok(); }; test no_mmap_read_int = [] { char data[4] = { '\xbd', '\xdd', '\0', '\0' }; archive a(data, 4); int_t r; a >> r; - if (56765 != r) return fail(L"no mmap read int_t"); + if (56765 != r) return fail("no mmap read int_t"); return ok(); }; @@ -231,95 +226,30 @@ int main() { data_options_expected_length); test read_options = read_test([](options& opts){ - wstringstream ss; ss<(term(24, ints{-5, 3, 0}, ats), - "\x18\0\0\0\0\0\x03\0\0\0\0\0\0\0\xfb\xff\xff\xff\x03\0", 20); - term t(0, {}, {}); - test read_term = read_test_ref(t, [](term& t){ - return t.size() == 3 && t.tab == 24 && - t.extype == term::REL && !t.neg && !t.goal && - t[0] == -5 && t[1] == 3 && t[2] == 0; + ostringstream_t ss; ss<( - rule(true, 12, term(true, (ntable)12, ints{}, - std::vector{}, types_int)), - data_rules_expected, data_rules_expected_length); - rule r(false, -1, term(0, {}, {})); - test read_rule = read_test_ref(r, [](rule& r){ - return r.neg && r.tab == 12 && r.len == 0 && r.t.tab == 12 && - r.t.neg; - }); - - test write_primitive_type = write_test( - primitive_type(base_type::STR, 2, 4), - "\x03\x02\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00", 13); - test read_primitive_type = read_test( - [](primitive_type& pt) { - return pt.type == base_type::STR && pt.bitness == 2 && - pt.num == 4; }); - - test write_compound_type = write_test( - compound_type(vtypes{ - primitive_type(base_type::INT, 4, 32), - primitive_type(base_type::STR, 2, 3) - }, true), - data_compound_expected, data_compound_expected_length); - - test read_compound_type = read_test( - [](compound_type& ct) { - return ct == compound_type({ - primitive_type(base_type::INT, 4, 32), - primitive_type(base_type::STR, 2, 3) - }, true); - }); - test write_elem_num = write_test( - elem(3), "\x02\x03\x00\x00\x00\x00\x00\x00\x00", 9 + elem(3), "\x02\x03\x00\x00\x00", 5 ); test read_elem_num = read_test([] (elem& e) { return e.type == elem::NUM && e.num == 3; }); test write_elem_chr = write_test( - elem(L'â‚¿'), "\x03\xbf\x20\x00\x00\x00\x00\x00\x00", 9 + elem('$'), "\x03\x24\x00\x00\x00", 5 ); test read_elem_chr = read_test([] (elem& e) { - return e.type == elem::CHR && e.ch == L'â‚¿'; + return e.type == elem::CHR && e.ch == '$'; }); test write_elem_str = write_test( - elem(elem::STR, test_dict.get_lexeme(L"ABC")), "\x08\x03\x00\x00\x00\x00\x00\x00\x00\x41\x42\x43", 12 + elem(elem::STR, test_dict.get_lexeme("ABC")), "\x08\x03\x00\x00\x00\x00\x00\x00\x00\x41\x42\x43", 12 ); test read_elem_str = read_test([] (elem& e) { - return e.type == elem::STR && lexeme2str(e.e) == L"ABC"; + return e.type == elem::STR && lexeme2str(e.e) == "ABC"; }); vector tests = { - // lexeme - // lexeme_range - // spbdd_handle - // bitsmeta - // table - // raw_term - // raw_rule - // raw_prog - // raw_progs - // directive - // production - // strs_t - // pair - // map - // vector - // set - // rcm tuple no_mmap_write_int, no_mmap_read_int, write_int, @@ -334,34 +264,20 @@ int main() { read_unsigned_char, write_string, read_string, - write_wstring, - read_wstring, - write_dict, - read_dict, - write_options, - read_options, - write_bdd_test, - read_bdd_test, - write_term, - read_term, - write_rule, - read_rule, write_sig, read_sig, - write_primitive_type, - read_primitive_type, - write_compound_type, - read_compound_type, write_elem_num, read_elem_num, write_elem_chr, read_elem_chr, - write_elem_str, - read_elem_str, + write_options, + read_options, + write_bdd_test, + read_bdd_test, write_tables, - write_driver, - read_driver, +// write_driver, +// read_driver, }; - return run(tests, L"archive"); + return run(tests, "archive"); } diff --git a/tests/archive.test.data.h b/tests/archive.test.data.h index a990d38a..3c3cf076 100644 --- a/tests/archive.test.data.h +++ b/tests/archive.test.data.h @@ -11,55 +11,57 @@ // Contact ohad@idni.org for requesting a permission. This license may be // modified over time by the Author. -strings data_options_input = { +std::vector data_options_input = { "--no-info", "--no-debug", "--no-benchmarks", "--run", "false", "--transformed" }; -size_t data_options_expected_length = 416; +size_t data_options_expected_length = 376; char data_options_expected[] = - "\x10\x00\x00\x00\x00\x00\x00\x00" "\x01\x0c\x00\x00\x00\x00\x00\x00" - "\x00\x62\x64\x64\x2d\x6d\x61\x78" "\x2d\x73\x69\x7a\x65\x00\x00\x00" - "\x08\x03\x0a\x00\x00\x00\x00\x00" "\x00\x00\x62\x65\x6e\x63\x68\x6d" - "\x61\x72\x6b\x73\x05\x00\x00\x00" "\x00\x00\x00\x00\x40\x6e\x75\x6c" - "\x6c\x03\x05\x00\x00\x00\x00\x00" "\x00\x00\x64\x65\x62\x75\x67\x05" - "\x00\x00\x00\x00\x00\x00\x00\x40" "\x6e\x75\x6c\x6c\x03\x04\x00\x00" - "\x00\x00\x00\x00\x00\x64\x75\x6d" "\x70\x07\x00\x00\x00\x00\x00\x00" - "\x00\x40\x73\x74\x64\x6f\x75\x74" "\x03\x05\x00\x00\x00\x00\x00\x00" - "\x00\x65\x72\x72\x6f\x72\x07\x00" "\x00\x00\x00\x00\x00\x00\x40\x73" - "\x74\x64\x65\x72\x72\x02\x09\x00" "\x00\x00\x00\x00\x00\x00\x69\x6e" - "\x66\x65\x72\x65\x6e\x63\x65\x01" "\x03\x04\x00\x00\x00\x00\x00\x00" - "\x00\x69\x6e\x66\x6f\x05\x00\x00" "\x00\x00\x00\x00\x00\x40\x6e\x75" - "\x6c\x6c\x02\x08\x00\x00\x00\x00" "\x00\x00\x00\x6f\x70\x74\x69\x6d" - "\x69\x7a\x65\x01\x03\x06\x00\x00" "\x00\x00\x00\x00\x00\x6f\x75\x74" - "\x70\x75\x74\x07\x00\x00\x00\x00" "\x00\x00\x00\x40\x73\x74\x64\x6f" - "\x75\x74\x03\x0b\x00\x00\x00\x00" "\x00\x00\x00\x72\x65\x70\x6c\x2d" - "\x6f\x75\x74\x70\x75\x74\x07\x00" "\x00\x00\x00\x00\x00\x00\x40\x73" - "\x74\x64\x6f\x75\x74\x02\x03\x00" "\x00\x00\x00\x00\x00\x00\x72\x75" - "\x6e\x00\x02\x0c\x00\x00\x00\x00" "\x00\x00\x00\x73\x74\x72\x69\x6e" - "\x67\x74\x61\x62\x6c\x65\x73\x01" "\x03\x0b\x00\x00\x00\x00\x00\x00" - "\x00\x74\x72\x61\x6e\x73\x66\x6f" "\x72\x6d\x65\x64\x00\x00\x00\x00" - "\x00\x00\x00\x00\x03\x08\x00\x00" "\x00\x00\x00\x00\x00\x75\x64\x70" - "\x2d\x61\x64\x64\x72\x09\x00\x00" "\x00\x00\x00\x00\x00\x31\x32\x37" - "\x2e\x30\x2e\x30\x2e\x31\x01\x08" "\x00\x00\x00\x00\x00\x00\x00\x75" - "\x64\x70\x2d\x70\x6f\x72\x74\x8b" "\x18\x00\x00\x02\x0b\x00\x00\x00" - "\x00\x00\x00\x00\x7a\x65\x72\x6f" "\x76\x61\x72\x63\x6f\x6d\x70\x01"; -std::wstring data_options_read_expected = - L"--bdd-max-size 134217728 " +"\x0d\x00\x00\x00\x00\x00\x00\x00" "\x01\x0c\x00\x00\x00\x00\x00\x00" +"\x00\x62\x64\x64\x2d\x6d\x61\x78" "\x2d\x73\x69\x7a\x65\x00\x00\x00" +"\x00\x08\x03\x0a\x00\x00\x00\x00" "\x00\x00\x00\x62\x65\x6e\x63\x68" +"\x6d\x61\x72\x6b\x73\x00\x05\x00" "\x00\x00\x00\x00\x00\x00\x40\x6e" +"\x75\x6c\x6c\x00\x03\x05\x00\x00" "\x00\x00\x00\x00\x00\x64\x65\x62" +"\x75\x67\x00\x05\x00\x00\x00\x00" "\x00\x00\x00\x40\x6e\x75\x6c\x6c" +"\x00\x03\x04\x00\x00\x00\x00\x00" "\x00\x00\x64\x75\x6d\x70\x00\x07" +"\x00\x00\x00\x00\x00\x00\x00\x40" "\x73\x74\x64\x6f\x75\x74\x00\x03" +"\x05\x00\x00\x00\x00\x00\x00\x00" "\x65\x72\x72\x6f\x72\x00\x07\x00" +"\x00\x00\x00\x00\x00\x00\x40\x73" "\x74\x64\x65\x72\x72\x00\x03\x04" +"\x00\x00\x00\x00\x00\x00\x00\x69" "\x6e\x66\x6f\x00\x05\x00\x00\x00" +"\x00\x00\x00\x00\x40\x6e\x75\x6c" "\x6c\x00\x02\x08\x00\x00\x00\x00" +"\x00\x00\x00\x6f\x70\x74\x69\x6d" "\x69\x7a\x65\x00\x01\x03\x06\x00" +"\x00\x00\x00\x00\x00\x00\x6f\x75" "\x74\x70\x75\x74\x00\x07\x00\x00" +"\x00\x00\x00\x00\x00\x40\x73\x74" "\x64\x6f\x75\x74\x00\x03\x0b\x00" +"\x00\x00\x00\x00\x00\x00\x72\x65" "\x70\x6c\x2d\x6f\x75\x74\x70\x75" +"\x74\x00\x07\x00\x00\x00\x00\x00" "\x00\x00\x40\x73\x74\x64\x6f\x75" +"\x74\x00\x02\x03\x00\x00\x00\x00" "\x00\x00\x00\x72\x75\x6e\x00\x00" +"\x03\x0b\x00\x00\x00\x00\x00\x00" "\x00\x74\x72\x61\x6e\x73\x66\x6f" +"\x72\x6d\x65\x64\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x03\x08" +"\x00\x00\x00\x00\x00\x00\x00\x75" "\x64\x70\x2d\x61\x64\x64\x72\x00" +"\x09\x00\x00\x00\x00\x00\x00\x00" "\x31\x32\x37\x2e\x30\x2e\x30\x2e" +"\x31\x00\x01\x08\x00\x00\x00\x00" "\x00\x00\x00\x75\x64\x70\x2d\x70" +"\x6f\x72\x74\x00\x8b\x18\x00\x00"; +std::string data_options_read_expected = + "--bdd-max-size 134217728 " "--benchmarks \"@null\" " "--debug \"@null\" " "--dump \"@stdout\" " "--error \"@stderr\" " - "--inference " "--info \"@null\" " "--optimize " "--output \"@stdout\" " "--repl-output \"@stdout\" " "--run false " - "--stringtables " "--transformed \"\" " "--udp-addr \"127.0.0.1\" " - "--udp-port 6283 " - "--zerovarcomp "; + "--udp-port 6283"; + +size_t data_rules_expected_length = 34; +char data_rules_expected[] = +"\x0c\x00\x00\x00" "\x03" "\x01" "\x00\x00\x00\x00\x00\x00\x00\x00" +"\x01\x00\x00\x00" "\xff\xff\xff\xff" "\x00\x00\x00\x00" +"\x00\x00\x00\x00\x00\x00\x00\x00" +; size_t data_dict_expected_length = 193; char data_dict_expected[] = "\x29\x00\x00\x00\x00\x00\x00\x00" @@ -85,117 +87,64 @@ char data_dict_expected[] = "\x29\x00\x00\x00\x00\x00\x00\x00" "\x29\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00"; -size_t data_bdd_expected_length = 68; -char data_bdd_expected[] = - "\x05\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00" "\x00\x00\x00\x00" - "\x00\x00\x00\x00" "\x01\x00\x00\x00" - "\x01\x00\x00\x00" "\x00\x00\x00\x00" - "\xFF\xFF\xFF\xFF" "\x01\x00\x00\x00" - "\x02\x00\x00\x00" "\xFE\xFF\xFF\xFF" - "\x01\x00\x00\x00" "\xFF\xFF\xFF\xFF" - "\x02\x00\x00\x00" "\x01\x00\x00\x00" - "\xFF\xFF\xFF\xFF"; +size_t data_bdd_expected_length = 104; +char data_bdd_expected[] = +"\x08\x00\x00\x00\x00\x00\x00\x00" +"\x00\x00\x00\x00""\x00\x00\x00\x00""\x00\x00\x00\x00" +"\x01\x00\x00\x00""\x01\x00\x00\x00""\x00\x00\x00\x00" +"\xff\xff\xff\xff""\x01\x00\x00\x00""\x04\x00\x00\x00" +"\xfe\xff\xff\xff""\x01\x00\x00\x00""\xfd\xff\xff\xff" +"\x03\x00\x00\x00""\x01\x00\x00\x00""\xfe\xff\xff\xff" +"\x04\x00\x00\x00""\x01\x00\x00\x00""\xff\xff\xff\xff" +"\x03\x00\x00\x00""\x01\x00\x00\x00""\x02\x00\x00\x00" +"\x06\x00\x00\x00""\x01\x00\x00\x00""\xff\xff\xff\xff"; std::vector data_bdd_read_expected = { { 0, 0, 0 }, { 0, 1, 1 }, - { 2, -1, 1 }, - { -1, -2, 1 }, - { -1, 2, 1 } + { 4, -1, 1 }, + { -3, -2, 1 }, + { -2, 3, 1 }, + { -1, 4, 1 }, + { 2, 3, 1 }, + { -1, 6, 1 } }; -size_t data_tables_expected_length = 967; -char data_tables_expected[] = // dict -"\x04\x00\x00\x00" "\x00\x00\x00\x00" "\x61\x62\x78\x79" // dict string -"\x02\x00\x00\x00" "\x00\x00\x00\x00" // nrels -"\x02\x00\x00\x00" "\x00\x00\x00\x00" // nsyms -"\x00\x00\x00\x00" "\x00\x00\x00\x00" // nbuiltins -// dict lexeme ranges -"\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x01\x00\x00\x00" "\x00\x00\x00\x00" -"\x01\x00\x00\x00" "\x00\x00\x00\x00" "\x02\x00\x00\x00" "\x00\x00\x00\x00" -"\x02\x00\x00\x00" "\x00\x00\x00\x00" "\x03\x00\x00\x00" "\x00\x00\x00\x00" -"\x03\x00\x00\x00" "\x00\x00\x00\x00" "\x04\x00\x00\x00" "\x00\x00\x00\x00" -// dict types -"\x00\x00\x00\x00\x00\x00\x00\x00" +size_t data_tables_expected_length = 317; +char data_tables_expected[] = // rules "\x01\x00\x00\x00\x00\x00\x00\x00" -"\x01\x00\x00\x00" "\x00" "\x00" -"\x01\x00\x00\x00\x00\x00\x00\x00" -"\x01\x00\x00\00" "\xfc\xff\xff\xff" "\xfc\xff\xff\xff" "\x00\x00\x00\x00" +"\x01\x00\x00\x00" // r.t + "\x00" // r.t.extype + "\x00" // bools{ r.t.neg, r.t.goal } +"\x01\x00\x00\x00\x00\x00\x00\x00" // r.t.size() +"\x04\x00\x00\x00" // r.t[0] +"\xfa\xff\xff\xff" "\xfa\xff\xff\xff" "\x00\x00\x00\x00" "\x01\x00\x00\x00\x00\x00\x00\x00" "\x01\x00\x00\x00" "\x00\x00\x00\x00" -// 0xa2 pos in file +// 48 "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x02\x00\x00\x00\x00\x00\x00\x00" // nstep "\x00\x00\x00\x00\x00\x00\x00\x00" // tmprels -"\x00\x00\x00\x00\x00\x00\x00\x00" // deps -"\x00\x00\x00\x00\x00\x00\x00\x00" // mhits -"\x01\x00\x00\x00\x00\x00\x00\x00" // altids -"\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" // -"- -"\x00\x00\x00\x00\x00\x00\x00\x00" // pBin +"\x02\x00\x00\x00\x00\x00\x00\x00" // deps + "\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x01\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x01\x00\x00\x00\x00\x00\x00\x00" // max_args "\x00\x00\x00\x00\x00\x00\x00\x00" // rcm "\x00\x00\x00\x00\x00\x00\x00\x00" // goals "\x00\x00\x00\x00\x00\x00\x00\x00" // to_drop -"\x01\x00\x00\x00\x00\x00\x00\x00" // exts -"\x00\x00\x00\x00" // -"- -// 0x116 "\x00\x00\x00\x00\x00\x00\x00\x00" // strs "\x00\x00\x00\x00\x00\x00\x00\x00" // str_rels "\x00\x00\x00\x00\x00\x00\x00\x00" // prog_after_fp -// 0x12d - 0x1ce infer -"\x00\x00\x00\x00\x00\x00\x00\x00" // minvtyps -"\x00\x00\x00\x00\x00\x00\x00\x00" // mtyps -"\x02\x00\x00\x00\x00\x00\x00\x00" // altids4types - "\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x01\x00\x00\x00" "\x01\x00\x00\x00\x00\x00\x00\x00" -"\x01\x00\x00\x00\x00\x00\x00\x00" // tblbodies - "\x00\x00\x00\x00" "\x01\x00\x00\x00\x00\x00\x00\x00" - "\x01\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00" -"\x01\x00\x00\x00\x00\x00\x00\x00" // tblrules - "\x01\x00\x00\x00" "\x01\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x01\x00\x00\x00\x00\x00\x00\x00" // altordermap - "\x01\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00" - "\x01\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00" -// end of infer_types -"\x08" // tbls bools at 0x1c6 +"\x00" // tbls bools "\x02\x00\x00\x00\x00\x00\x00\x00" // tbls size // tbl 1 "\x00\x00\x00\x00" // rel "\x01\x00\x00\x00\x00\x00\x00\x00" "\x01\x00\x00\x00" // arity -// tbl 1 bitsmeta -"\x01\x00\x00\x00\x00\x00\x00\x00" // n types - "\x00\x00\x00\x00\x00\x00\x00\x00" // sizes (sig) - "\x00\x00\x00\x00\x00\x00\x00\x00" // mprimes - "\x00" // kind = 0 = Primitive - "\x03" // primitive type - "\x02\x00\x00\x00\x00\x00\x00\x00" // bitness - "\x00\x00\x00\x00" // num -"\x01\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00" // vargs -"\x01\x00\x00\x00\x00\x00\x00\x00" "\x02\x00\x00\x00" // vbits -"\x02\x00\x00\x00\x00\x00\x00\x00" // nterms -"\x02\x00\x00\x00\x00\x00\x00\x00" // args_bits -"\x02\x00\x00\x00\x00\x00\x00\x00" // maxbits -"\x01\x00\x00\x00\x00\x00\x00\x00" // mleftbits - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x02\x00\x00\x00\x00\x00\x00\x00" // mleftargs - "\x00\x00\x00\x00\x00\x00\x00\x00" // first - "\x01\x00\x00\x00\x00\x00\x00\x00" // second is map = size - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x01\x00\x00\x00\x00\x00\x00\x00" - "\x01\x00\x00\x00\x00\x00\x00\x00" // first - "\x01\x00\x00\x00\x00\x00\x00\x00" // second is map = size - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x05" // bm bools 0x299 -"\xfe\xff\xff\xff" // tq +"\xfe\xff\xff\xff" // t "\x01\x00\x00\x00\x00\x00\x00\x00" //len "\x00\x00\x00\x00\x00\x00\x00\x00" // priority "\x00\x00\x00\x00\x00\x00\x00\x00" // r @@ -203,38 +152,11 @@ char data_tables_expected[] = // dict "\xff\xff\xff\xff" // idbltin "\x00\x00\x00\x00\x00\x00\x00\x00" // bltinargs "\x00\x00\x00\x00\x00\x00\x00\x00" // btlinsize -// 0x2cb // tbl 1 "\x01\x00\x00\x00" // rel "\x01\x00\x00\x00\x00\x00\x00\x00" "\x01\x00\x00\x00" // arity -// tbl 1 bitsmeta -"\x01\x00\x00\x00\x00\x00\x00\x00" // n types - "\x00\x00\x00\x00\x00\x00\x00\x00" // sizes (sig) - "\x00\x00\x00\x00\x00\x00\x00\x00" // mprimes - "\x00" // kind = 0 = Primitive - "\x03" // primitive type - "\x02\x00\x00\x00\x00\x00\x00\x00" // bitness - "\x00\x00\x00\x00" // num -"\x01\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00" // vargs -"\x01\x00\x00\x00\x00\x00\x00\x00" "\x02\x00\x00\x00" // vbits -"\x01\x00\x00\x00\x00\x00\x00\x00" // nterms -"\x02\x00\x00\x00\x00\x00\x00\x00" // args_bits -"\x02\x00\x00\x00\x00\x00\x00\x00" // maxbits -"\x01\x00\x00\x00\x00\x00\x00\x00" // mleftbits - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x02\x00\x00\x00\x00\x00\x00\x00" // mleftargs - "\x00\x00\x00\x00\x00\x00\x00\x00" // first - "\x01\x00\x00\x00\x00\x00\x00\x00" // second is map = size - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x01\x00\x00\x00\x00\x00\x00\x00" - "\x01\x00\x00\x00\x00\x00\x00\x00" // first - "\x01\x00\x00\x00\x00\x00\x00\x00" // second is map = size - "\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x05" // bm bools 0x299 -"\xfc\xff\xff\xff" // tq +"\xfa\xff\xff\xff" // t "\x01\x00\x00\x00\x00\x00\x00\x00" //len "\x00\x00\x00\x00\x00\x00\x00\x00" // priority "\x01\x00\x00\x00\x00\x00\x00\x00" // r @@ -245,205 +167,169 @@ char data_tables_expected[] = // dict "\x00\x00\x00\x00\x00\x00\x00\x00" // btlinsize ; -size_t data_driver_expected_length = 2720; +size_t data_driver_expected_length = 2618; char data_driver_expected[] = -"\xbd\xdd\x00\x00\x00\x00\x00\x00" "\x00\x00\x06\x00\x00\x00\x00\x00" -"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x01\x00" -"\x00\x00\x01\x00\x00\x00\x00\x00" "\x00\x00\xff\xff\xff\xff\x01\x00" -"\x00\x00\x02\x00\x00\x00\xfe\xff" "\xff\xff\x01\x00\x00\x00\xff\xff" -"\xff\xff\x02\x00\x00\x00\x01\x00" "\x00\x00\xff\xff\xff\xff\xfe\xff" -"\xff\xff\x01\x00\x00\x00\x01\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" +"\xbd\xdd\x00\x00\x00\x00\x00\x00" "\x00\x00\x01\x00\x00\x00\x00\x00" +"\x00\x00\xff\xff\xff\xff\x00\x21" "\x00\x00\x00\x00\x00\x00\x00\x61" +"\x28\x78\x29\x2e\x20\x62\x28\x79" "\x29\x20\x3a\x2d\x20\x61\x28\x78" +"\x29\x2e\x20\x63\x28\x7a\x29\x20" "\x3a\x2d\x20\x62\x28\x79\x29\x2e" +"\x00\x03\x00\x00\x00\x00\x00\x00" "\x00\x03\x00\x00\x00\x00\x00\x00" +"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x13\x00\x00\x00\x00\x00\x00" +"\x00\x11\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" +"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x5e\x00\x00\x00\x00\x00\x00" +"\x00\x28\x29\x72\x6e\x64\x66\x61" "\x69\x6c\x68\x61\x6c\x74\x61\x6c" +"\x6e\x75\x6d\x61\x6c\x70\x68\x61" "\x62\x77\x5f\x6f\x72\x63\x6f\x75" +"\x6e\x74\x64\x69\x67\x69\x74\x70" "\x72\x69\x6e\x74\x73\x70\x61\x63" +"\x65\x62\x77\x5f\x61\x6e\x64\x62" "\x77\x5f\x6e\x6f\x74\x62\x77\x5f" +"\x78\x6f\x72\x6c\x70\x72\x69\x6e" "\x74\x70\x77\x5f\x61\x64\x64\x70" +"\x77\x5f\x6d\x75\x6c\x74\x70\x72" "\x69\x6e\x74\x61\x62\x6c\x65\x1f" +"\x00\x00\x00\x00\x00\x00\x00\x20" "\x00\x00\x00\x00\x00\x00\x00\x25" +"\x00\x00\x00\x00\x00\x00\x00\x26" "\x00\x00\x00\x00\x00\x00\x00\x33" +"\x00\x00\x00\x00\x00\x00\x00\x34" "\x00\x00\x00\x00\x00\x00\x00\x21" +"\x00\x00\x00\x00\x00\x00\x00\x22" "\x00\x00\x00\x00\x00\x00\x00\x27" +"\x00\x00\x00\x00\x00\x00\x00\x28" "\x00\x00\x00\x00\x00\x00\x00\x35" +"\x00\x00\x00\x00\x00\x00\x00\x36" "\x00\x00\x00\x00\x00\x00\x00\x60" +"\x01\x00\x00\x00\x00\x00\x00\x61" "\x01\x00\x00\x00\x00\x00\x00\x61" +"\x01\x00\x00\x00\x00\x00\x00\x62" "\x01\x00\x00\x00\x00\x00\x00\x62" +"\x01\x00\x00\x00\x00\x00\x00\x65" "\x01\x00\x00\x00\x00\x00\x00\x65" +"\x01\x00\x00\x00\x00\x00\x00\x69" "\x01\x00\x00\x00\x00\x00\x00\x69" +"\x01\x00\x00\x00\x00\x00\x00\x6d" "\x01\x00\x00\x00\x00\x00\x00\x6d" +"\x01\x00\x00\x00\x00\x00\x00\x72" "\x01\x00\x00\x00\x00\x00\x00\x72" +"\x01\x00\x00\x00\x00\x00\x00\x77" "\x01\x00\x00\x00\x00\x00\x00\x77" +"\x01\x00\x00\x00\x00\x00\x00\x7c" "\x01\x00\x00\x00\x00\x00\x00\x7c" +"\x01\x00\x00\x00\x00\x00\x00\x81" "\x01\x00\x00\x00\x00\x00\x00\x81" +"\x01\x00\x00\x00\x00\x00\x00\x86" "\x01\x00\x00\x00\x00\x00\x00\x86" +"\x01\x00\x00\x00\x00\x00\x00\x8b" "\x01\x00\x00\x00\x00\x00\x00\x8b" +"\x01\x00\x00\x00\x00\x00\x00\x90" "\x01\x00\x00\x00\x00\x00\x00\x90" +"\x01\x00\x00\x00\x00\x00\x00\x96" "\x01\x00\x00\x00\x00\x00\x00\x96" +"\x01\x00\x00\x00\x00\x00\x00\x9c" "\x01\x00\x00\x00\x00\x00\x00\x9c" +"\x01\x00\x00\x00\x00\x00\x00\xa2" "\x01\x00\x00\x00\x00\x00\x00\xa2" +"\x01\x00\x00\x00\x00\x00\x00\xa8" "\x01\x00\x00\x00\x00\x00\x00\xa8" +"\x01\x00\x00\x00\x00\x00\x00\xae" "\x01\x00\x00\x00\x00\x00\x00\xae" +"\x01\x00\x00\x00\x00\x00\x00\xb5" "\x01\x00\x00\x00\x00\x00\x00\xb5" +"\x01\x00\x00\x00\x00\x00\x00\xbe" "\x01\x00\x00\x00\x00\x00\x00\x62" +"\x01\x00\x00\x00\x00\x00\x00\x65" "\x01\x00\x00\x00\x00\x00\x00\x65" +"\x01\x00\x00\x00\x00\x00\x00\x69" "\x01\x00\x00\x00\x00\x00\x00\x69" +"\x01\x00\x00\x00\x00\x00\x00\x6d" "\x01\x00\x00\x00\x00\x00\x00\x6d" +"\x01\x00\x00\x00\x00\x00\x00\x72" "\x01\x00\x00\x00\x00\x00\x00\x72" +"\x01\x00\x00\x00\x00\x00\x00\x77" "\x01\x00\x00\x00\x00\x00\x00\x77" +"\x01\x00\x00\x00\x00\x00\x00\x7c" "\x01\x00\x00\x00\x00\x00\x00\x7c" +"\x01\x00\x00\x00\x00\x00\x00\x81" "\x01\x00\x00\x00\x00\x00\x00\x81" +"\x01\x00\x00\x00\x00\x00\x00\x86" "\x01\x00\x00\x00\x00\x00\x00\x86" +"\x01\x00\x00\x00\x00\x00\x00\x8b" "\x01\x00\x00\x00\x00\x00\x00\x8b" +"\x01\x00\x00\x00\x00\x00\x00\x90" "\x01\x00\x00\x00\x00\x00\x00\x90" +"\x01\x00\x00\x00\x00\x00\x00\x96" "\x01\x00\x00\x00\x00\x00\x00\x96" +"\x01\x00\x00\x00\x00\x00\x00\x9c" "\x01\x00\x00\x00\x00\x00\x00\x9c" +"\x01\x00\x00\x00\x00\x00\x00\xa2" "\x01\x00\x00\x00\x00\x00\x00\xa2" +"\x01\x00\x00\x00\x00\x00\x00\xa8" "\x01\x00\x00\x00\x00\x00\x00\xa8" +"\x01\x00\x00\x00\x00\x00\x00\xae" "\x01\x00\x00\x00\x00\x00\x00\xae" +"\x01\x00\x00\x00\x00\x00\x00\xb5" "\x01\x00\x00\x00\x00\x00\x00\xb5" +"\x01\x00\x00\x00\x00\x00\x00\xbe" "\x01\x00\x00\x00\x00\x00\x00\x09" +"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" +"\x00\x00\x00\x01\x00\x00\x00\x01" "\x00\x00\x00\x00\x00\x00\x00\xff" +"\xff\xff\xff\x01\x00\x00\x00\x04" "\x00\x00\x00\xfe\xff\xff\xff\x01" +"\x00\x00\x00\xfd\xff\xff\xff\x03" "\x00\x00\x00\x01\x00\x00\x00\xfe" +"\xff\xff\xff\x04\x00\x00\x00\x01" "\x00\x00\x00\xff\xff\xff\xff\x03" +"\x00\x00\x00\x01\x00\x00\x00\x02" "\x00\x00\x00\x06\x00\x00\x00\x01" +"\x00\x00\x00\xff\xff\xff\xff\x04" "\x00\x00\x00\x01\x00\x00\x00\x01" +"\x00\x00\x00\x0d\x00\x00\x00\x00" "\x00\x00\x00\x01\x0c\x00\x00\x00" +"\x00\x00\x00\x00\x62\x64\x64\x2d" "\x6d\x61\x78\x2d\x73\x69\x7a\x65" +"\x00\x00\x00\x00\x08\x03\x0a\x00" "\x00\x00\x00\x00\x00\x00\x62\x65" +"\x6e\x63\x68\x6d\x61\x72\x6b\x73" "\x00\x05\x00\x00\x00\x00\x00\x00" +"\x00\x40\x6e\x75\x6c\x6c\x00\x03" "\x05\x00\x00\x00\x00\x00\x00\x00" +"\x64\x65\x62\x75\x67\x00\x12\x00" "\x00\x00\x00\x00\x00\x00\x61\x72" +"\x63\x68\x69\x76\x65\x2e\x74\x65" "\x73\x74\x2e\x64\x65\x62\x75\x67" +"\x00\x03\x04\x00\x00\x00\x00\x00" "\x00\x00\x64\x75\x6d\x70\x00\x07" +"\x00\x00\x00\x00\x00\x00\x00\x40" "\x73\x74\x64\x6f\x75\x74\x00\x03" +"\x05\x00\x00\x00\x00\x00\x00\x00" "\x65\x72\x72\x6f\x72\x00\x07\x00" +"\x00\x00\x00\x00\x00\x00\x40\x73" "\x74\x64\x65\x72\x72\x00\x03\x04" +"\x00\x00\x00\x00\x00\x00\x00\x69" "\x6e\x66\x6f\x00\x05\x00\x00\x00" +"\x00\x00\x00\x00\x40\x6e\x75\x6c" "\x6c\x00\x03\x0a\x00\x00\x00\x00" +"\x00\x00\x00\x69\x6e\x70\x75\x74" "\x2d\x65\x76\x61\x6c\x00\x21\x00" +"\x00\x00\x00\x00\x00\x00\x61\x28" "\x78\x29\x2e\x20\x62\x28\x79\x29" +"\x20\x3a\x2d\x20\x61\x28\x78\x29" "\x2e\x20\x63\x28\x7a\x29\x20\x3a" +"\x2d\x20\x62\x28\x79\x29\x2e\x00" "\x02\x08\x00\x00\x00\x00\x00\x00" +"\x00\x6f\x70\x74\x69\x6d\x69\x7a" "\x65\x00\x01\x03\x06\x00\x00\x00" +"\x00\x00\x00\x00\x6f\x75\x74\x70" "\x75\x74\x00\x07\x00\x00\x00\x00" +"\x00\x00\x00\x40\x73\x74\x64\x6f" "\x75\x74\x00\x03\x0b\x00\x00\x00" +"\x00\x00\x00\x00\x72\x65\x70\x6c" "\x2d\x6f\x75\x74\x70\x75\x74\x00" +"\x07\x00\x00\x00\x00\x00\x00\x00" "\x40\x73\x74\x64\x6f\x75\x74\x00" +"\x02\x03\x00\x00\x00\x00\x00\x00" "\x00\x72\x75\x6e\x00\x01\x03\x08" +"\x00\x00\x00\x00\x00\x00\x00\x75" "\x64\x70\x2d\x61\x64\x64\x72\x00" +"\x09\x00\x00\x00\x00\x00\x00\x00" "\x31\x32\x37\x2e\x30\x2e\x30\x2e" +"\x31\x00\x01\x08\x00\x00\x00\x00" "\x00\x00\x00\x75\x64\x70\x2d\x70" +"\x6f\x72\x74\x00\x8b\x18\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x01\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" +"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x01\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x00\x00\x00\x00\x11" "\x00\x00\x00\x00\x00\x00\x00\x03" -"\x00\x00\x00\x00\x00\x00\x00\x61" "\x64\x64\x03\x00\x00\x00\x00\x00" -"\x00\x00\x72\x6e\x64\x04\x00\x00" "\x00\x00\x00\x00\x00\x63\x61\x73" -"\x74\x04\x00\x00\x00\x00\x00\x00" "\x00\x66\x61\x69\x6c\x04\x00\x00" -"\x00\x00\x00\x00\x00\x68\x61\x6c" "\x74\x04\x00\x00\x00\x00\x00\x00" -"\x00\x6c\x69\x73\x74\x05\x00\x00" "\x00\x00\x00\x00\x00\x62\x77\x5f" -"\x6f\x72\x05\x00\x00\x00\x00\x00" "\x00\x00\x63\x6f\x75\x6e\x74\x05" -"\x00\x00\x00\x00\x00\x00\x00\x70" "\x72\x69\x6e\x74\x06\x00\x00\x00" -"\x00\x00\x00\x00\x62\x77\x5f\x61" "\x6e\x64\x06\x00\x00\x00\x00\x00" -"\x00\x00\x62\x77\x5f\x6e\x6f\x74" "\x06\x00\x00\x00\x00\x00\x00\x00" -"\x62\x77\x5f\x78\x6f\x72\x06\x00" "\x00\x00\x00\x00\x00\x00\x6c\x70" -"\x72\x69\x6e\x74\x06\x00\x00\x00" "\x00\x00\x00\x00\x70\x77\x5f\x61" -"\x64\x64\x07\x00\x00\x00\x00\x00" "\x00\x00\x69\x74\x65\x72\x61\x74" -"\x65\x07\x00\x00\x00\x00\x00\x00" "\x00\x70\x77\x5f\x6d\x75\x6c\x74" -"\x09\x00\x00\x00\x00\x00\x00\x00" "\x64\x65\x63\x6f\x6d\x70\x6f\x73" -"\x65\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x01\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x03\x00\x00\x00\x00\x00\x00" -"\x00\x00\x01\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x04\x00\x00\x00" -"\x00\x00\x00\x00\x01\x05\x01\x06" "\x01\x00\x00\x00\x00\x00\x00\x00" -"\x01\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x01\x00\x00" -"\x00\x00\x00\x00\x00\x00\x00\x04" "\x00\x00\x00\x00\x00\x00\x00\x01" -"\x05\x01\x06\x01\x00\x00\x00\x00" "\x00\x00\x00\x01\x00\x00\x00\x01" -"\x00\x00\x00\x00\x00\x00\x00\x01" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x04\x00\x00\x00\x00\x00\x00" "\x00\x01\x05\x01\x06\x01\x00\x00" -"\x00\x00\x00\x00\x00\x01\x00\x00" "\x00\x00\x01\x00\x00\x00\x00\x00" -"\x00\x00\x00\x00\x04\x00\x00\x00" "\x00\x00\x00\x00\x01\x05\x01\x06" +"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x01\x00" +"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" +"\x00\x00\x00\x00\x00\x00\x03\x00" "\x00\x00\x00\x00\x00\x00\x00\x01" +"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x04\x00\x00\x00\x00\x00\x00" +"\x00\x01\x1f\x00\x00\x00\x00\x00" "\x00\x00\x20\x00\x00\x00\x00\x00" +"\x00\x00\x05\x01\x21\x00\x00\x00" "\x00\x00\x00\x00\x22\x00\x00\x00" +"\x00\x00\x00\x00\x06\x01\x00\x00" "\x00\x00\x00\x00\x00\x01\x00\x00" +"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x01\x00\x00\x00\x00\x00" +"\x00\x00\x00\x00\x04\x00\x00\x00" "\x00\x00\x00\x00\x01\x25\x00\x00" +"\x00\x00\x00\x00\x00\x26\x00\x00" "\x00\x00\x00\x00\x00\x05\x01\x27" +"\x00\x00\x00\x00\x00\x00\x00\x28" "\x00\x00\x00\x00\x00\x00\x00\x06" "\x01\x00\x00\x00\x00\x00\x00\x00" "\x01\x00\x00\x00\x01\x00\x00\x00" "\x00\x00\x00\x00\x01\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x04\x00" -"\x00\x00\x00\x00\x00\x00\x01\x05" "\x01\x06\x01\x00\x00\x00\x00\x00" -"\x00\x00\x01\x00\x00\x00\x11\x00" "\x00\x00\x00\x00\x00\x00\x03\x00" -"\x00\x00\x00\x00\x00\x00\x61\x64" "\x64\x03\x00\x00\x00\x00\x00\x00" -"\x00\x72\x6e\x64\x04\x00\x00\x00" "\x00\x00\x00\x00\x63\x61\x73\x74" -"\x04\x00\x00\x00\x00\x00\x00\x00" "\x66\x61\x69\x6c\x04\x00\x00\x00" -"\x00\x00\x00\x00\x68\x61\x6c\x74" "\x04\x00\x00\x00\x00\x00\x00\x00" -"\x6c\x69\x73\x74\x05\x00\x00\x00" "\x00\x00\x00\x00\x62\x77\x5f\x6f" -"\x72\x05\x00\x00\x00\x00\x00\x00" "\x00\x63\x6f\x75\x6e\x74\x05\x00" -"\x00\x00\x00\x00\x00\x00\x70\x72" "\x69\x6e\x74\x06\x00\x00\x00\x00" -"\x00\x00\x00\x62\x77\x5f\x61\x6e" "\x64\x06\x00\x00\x00\x00\x00\x00" -"\x00\x62\x77\x5f\x6e\x6f\x74\x06" "\x00\x00\x00\x00\x00\x00\x00\x62" -"\x77\x5f\x78\x6f\x72\x06\x00\x00" "\x00\x00\x00\x00\x00\x6c\x70\x72" -"\x69\x6e\x74\x06\x00\x00\x00\x00" "\x00\x00\x00\x70\x77\x5f\x61\x64" -"\x64\x07\x00\x00\x00\x00\x00\x00" "\x00\x69\x74\x65\x72\x61\x74\x65" -"\x07\x00\x00\x00\x00\x00\x00\x00" "\x70\x77\x5f\x6d\x75\x6c\x74\x09" -"\x00\x00\x00\x00\x00\x00\x00\x64" "\x65\x63\x6f\x6d\x70\x6f\x73\x65" -"\x0f\x00\x00\x00\x00\x00\x00\x00" "\x01\x0c\x00\x00\x00\x00\x00\x00" -"\x00\x62\x64\x64\x2d\x6d\x61\x78" "\x2d\x73\x69\x7a\x65\x00\x00\x00" -"\x08\x03\x0a\x00\x00\x00\x00\x00" "\x00\x00\x62\x65\x6e\x63\x68\x6d" -"\x61\x72\x6b\x73\x05\x00\x00\x00" "\x00\x00\x00\x00\x40\x6e\x75\x6c" -"\x6c\x03\x05\x00\x00\x00\x00\x00" "\x00\x00\x64\x65\x62\x75\x67\x12" -"\x00\x00\x00\x00\x00\x00\x00\x61" "\x72\x63\x68\x69\x76\x65\x2e\x74" -"\x65\x73\x74\x2e\x64\x65\x62\x75" "\x67\x03\x04\x00\x00\x00\x00\x00" -"\x00\x00\x64\x75\x6d\x70\x07\x00" "\x00\x00\x00\x00\x00\x00\x40\x73" -"\x74\x64\x6f\x75\x74\x03\x05\x00" "\x00\x00\x00\x00\x00\x00\x65\x72" -"\x72\x6f\x72\x07\x00\x00\x00\x00" "\x00\x00\x00\x40\x73\x74\x64\x65" -"\x72\x72\x02\x09\x00\x00\x00\x00" "\x00\x00\x00\x69\x6e\x66\x65\x72" -"\x65\x6e\x63\x65\x01\x03\x04\x00" "\x00\x00\x00\x00\x00\x00\x69\x6e" -"\x66\x6f\x05\x00\x00\x00\x00\x00" "\x00\x00\x40\x6e\x75\x6c\x6c\x02" -"\x08\x00\x00\x00\x00\x00\x00\x00" "\x6f\x70\x74\x69\x6d\x69\x7a\x65" -"\x01\x03\x06\x00\x00\x00\x00\x00" "\x00\x00\x6f\x75\x74\x70\x75\x74" -"\x07\x00\x00\x00\x00\x00\x00\x00" "\x40\x73\x74\x64\x6f\x75\x74\x03" -"\x0b\x00\x00\x00\x00\x00\x00\x00" "\x72\x65\x70\x6c\x2d\x6f\x75\x74" -"\x70\x75\x74\x07\x00\x00\x00\x00" "\x00\x00\x00\x40\x73\x74\x64\x6f" -"\x75\x74\x02\x03\x00\x00\x00\x00" "\x00\x00\x00\x72\x75\x6e\x01\x02" -"\x0c\x00\x00\x00\x00\x00\x00\x00" "\x73\x74\x72\x69\x6e\x67\x74\x61" -"\x62\x6c\x65\x73\x01\x03\x08\x00" "\x00\x00\x00\x00\x00\x00\x75\x64" -"\x70\x2d\x61\x64\x64\x72\x09\x00" "\x00\x00\x00\x00\x00\x00\x31\x32" -"\x37\x2e\x30\x2e\x30\x2e\x31\x01" "\x08\x00\x00\x00\x00\x00\x00\x00" -"\x75\x64\x70\x2d\x70\x6f\x72\x74" "\x8b\x18\x00\x00\x02\x0b\x00\x00" -"\x00\x00\x00\x00\x00\x7a\x65\x72" "\x6f\x76\x61\x72\x63\x6f\x6d\x70" -"\x01\x00\x00\x00\x00\x00\x00\x00" "\x00\x03\x06\x00\x00\x00\x00\x00" -"\x00\x00\x61\x62\x63\x78\x79\x7a" "\x03\x00\x00\x00\x00\x00\x00\x00" -"\x03\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" +"\x00\x00\x00\x00\x00\x00\x01\x1f" "\x00\x00\x00\x00\x00\x00\x00\x20" +"\x00\x00\x00\x00\x00\x00\x00\x05" "\x01\x21\x00\x00\x00\x00\x00\x00" +"\x00\x22\x00\x00\x00\x00\x00\x00" "\x00\x06\x01\x00\x00\x00\x00\x00" +"\x00\x00\x01\x00\x00\x00\x00\x01" "\x00\x00\x00\x00\x00\x00\x00\x00" +"\x00\x04\x00\x00\x00\x00\x00\x00" "\x00\x01\x33\x00\x00\x00\x00\x00" +"\x00\x00\x34\x00\x00\x00\x00\x00" "\x00\x00\x05\x01\x35\x00\x00\x00" +"\x00\x00\x00\x00\x36\x00\x00\x00" "\x00\x00\x00\x00\x06\x01\x00\x00" +"\x00\x00\x00\x00\x00\x01\x00\x00" "\x00\x01\x00\x00\x00\x00\x00\x00" +"\x00\x01\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x04\x00\x00\x00\x00" +"\x00\x00\x00\x01\x25\x00\x00\x00" "\x00\x00\x00\x00\x26\x00\x00\x00" +"\x00\x00\x00\x00\x05\x01\x27\x00" "\x00\x00\x00\x00\x00\x00\x28\x00" +"\x00\x00\x00\x00\x00\x00\x06\x01" "\x00\x00\x00\x00\x00\x00\x00\x01" +"\x00\x00\x00\x11\x00\x00\x00\x00" "\x00\x00\x00\x83\x00\x00\x00\x00" +"\x00\x00\x00\x86\x00\x00\x00\x00" "\x00\x00\x00\x86\x00\x00\x00\x00" +"\x00\x00\x00\x8a\x00\x00\x00\x00" "\x00\x00\x00\x8a\x00\x00\x00\x00" +"\x00\x00\x00\x8e\x00\x00\x00\x00" "\x00\x00\x00\x8e\x00\x00\x00\x00" +"\x00\x00\x00\x93\x00\x00\x00\x00" "\x00\x00\x00\x93\x00\x00\x00\x00" +"\x00\x00\x00\x98\x00\x00\x00\x00" "\x00\x00\x00\x98\x00\x00\x00\x00" +"\x00\x00\x00\x9d\x00\x00\x00\x00" "\x00\x00\x00\x9d\x00\x00\x00\x00" +"\x00\x00\x00\xa2\x00\x00\x00\x00" "\x00\x00\x00\xa2\x00\x00\x00\x00" +"\x00\x00\x00\xa7\x00\x00\x00\x00" "\x00\x00\x00\xa7\x00\x00\x00\x00" +"\x00\x00\x00\xac\x00\x00\x00\x00" "\x00\x00\x00\xac\x00\x00\x00\x00" +"\x00\x00\x00\xb1\x00\x00\x00\x00" "\x00\x00\x00\xb1\x00\x00\x00\x00" +"\x00\x00\x00\xb7\x00\x00\x00\x00" "\x00\x00\x00\xb7\x00\x00\x00\x00" +"\x00\x00\x00\xbd\x00\x00\x00\x00" "\x00\x00\x00\xbd\x00\x00\x00\x00" +"\x00\x00\x00\xc3\x00\x00\x00\x00" "\x00\x00\x00\xc3\x00\x00\x00\x00" +"\x00\x00\x00\xc9\x00\x00\x00\x00" "\x00\x00\x00\xc9\x00\x00\x00\x00" +"\x00\x00\x00\xcf\x00\x00\x00\x00" "\x00\x00\x00\xcf\x00\x00\x00\x00" +"\x00\x00\x00\xd6\x00\x00\x00\x00" "\x00\x00\x00\xd6\x00\x00\x00\x00" +"\x00\x00\x00\xdf\x00\x00\x00\x00" "\x00\x00\x00\x03\x02\x00\x00\x00" +"\x00\x00\x00\x00\x01\x00\x00\x00" "\x00\x00\x01\x00\x00\x00\x00\x00" +"\x00\x00\x04\x00\x00\x00\xf9\xff" "\xff\xff\xf9\xff\xff\xff\x00\x00" +"\x00\x00\x01\x00\x00\x00\x00\x00" "\x00\x00\x01\x00\x00\x00\x02\x00" +"\x00\x00\x00\x00\x01\x00\x00\x00" "\x00\x00\x00\x00\x08\x00\x00\x00" +"\xf8\xff\xff\xff\xff\xff\xff\xff" "\x00\x00\x00\x00\x01\x00\x00\x00" +"\x00\x00\x00\x00\xff\xff\xff\xff" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x01\x00\x00\x00\x00\x00\x00\x00" -"\x01\x00\x00\x00\x00\x00\x00\x00" "\x02\x00\x00\x00\x00\x00\x00\x00" -"\x02\x00\x00\x00\x00\x00\x00\x00" "\x03\x00\x00\x00\x00\x00\x00\x00" -"\x03\x00\x00\x00\x00\x00\x00\x00" "\x04\x00\x00\x00\x00\x00\x00\x00" -"\x04\x00\x00\x00\x00\x00\x00\x00" "\x05\x00\x00\x00\x00\x00\x00\x00" -"\x05\x00\x00\x00\x00\x00\x00\x00" "\x06\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x00\x00\x00\x00\x00" "\x02\x00\x00\x00\x00\x00\x00\x00" -"\x01\x00\x00\x00\x00\x00\x01\x00" "\x00\x00\x00\x00\x00\x00\x01\x00" -"\x00\x00\xfc\xff\xff\xff\xfc\xff" "\xff\xff\x00\x00\x00\x00\x01\x00" -"\x00\x00\x00\x00\x00\x00\x01\x00" "\x00\x00\x02\x00\x00\x00\x00\x00" -"\x01\x00\x00\x00\x00\x00\x00\x00" "\x02\x00\x00\x00\xfb\xff\xff\xff" -"\xff\xff\xff\xff\x00\x00\x00\x00" "\x01\x00\x00\x00\x00\x00\x00\x00" -"\xff\xff\xff\xff\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x00\x01\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x00\x02\x00\x00\x00" "\x00\x00\x00\x00\x01\x00\x00\x00" -"\x01\x00\x00\x00\x00\x00\x00\x00" "\x02\x00\x00\x00\x01\x00\x00\x00" -"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x01\x00\x00\x00" -"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" +"\x00\x00\x00\x00\x00\x00\x00\x00" "\x03\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x01\x00\x00\x00" -"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x03\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x00\x01\x00\x00\x00" "\x01\x00\x00\x00\x00\x00\x00\x00" -"\x02\x00\x00\x00\x01\x00\x00\x00" "\x00\x00\x00\x00\x02\x00\x00\x00" -"\x00\x00\x00\x00\x00\x00\x00\x00" "\x01\x00\x00\x00\x00\x00\x00\x00" -"\x01\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x01\x00\x00\x00\x01\x00\x00\x00" "\x00\x00\x00\x00\x02\x00\x00\x00" -"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x02\x00\x00\x00" -"\x00\x00\x00\x00\x01\x00\x00\x00" "\x01\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x00\x00\x00\x00\x00" "\x02\x00\x00\x00\x01\x00\x00\x00" -"\x00\x00\x00\x00\x01\x00\x00\x00" "\x00\x00\x00\x00\x02\x00\x00\x00" -"\x00\x00\x00\x00\x01\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" +"\x00\x00\x00\x00\x00\x00\x00\x00" "\x02\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x01\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x00\x02\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x00\x02\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x00\x08\x03\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x01\x00\x00\x00\x00\x00\x00" "\x00\x01\x00\x00\x00\x01\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x00\x00\x00\x03\x02" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x01\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x01" -"\x00\x00\x00\x00\x00\x00\x00\x02" "\x00\x00\x00\x02\x00\x00\x00\x00" -"\x00\x00\x00\x02\x00\x00\x00\x00" "\x00\x00\x00\x02\x00\x00\x00\x00" -"\x00\x00\x00\x01\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x02\x00\x00\x00\x00" -"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x01\x00\x00\x00\x00" -"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x01\x00\x00\x00\x00" -"\x00\x00\x00\x01\x00\x00\x00\x00" "\x00\x00\x00\x01\x00\x00\x00\x00" -"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x05\xfd\xff\xff\xff" "\x01\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x01\xff\xff\xff\xff\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x00\x00\x01\x00\x00" "\x00\x01\x00\x00\x00\x00\x00\x00" -"\x00\x01\x00\x00\x00\x01\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x03\x02" -"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x01\x00\x00\x00\x00" -"\x00\x00\x00\x00\x00\x00\x00\x01" "\x00\x00\x00\x00\x00\x00\x00\x02" -"\x00\x00\x00\x02\x00\x00\x00\x00" "\x00\x00\x00\x02\x00\x00\x00\x00" -"\x00\x00\x00\x02\x00\x00\x00\x00" "\x00\x00\x00\x01\x00\x00\x00\x00" +"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x03\x00\x00" +"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x01\x00\x00\x00\x00\x00\x00" +"\x00\x01\x00\x00\x00\xfb\xff\xff" "\xff\x01\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x02\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x01\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" +"\x00\x01\xff\xff\xff\xff\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" +"\x00\x00\x00\x00\x00\x00\x01\x00" "\x00\x00\x01\x00\x00\x00\x00\x00" +"\x00\x00\x01\x00\x00\x00\xf9\xff" "\xff\xff\x01\x00\x00\x00\x00\x00" +"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x01\x00\x00\x00\x00\x00" +"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\xff\xff\xff\xff\x00" +"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x02" +"\x00\x00\x00\x01\x00\x00\x00\x00" "\x00\x00\x00\x01\x00\x00\x00\xff" +"\xff\xff\xff\x01\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x01\x00\x00\x00\x00" "\x00\x00\x00\x01\x00\x00\x00\x00" -"\x00\x00\x00\x01\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x05\xfc\xff\xff\xff" -"\x01\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x01\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\xff\xff\xff\xff\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x00\x00\x02\x00\x00" "\x00\x01\x00\x00\x00\x00\x00\x00" -"\x00\x01\x00\x00\x00\x01\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x03\x02" -"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x01\x00\x00\x00\x00" -"\x00\x00\x00\x00\x00\x00\x00\x01" "\x00\x00\x00\x00\x00\x00\x00\x02" -"\x00\x00\x00\x01\x00\x00\x00\x00" "\x00\x00\x00\x02\x00\x00\x00\x00" -"\x00\x00\x00\x02\x00\x00\x00\x00" "\x00\x00\x00\x01\x00\x00\x00\x00" -"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x02\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x01\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x01\x00\x00\x00\x00" "\x00\x00\x00\x01\x00\x00\x00\x00" -"\x00\x00\x00\x01\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x05\xff\xff\xff\xff" -"\x01\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x01\x00\x00\x00\x00\x00\x00\x00" "\x01\x00\x00\x00\x00\x00\x00\x00" -"\x00\xff\xff\xff\xff\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x00\x00\x00\x00\x00\x21\x00\x00" "\x00\x00\x00\x00\x00\x61\x28\x78" -"\x29\x2e\x20\x62\x28\x79\x29\x20" "\x3a\x2d\x20\x61\x28\x78\x29\x2e" -"\x20\x63\x28\x7a\x29\x20\x3a\x2d" "\x20\x62\x28\x79\x29\x2e\x62\x83"; - -size_t data_rules_expected_length = 34; -char data_rules_expected[] = -"\x0c\x00\x00\x00" "\x03" "\x01" "\x00\x00\x00\x00\x00\x00\x00\x00" -"\x01\x00\x00\x00" "\xff\xff\xff\xff" "\x00\x00\x00\x00" -"\x00\x00\x00\x00\x00\x00\x00\x00" -; - -size_t data_compound_expected_length = 98; -char data_compound_expected[] = -"\x01" // bools = root -"\x00" // alignment: type - "\x00\x00\x00\x00\x00\x00\x00\x00" // bitness - "\x00\x00\x00\x00" // num -"\x00\x00\x00\x00\x00\x00\x00\x00" // sumOfBits -"\x00\x00\x00\x00\x00\x00\x00\x00" // sumOfPrimitives -"\x02\x00\x00\x00\x00\x00\x00\x00" // nsize of types -"\x00\x00\x00\x00\x00\x00\x00\x00" // sig -"\x00\x00\x00\x00\x00\x00\x00\x00" // mprimes -"\x00" // kind::Primitive -"\x01" // base_type::INT - "\x04\x00\x00\x00\x00\x00\x00\x00" // bitness - "\x20\x00\x00\x00" // num -"\x00\x00\x00\x00\x00\x00\x00\x00" // sig -"\x00\x00\x00\x00\x00\x00\x00\x00" // mprimes -"\x00" // kind::Primitive -"\x03" // kind::STR - "\x02\x00\x00\x00\x00\x00\x00\x00" // bitness - "\x03\x00\x00\x00" // num -; +"\x00\x00\x00\x00\xff\xff\xff\xff" "\x00\x00\x00\x00\x00\x00\x00\x00" +"\x00\x00\x00\x00\x00\x00\x00\x00" "\x62\x83"; diff --git a/tests/archive.test.sh b/tests/archive.test.sh index 99abcb99..cc0ddd7e 100755 --- a/tests/archive.test.sh +++ b/tests/archive.test.sh @@ -1,4 +1,6 @@ -rm -f ./test_file* +#!/bin/bash + +#rm -f ./test_file* ret=1 g++ archive.test.cpp \ ../build-Debug/libTML.a \ @@ -8,6 +10,6 @@ g++ archive.test.cpp \ && ./archive.test ret=$? -#hexdump -Cv ./test_file1.bin +#hexdump -Cv ./test_file1.bin > ./test_file1.bin.hexdump rm -f ./archive.test ./test_file* ./archive.test.debug exit $ret diff --git a/tests/bdd.test.cpp b/tests/bdd.test.cpp index 3e28df70..a0b99a56 100644 --- a/tests/bdd.test.cpp +++ b/tests/bdd.test.cpp @@ -88,7 +88,7 @@ struct tt { // truth table tt r = *this; for (size_t n = 0; n < bits; ++n) if (b[n]) r = r.ex(n); if (r.bdd() != bdd_ex(bdd(), b)) { -/* wcout << "existential quantification of" < sb; for (auto& x : s) sb.emplace(x); if (sb != table) { - wcout << "expected"<data()) != prog1) + || (string(i->begin()) != prog1)) + return fail("wrong input1 data"); + + i = ii.next(); + if (ii.current() != i) return fail("input2 current error"); + if (i == 0) return fail("input2 next == 0"); + if ((string(i->data()) != prog2) + || (string(i->begin()) != prog2)) + return fail("wrong input2 data"); + + i = ii.next(); + if (ii.current() != i) return fail("input3 current error"); + if (i == 0) return fail("input3 == 0"); + //COUT << "prog3: '" << prog3 << "'\n i->begin(): '" + // << i->begin() << "'\n"; + if ((string(i->data()) != prog3) + || (string(i->begin()) != prog3)) + return fail("wrong input3 data"); + + return ok(); +}; + +int main() { + setlocale(LC_ALL, ""); + vector tests = { + string_input, + file_input, + multiple_inputs, + }; + return run(tests, "input"); +} diff --git a/tests/input.test.file b/tests/input.test.file new file mode 100644 index 00000000..774e6c3f --- /dev/null +++ b/tests/input.test.file @@ -0,0 +1,3 @@ +a. +b. +c :- a, b. diff --git a/tests/input.test.sh b/tests/input.test.sh new file mode 100755 index 00000000..de56a513 --- /dev/null +++ b/tests/input.test.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +rm -f ./input.test +ret=0 + +g++ input.test.cpp \ + ../build-Debug/libTML.a \ + -W -Wall -Wextra -Wpedantic \ + -DGIT_DESCRIBED=1 -DGIT_COMMIT_HASH=1 -DGIT_BRANCH=1 \ + -DWITH_THREADS=TRUE \ + -std=c++17 -O0 -DDEBUG -ggdb3 -oinput.test -lgcov \ + && ./input.test + +ret=$? +rm -f ./input.test +exit $ret diff --git a/tests/memory_map.test.cpp b/tests/memory_map.test.cpp index 4f57835d..29681f43 100644 --- a/tests/memory_map.test.cpp +++ b/tests/memory_map.test.cpp @@ -48,11 +48,11 @@ test open_and_read_written = [] { if (mm.error) return fail(mm.error_message); char* data = (char*) mm.data(); if (mm.error) return fail(mm.error_message); - wstringstream ss; + ostringstream ss; for (size_t i = 0; i != S2; ++i) { if (data[i] != (char)(255 - (i % 255))) - return ss << L"open_and_read_written pos: " << i - << L" '" << (int)data[i] << "'", fail(ss.str()); + return ss << "open_and_read_written pos: " << i + << " '" << (int)data[i] << "'", fail(ss.str()); } return ok(); }; @@ -73,11 +73,11 @@ test open_and_read_written_again = [] { if (mm.error) return fail(mm.error_message); char* data = (char*) mm.data(); if (mm.error) return fail(mm.error_message); - wstringstream ss; + ostringstream ss; for (size_t i = 0; i != S3; ++i) { if (data[i] != (char)(i % 255)) - return ss << L"open_and_read_written_again pos: " << i - << L" '" << (int)data[i] << "'", fail(ss.str()); + return ss << "open_and_read_written_again pos: " << i + << " '" << (int)data[i] << "'", fail(ss.str()); } return ok(); }; @@ -90,20 +90,20 @@ test vector_with_memory_map_allocator_int_t_write = [] { for (int_t i = 0; i != 1000; ++i) v[i] = i-500; for (int_t i = 0; i != 1000; ++i) if (i-500 != v[i]) { f = true; break; } - //o::out() << L"done" << std::endl; - if (f) return fail(L"vector_with_memory_map_allocator_int_t_write"); + //o::out() << "done" << std::endl; + if (f) return fail("vector_with_memory_map_allocator_int_t_write"); return ok(); }; test vector_with_memory_map_allocator_int_t_read = [] { - //o::out() << L"read" << std::endl; + //o::out() << "read" << std::endl; memory_map_allocator a(TF1, MMAP_READ); vector > v(a); v.reserve(1000); bool f = false; for (int_t i = 0; i != 1000; ++i) if (i-500 != v[i]) { f = true; break; } - if (f) return fail(L"vector_with_memory_map_allocator_int_t_read"); + if (f) return fail("vector_with_memory_map_allocator_int_t_read"); return ok(); }; @@ -115,7 +115,7 @@ test mmap_vector_with_nommap_allocator_int_t_write = [] { for (int_t i = 0; i != 1000; ++i) v[i] = i-500; for (int_t i = 0; i != 1000; ++i) if (i-500 != v[i]) { f = true; break; } - if (f) return fail(L"vector_with_memory_map_allocator_int_t_write"); + if (f) return fail("vector_with_memory_map_allocator_int_t_write"); return ok(); }; @@ -145,8 +145,8 @@ test bdd_mmap_write = [] { int main() { setlocale(LC_ALL, ""); outputs oo; - oo.target(L"debug", L"@stdout"); - oo.target(L"output", L"@stdout"); + oo.target("debug", "@stdout"); + oo.target("output", "@stdout"); vector tests = { create_new_and_open, open_and_write, @@ -159,5 +159,5 @@ int main() { temporary, bdd_mmap_write, }; - return run(tests, L"memory_map"); + return run(tests, "memory_map"); } diff --git a/tests/memory_map.test.sh b/tests/memory_map.test.sh index a1f4b55b..53bcf4bf 100755 --- a/tests/memory_map.test.sh +++ b/tests/memory_map.test.sh @@ -1,3 +1,5 @@ +#!/bin/bash + rm -f ./test_file*.mmap ret=1 g++ memory_map.test.cpp \ diff --git a/tests/output.test.cpp b/tests/output.test.cpp index f361b9d0..b2a47166 100644 --- a/tests/output.test.cpp +++ b/tests/output.test.cpp @@ -17,106 +17,106 @@ using namespace std; test output_create = [] { // STDOUT - output o1(L"def"); - if (o1.name() != L"def" || o1.target() != L"@stdout" || o1.is_null()) - return fail(L"create default = @stdout"); - output o2(L"std", L"@stdout"); - if (o2.name() != L"std" || o2.target() != L"@stdout" || o2.is_null()) - return fail(L"create @stdout"); + output o1("def"); + if (o1.name() != "def" || o1.target() != "@stdout" || o1.is_null()) + return fail("create default = @stdout"); + output o2("std", "@stdout"); + if (o2.name() != "std" || o2.target() != "@stdout" || o2.is_null()) + return fail("create @stdout"); // STDERR - output oe(L"err", L"@stderr"); - if (oe.name() != L"err" || oe.target() != L"@stderr" || oe.is_null()) - return fail(L"create @stderr"); + output oe("err", "@stderr"); + if (oe.name() != "err" || oe.target() != "@stderr" || oe.is_null()) + return fail("create @stderr"); // NULL - output on(L"null", L"@null"); - if (on.name() != L"null" || on.target() != L"@null" || !on.is_null()) - return fail(L"create @null"); + output on("null", "@null"); + if (on.name() != "null" || on.target() != "@null" || !on.is_null()) + return fail("create @null"); // BUFFER - output ob(L"buf", L"@buffer"); - if (ob.name() != L"buf" || ob.target() != L"@buffer" || ob.is_null()) - return fail(L"create @buffer"); + output ob("buf", "@buffer"); + if (ob.name() != "buf" || ob.target() != "@buffer" || ob.is_null()) + return fail("create @buffer"); // FILE - output of(L"file", L"output.test.file"); - if (of.name() != L"file" || of.target() != L"output.test.file" || - of.is_null()) return fail(L"create file"); + output of("file", "output.test.file"); + if (of.name() != "file" || of.target() != "output.test.file" || + of.is_null()) return fail("create file"); return ok(); }; test output_null = [] { - output on(L"null", L"@null"); on << L"discarded"; - if (on.name() != L"null" || on.target() != L"@null" || !on.is_null()) - return fail(L"write @null"); + output on("null", "@null"); on << "discarded"; + if (on.name() != "null" || on.target() != "@null" || !on.is_null()) + return fail("write @null"); return ok(); }; test output_std = [] { - output os(L"std", L"@stdout"); os << L"stdout test"; - output oe(L"err", L"@stderr"); oe << L"stderr test"; + output os("std", "@stdout"); os << "stdout test"; + output oe("err", "@stderr"); oe << "stderr test"; return ok(); }; test output_buffer= [] { - output ob(L"b", L"@buffer"); ob << L"buffer test"; - if (ob.read() != L"buffer test") - return fail(L"write @buffer"); + output ob("b", "@buffer"); ob << "buffer test"; + if (ws2s(ob.read()) != "buffer test") + return fail("write @buffer"); return ok(); }; test output_file = [] { - { output of(L"f", L"output.test.file2"); of << L"file test"; } + { output of("f", "output.test.file2"); of << "file test"; } if (file_and_mem_cmp("output.test.file2", "file test", 9)) - return fail(L"write file"); + return fail("write file"); return ok(); }; test output_name = [] { - outputs oo; oo.use(); oo.target(L"error", L"@buffer"); - oo.create(L"noname", L".noname",L"@name"); - if (oo.read(L"error") != - L"output 'noname' targeting @name without setting name\n") - fail(L"creating @name output without setting --name " - L"does not raise an err"); - outputs::name(L"named"); - oo.create(L"name1", L".name1", L"@name"); - oo.create(L"name2", L".name2", L"@name"); - outputs::to(L"name1") << L"named1 test" << endl; - outputs::to(L"name2") << L"named2 test" << endl; + outputs oo; oo.use(); oo.target("error", "@buffer"); + oo.create("noname", ".noname","@name"); + if (ws2s(oo.read("error")) != + "output 'noname' targeting @name without setting name\n") + fail("creating @name output without setting --name " + "does not raise an err"); + outputs::name("named"); + oo.create("name1", ".name1", "@name"); + oo.create("name2", ".name2", "@name"); + outputs::to("name1") << "named1 test" << endl; + outputs::to("name2") << "named2 test" << endl; if (file_and_mem_cmp("named.name1", "named1 test", 11) || file_and_mem_cmp("named.name2", "named2 test", 11)) - return fail(L"write name"); + return fail("write name"); return ok(); }; test outputs_create = [] { outputs oo; oo.use(); - oo.add(output::create(L"stdout", L"@stdout")); - if (!oo.exists(L"stdout")) fail(L"outputs: created does not exist"); + oo.add(output::create("stdout", "@stdout")); + if (!oo.exists("stdout")) fail("outputs: created does not exist"); return ok(); }; test outputs_multiple = [] { outputs oo1; oo1.use(); - oo1.add(output::create(L"output_name", L"@buffer")); - output* o = outputs::get(L"output_name"); - outputs::to(L"output_name") << L"test1"; - *o << L"test2"; - if (o->read() != L"test1test2") - return fail (L"outputs: oo1 from multiple"); + oo1.add(output::create("output_name", "@buffer")); + output* o = outputs::get("output_name"); + outputs::to("output_name") << "test1"; + *o << "test2"; + if (ws2s(o->read()) != "test1test2") + return fail ("outputs: oo1 from multiple"); outputs oo2; oo2.use(); - oo2.add(output::create(L"output_name", L"@buffer")); - outputs::to(L"output_name") << L"test3"; - o = outputs::get(L"output_name"); - *o << L"test4"; - if (o->read() != L"test3test4") - return fail (L"outputs: oo2 from multiple"); + oo2.add(output::create("output_name", "@buffer")); + outputs::to("output_name") << "test3"; + o = outputs::get("output_name"); + *o << "test4"; + if (ws2s(o->read()) != "test3test4") + return fail ("outputs: oo2 from multiple"); oo1.use(); - outputs::to(L"output_name") << L"test5"; - o = outputs::get(L"output_name"); - *o << L"test6"; - if (o->read() != L"test1test2test5test6") - return fail (L"outputs: oo1 after oo2 from multiple"); + outputs::to("output_name") << "test5"; + o = outputs::get("output_name"); + *o << "test6"; + if (ws2s(o->read()) != "test1test2test5test6") + return fail ("outputs: oo1 after oo2 from multiple"); return ok(); }; @@ -133,6 +133,6 @@ int main() { outputs_create, outputs_multiple }; - wofstream info("output.test.info"); - return run(tests, L"output", &info); + ofstream_t info("output.test.info"); + return run(tests, "output", &info); } diff --git a/tests/parse_error.test.cpp b/tests/parse_error.test.cpp index fbc8a39a..206770f1 100644 --- a/tests/parse_error.test.cpp +++ b/tests/parse_error.test.cpp @@ -24,43 +24,48 @@ using namespace std; // err - expected parse error // line, chr - expected error position // to - expected "close to" -test pe(wstring prog, wstring err, long line, long chr, wstring to) { - std::wstringstream ws; ws << L"Parse error: \"" << err - << L"\" at " << line << L':' << chr; - if (to != L"") ws << " close to \"" << to << "\""; - std::wstring expected = ws.str(); +test pe(std::string prog, std::string err, long line, long chr, std::string to) { + std::stringstream ss; ss << "Parse error: \"" << err + << "\" at " << line << ':' << chr; + if (to != "") ss << " close to \"" << to << "\""; + std::string expected = ss.str(); auto got_output = [] () { - wchar_t t[256]; - wistringstream is(::outputs::get(L"error")->read()); + char_t t[256]; + istringstream_t is(::outputs::get("error")->read()); is.getline(t, 256); - return wstring(t); + return ws2s(t); }; return [expected, &got_output, prog] () -> int { - wstring got, prg(prog); + string got, prg(prog); outputs *oldoo = outputs::in_use(); outputs oo; oo.use(); oo.init_defaults(); - driver d(prog, ::options({ "--error", "@buffer", - "--no-output", "--no-debug", "--no-info" }, &oo)); - wchar_t t[256]; - wistringstream is(oo.get(L"error")->read()); + inputs ii; + try { + driver d(prog, ::options(strings{ "--error", "@buffer", + "--no-output", "--no-debug", "--no-info" }, &ii, &oo)); + } catch (std::exception& e) { + return fail(e.what()); + } + char_t t[256]; + istringstream_t is(oo.get("error")->read()); is.getline(t, 256); - got = wstring(t); + got = ws2s(t); oldoo->use(); if (got.length() > 0) { if (got.compare(expected)) { size_t p = 0; - while ((p=prg.find(L"\n",p)) != wstring::npos) { - prg.replace(p, 1, L"\\n"); + while ((p=prg.find("\n", p)) != string::npos) { + prg.replace(p, 1, "\\n"); p += 2; } - wostringstream os; - os << L"parse error fail (#" << n << ")\n" - << L"\tprog: '" << prog << L"'\n" - << L"\tgot: '" << got << L"'\n" - << L"\texp: '" << expected << L"'\n"; + ostringstream os; + os << "parse error fail (#" << n << ")\n" + << "\tprog: '" << prog << "'\n" + << "\tgot: '" << got << "'\n" + << "\texp: '" << expected << "'\n"; return fail(os.str()); - } // else wcout << L"ok " << n << L"\n"; - } else return fail(L"no error", n); + } //else COUT << "ok " << n << "\n"; + } else return fail("no error", n); return ok(); }; } @@ -69,46 +74,46 @@ int main() { setlocale(LC_ALL, ""); outputs oo; vector tests = { - pe(L"a\n. /* aaa", err_comment, 2, 3, L""), - pe(L"\"", unmatched_quotes, 1, 1, L"\""), - pe(L"\"\\'\"", err_escape, 1, 3, L"'\""), - pe(L"<", err_eof, 1, 2, L"<"), - pe(L"'\\0'", err_escape, 1, 3, L"0'"), + pe("a\n. /* aaa", err_comment, 2, 3, ""), + pe("\"", unmatched_quotes, 1, 1, "\""), + pe("\"\\'\"", err_escape, 1, 3, "'\""), + pe("<", err_eof, 1, 2, "<"), + pe("'\\0'", err_escape, 1, 3, "0'"), // 5 - pe(L"\n'c.", err_quote, 2, 3, L"."), - pe(L"a", err_eof, 1, 2, L"a"), - pe(L"\na\n(.", err_paren, 3, 1, L"."), - pe(L"@trace 1", err_trace_rel, 1, 8, L"1"), - pe(L"@trace r a", dot_expected, 1, 10, L"a"), + pe("\n'c.", err_quote, 2, 3, "."), + pe("a", err_eof, 1, 2, "a"), + pe("\na\n(.", err_paren, 3, 1, "."), + pe("@trace 1", err_trace_rel, 1, 8, "1"), + pe("@trace r a", dot_expected, 1, 10, "a"), // 10 - pe(L"@bwd a", dot_expected, 1, 6, L"a"), - pe(L"@stdout.", err_stdout, 1, 8, L"."), - pe(L"@stdout str1(),", dot_expected, 1, 15, L","), - pe(L"@dummy.", err_directive, 1, 2, L"dummy"), - pe(L"@string 5", err_rel_expected, 1, 9, L"5"), + pe("@bwd a", dot_expected, 1, 6, "a"), + pe("@stdout.", err_stdout, 1, 8, "."), + pe("@stdout str1(),", dot_expected, 1, 15, ","), + pe("@dummy.", err_directive, 1, 2, "dummy."), + pe("@string 5", err_rel_expected, 1, 9, "5"), // 15 - pe(L"@string s 6", dot_expected, 1, 12, L"<"), - pe(L"@string s ;", err_directive_arg, 1, 11, L";"), - pe(L"@string s stdin ", dot_expected, 1, 16, L"stdin"), - pe(L"a", err_eof, 1, 2, L"a"), - pe(L"1.", err_relsym_expected, 1, 1, L"1"), + pe("@string s 6", dot_expected, 1, 12, " 6"), + pe("@string s ;", err_directive_arg, 1, 11, ";"), + pe("@string s stdin ", dot_expected, 1, 16, "stdin "), + pe("a", err_eof, 1, 2, "a"), + pe("1.", err_relsym_expected, 1, 1, "1."), // 20 - pe(L"a 3 f.", err_paren_expected, 1, 6, L"."), - pe(L"a(.", err_paren, 1, 2, L"."), - pe(L"a((((()(()())))).", err_paren, 1, 1, L"a"), - pe(L"a;", err_head, 1, 2, L";"), - pe(L"a:-.", err_body, 1, 4, L"."), + pe("a 3 f.", err_paren_expected, 1, 6, "."), + pe("a(.", err_paren, 1, 2, "."), + pe("a((((()(()())))).", err_paren, 1, 1, "a((((()(()()))))."), + pe("a;", err_head, 1, 2, ";"), + pe("a:-.", err_body, 1, 4, "."), // 25 - pe(L"b;", err_head, 1, 2, L";"), - pe(L"a => e1 e2", err_prod, 1, 6, L"e1"), - pe(L":-a.", err_rule_dir_prod_expected, 1, 1, L":-"), - pe(L"{ a(). ", err_close_curly, 1, 7, L"."), - pe(L":a", err_chr, 1, 2, L"a"), + pe("b;", err_head, 1, 2, ";"), + pe("a => e1 e2", err_prod, 1, 6, "e1 e2"), + pe(":-a.", err_rule_dir_prod_expected, 1, 1, ":-a."), + pe("{ a(). ", err_close_curly, 1, 7, ". "), + pe(":a", err_chr, 1, 2, "a"), // 30 - pe(L"1a", err_int, 1, 1, L"1a"), - pe(L"?(", err_chr, 1, 2, L"("), - pe(L"{{", err_parse, 1, 2, L"{" ) - // TODO: pe(L"", err_term_or_dot, 1, 1, L""), + pe("1a", err_int, 1, 1, "1a"), + pe("?(", err_chr, 1, 2, "("), + pe("{{", err_parse, 1, 2, "{" ) + // TODO: pe("", err_term_or_dot, 1, 1, ""), }; - return run(tests, L"parse errors"); + return run(tests, "parse errors"); } diff --git a/tests/parse_error.test.sh b/tests/parse_error.test.sh index 63fbf45d..9dec2e66 100755 --- a/tests/parse_error.test.sh +++ b/tests/parse_error.test.sh @@ -1,3 +1,5 @@ +#!/bin/bash + rm -f ./parse_error.test ret=1 g++ parse_error.test.cpp \ diff --git a/tests/query.test.cpp b/tests/query.test.cpp index ef212fc4..f2407e88 100644 --- a/tests/query.test.cpp +++ b/tests/query.test.cpp @@ -16,8 +16,8 @@ using namespace std; /* size_t query_ref(size_t x, term t, size_t bits, vector& perm) { size_t y = fact(t, bits), ar = t.size()-1, r; - wcout << "x:"< m; @@ -31,11 +31,11 @@ size_t query_ref(size_t x, term t, size_t bits, vector& perm) { else perm.push_back(n); r = bdd_and(x, y); - wcout << "and:" << endl << from_bits(r, bits, ar); + COUT << "and:" << endl << from_bits(r, bits, ar); r = bdd_ex(r, ex); - wcout << "ex:" << endl << from_bits(r, bits, ar); + COUT << "ex:" << endl << from_bits(r, bits, ar); r = bdd_permute(r, perm); - wcout << "perm:"< l1({arg1},bits,args,leq_const(n,bits,args)); builtins l2({arg2},bits,args,leq_const(n,bits,args)); spnode x = T, y = bdd_and(l1(T),l2(T)); from_range(n, bits, arg1, args, x); from_range(n, bits, arg2, args, x); - wcout<<"x:"<; size_t f = 0; // fails size_t n = 0; // current test no. -std::wostream* tout; +ostream_t* tout; -int fail(std::wstring msg, int r=1) { - return *tout<& tests, std::wstring name, std::wostream* os=&std::wcout){ - try { +int run(const std::vector& tests, std::string name, ostream_t* os=&COUT){ + //try { tout = os; for (auto t : tests) ++n, f += t(); - *tout << name << L": " << n-f << L'/' << n << L" ok.\n"; - if (f) *tout << f << L'/' << n << " failed.\n"; - //*tout << std::flush; - } catch (std::exception& e) { *tout < 0 ? 1 : 0; } @@ -46,16 +46,16 @@ int file_read(const char* path, char* data, size_t size) { #ifdef _WIN32 HANDLE fd = ::CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); - if (fd == INVALID_HANDLE_VALUE) return fail(L"file cannot be opened", -1); + if (fd == INVALID_HANDLE_VALUE) return fail("file cannot be opened", -1); DWORD r; - if (::ReadFile(fd, data, size, &r, 0) == FALSE) return fail(L"file cannot be read", -3); - if (r != (DWORD)size) return fail(L"read failed", -2); + if (::ReadFile(fd, data, size, &r, 0) == FALSE) return fail("file cannot be read", -3); + if (r != (DWORD)size) return fail("read failed", -2); ::CloseHandle(fd); #else int fd = ::open(path, O_RDONLY | O_NONBLOCK); - if (fd == -1) return fail(L"file cannot be opened", -1); + if (fd == -1) return fail("file cannot be opened", -1); int r = ::read(fd, data, size); - if (r != (int)size) return fail(L"read failed", -2); + if (r != (int)size) return fail("read failed", -2); ::close(fd); #endif return ok(); @@ -65,15 +65,15 @@ int file_read(const char* path, char* data, size_t size) { int file_and_mem_cmp(const char* path, const char* expected, size_t size) { char* data = (char*) malloc(size); if (file_read(path, data, size) == -1) return -1; - auto flags = std::wcout.flags(); + auto flags = COUT.flags(); for (size_t pos = 0; pos != size; ++pos) { if (data[pos] != expected[pos]) { - std::wcout << L"differs at pos: " << pos << L" 0x" - << std::hex << std::setw(2) < ?y."; - lexemes r = prog_lex(s); - CHECK(r.size() == 27); + ccs emptyString = " "; + input in1(emptyString); + CHECK(in1.l.size() == 0); + ccs stringWithComment = " /* "; + DOCTEST_CHECK_THROWS(input in2(stringWithComment)); + ccs s = "setB(?x ?y ?z) :- e(?x), e(?y), ?x + ?y = ?z. ?x > ?y."; + input in3(s); + CHECK(in3.l.size() == 27); } }