diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 52eacf620..16b9f47f4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -83,7 +83,7 @@ jobs: if: ${{ always() }} run: | nix log .#hobbesPackages/gcc-${{ matrix.gcc }}/llvm-${{ matrix.llvm }}/hobbes &> ${{ matrix.os }}-gcc-${{ matrix.gcc }}-llvm-${{ matrix.llvm }}-hobbes.log - - name: upload log ${{ matrix.os }}-gcc-${{ matrix.gcc }}-llvm-${{ matrix.gitllvm }}-hobbes.log + - name: upload log ${{ matrix.os }}-gcc-${{ matrix.gcc }}-llvm-${{ matrix.llvm }}-hobbes.log if: ${{ always() }} uses: actions/upload-artifact@v3 with: diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 000000000..ca1887ebf --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,76 @@ +# This file is a template, and might need editing before it works on your project. +# To contribute improvements to CI/CD templates, please follow the Development guide at: +# https://docs.gitlab.com/ee/development/cicd/templates.html +# This specific template is located at: +# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Getting-Started.gitlab-ci.yml + +# This is a sample GitLab CI/CD configuration file that should run without any modifications. +# It demonstrates a basic 3 stage CI/CD pipeline. Instead of real tests or scripts, +# it uses echo commands to simulate the pipeline execution. +# +# A pipeline is composed of independent jobs that run scripts, grouped into stages. +# Stages run in sequential order, but jobs within stages run in parallel. +# +# For more information, see: https://docs.gitlab.com/ee/ci/yaml/README.html#stages +image: nixpkgs/nix-flakes:latest +stages: # List of stages for jobs, and their order of execution + - build + - test + - deploy + +build-job-gcc10-llvm11: # This job runs in the build stage, which runs first. + stage: build + script: + - echo "Compiling the code..." + - nix build .#hobbesPackages/gcc-10/llvm-11/hobbes + - echo "Compile complete." + after_script: + - echo "nix log .#hobbesPackages/gcc-10/llvm-11/hobbes..." + - mkdir -pv log-job-gcc10-llvm11 + - nix log .#hobbesPackages/gcc-10/llvm-11/hobbes > log-job-gcc10-llvm11/nix.log + - echo "nix log .#hobbesPackages/gcc-10/llvm-11/hobbes complete." + artifacts: + name: "$CI_COMMIT_REF_SLUG" + paths: + - log-job-gcc10-llvm11/ + expire_in: 1 week + when: always + +build-job-clang11: # This job runs in the build stage, which runs first. + stage: build + script: + - mkdir -pv log-clang-11 + - echo "Compiling the code..." + - nix build .#hobbesPackages/clang-11/hobbes; nix log .#hobbesPackages/clang-11/hobbes > log-job-clang-11/nix.log + - echo "Compile complete." + after_script: + - echo "nix log .#hobbesPackages/clang-11/hobbes..." + - mkdir -pv log-job-clang-11 + - nix log .#hobbesPackages/clang-11/hobbes > log-job-clang-11/nix.log + - echo "nix log .#hobbesPackages/clang-11/hobbes complete." + artifacts: + name: "$CI_COMMIT_REF_SLUG" + paths: + - log-job-clang-11/ + expire_in: 1 week + when: always + +unit-test-job-gcc: # This job runs in the test stage. + stage: test # It only starts when the job in the build stage completes successfully. + script: + - echo "Running unit tests... This will take about 60 seconds." + - sleep 60 + - echo "Code coverage is 90%" + +lint-test-job: # This job also runs in the test stage. + stage: test # It can run at the same time as unit-test-job (in parallel). + script: + - echo "Linting code... This will take about 10 seconds." + - sleep 10 + - echo "No lint issues found." + +deploy-job: # This job runs in the deploy stage. + stage: deploy # It only runs when *both* jobs in the test stage complete successfully. + script: + - echo "Deploying application..." + - echo "Application successfully deployed." diff --git a/CMakeLists.txt b/CMakeLists.txt index bf24e5e55..2ccc6e7c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,22 +14,21 @@ find_package(Curses REQUIRED) include_directories(${CURSES_INCLUDE_DIRS}) find_package(LLVM REQUIRED CONFIG) -include_directories(${LLVM_INCLUDE_DIRS}) +include_directories(SYSTEM ${LLVM_INCLUDE_DIRS}) add_definitions(${LLVM_DEFINITIONS}) -if (${LLVM_PACKAGE_VERSION} VERSION_LESS "10.0") - set(CMAKE_CXX_STANDARD 11) -else() - set(CMAKE_CXX_STANDARD 14) -endif() +set(CMAKE_CXX_STANDARD 14) if (${LLVM_PACKAGE_VERSION} VERSION_LESS "3.6") set(jit_lib jit) -else() +elseif(${LLVM_PACKAGE_VERSION} VERSION_LESS "11.0") set(jit_lib mcjit) +else() + set(jit_lib mcjit orcjit) endif() -find_program(llvm-config llvm-config PATHS ${LLVM_TOOLS_BINARY_DIR}) +find_program(llvm-config llvm-config PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH) +find_program(llvm-config llvm-config) if (${LLVM_PACKAGE_VERSION} VERSION_LESS "4.0") execute_process(COMMAND ${llvm-config} --libs x86 ipo ${jit_lib} OUTPUT_VARIABLE llvm_libs @@ -82,6 +81,19 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${cxx_flags}") set(CMAKE_CXX_FLAGS_DEBUG "-g") set(CMAKE_CXX_FLAGS_RELEASE "-O2") +option(USE_ASAN_UBSAN "Use address,undefined sanitizers" OFF) +if(USE_ASAN_AND_UBSAN) + # _FORTIFY_SOURCE doesn't play well with asan + # https://github.com/google/sanitizers/issues/247 + add_definitions(-U_FORTIFY_SOURCE) + add_compile_options("-fno-omit-frame-pointer;-fsanitize=address,undefined;-fno-optimize-sibling-calls;-fno-sanitize-recover=all") + add_link_options("-fsanitize=address,undefined;-fno-optimize-sibling-calls;-fno-sanitize-recover=all") + add_compile_options("$<$,$>:-fsanitize=local-bounds,float-divide-by-zero,nullability,signed-integer-overflow,shift,integer-divide-by-zero>") + add_link_options("$<$,$>:-fsanitize=local-bounds,float-divide-by-zero,nullability,signed-integer-overflow,shift,integer-divide-by-zero>") + add_compile_options("$<$:--param=max-vartrack-size=60000000>") + message(STATUS "address and undefined sanitizers enabled") +endif() + add_library(hobbes STATIC ${lib_files}) target_link_libraries(hobbes PUBLIC ${llvm_ldflags} ${llvm_libs} ${ZLIB_LIBRARIES} ${CURSES_LIBRARIES} ${sys_libs}) add_library(hobbes-pic STATIC ${lib_files}) @@ -94,10 +106,11 @@ add_executable(hog ${hog_files}) target_link_libraries(hog PRIVATE hobbes) enable_testing() +add_executable(mock-proc test/mocks/proc.C) add_executable(hobbes-test ${test_files}) target_link_libraries(hobbes-test PRIVATE hobbes) add_test(hobbes-test hobbes-test) -include(FindPythonInterp) +find_package(PythonInterp 2.7 REQUIRED) set_property(TARGET hobbes-test PROPERTY COMPILE_FLAGS "-DPYTHON_EXECUTABLE=\"${PYTHON_EXECUTABLE}\" -DSCRIPT_DIR=\"${CMAKE_SOURCE_DIR}/scripts/\"") install(TARGETS hobbes hobbes-pic DESTINATION "lib") diff --git a/bin/hi/cio.H b/bin/hi/cio.H index 073e356c2..7a6b243ab 100644 --- a/bin/hi/cio.H +++ b/bin/hi/cio.H @@ -7,7 +7,7 @@ namespace hi { // controls display options -typedef unsigned char color; +using color = unsigned char; DEFINE_STRUCT(ConsoleColors, (color, promptfg), @@ -62,13 +62,13 @@ inline void sendCmd(std::ostream& out, int n0, int n1, int n2, char c) { } } -struct setbold { setbold() { } }; +struct setbold {}; inline std::ostream& operator<<(std::ostream& lhs, const setbold&) { sendCmd(lhs, 1, 'm'); return lhs; } -struct setunderline { setunderline() { } }; +struct setunderline {}; inline std::ostream& operator<<(std::ostream& lhs, const setunderline&) { sendCmd(lhs, 4, 'm'); return lhs; @@ -103,18 +103,14 @@ inline std::ostream& operator<<(std::ostream& lhs, const setbgc& c) { return lhs; } -struct resetfmt { - resetfmt() { } -}; +struct resetfmt {}; inline std::ostream& operator<<(std::ostream& lhs, const resetfmt&) { sendCmd(lhs, 0, 'm'); return lhs; } -struct clearscr { - clearscr() { } -}; +struct clearscr {}; inline std::ostream& operator<<(std::ostream& lhs, const clearscr&) { sendCmd(lhs, 2, 'J'); @@ -151,13 +147,13 @@ inline std::ostream& operator<<(std::ostream& lhs, const movecursor& mc) { return lhs; } -struct eraseToEOL { eraseToEOL() { } }; +struct eraseToEOL {}; inline std::ostream& operator<<(std::ostream& lhs, const eraseToEOL&) { sendCmd(lhs, 0, 'K'); return lhs; } -struct clearline { clearline() { } }; +struct clearline {}; inline std::ostream& operator<<(std::ostream& lhs, const clearline&) { sendCmd(lhs, 2, 'K'); return lhs; diff --git a/bin/hi/evaluator.C b/bin/hi/evaluator.C index 308ececee..693c35b7d 100644 --- a/bin/hi/evaluator.C +++ b/bin/hi/evaluator.C @@ -3,20 +3,27 @@ #include "funcdefs.H" #include "cio.H" -#include -#include #include +#include #include +#include #include #include #include #include +#include + +namespace { +void defPrintUnreachableMatches(const hobbes::cc::UnreachableMatches& m) { + std::cout << "warning: " << m.la.filename() << ':' << m.la.lineDesc() << " " << m.lines << std::endl; +} +} // namespace namespace hi { // allocate a string in global memory hobbes::array* allocGlobalStr(const char* x, size_t len) { - hobbes::array* r = reinterpret_cast*>(malloc(sizeof(long) + len * sizeof(char))); + auto* r = reinterpret_cast*>(malloc(sizeof(long) + len * sizeof(char))); memcpy(r->data, x, len * sizeof(char)); r->size = len; return r; @@ -30,12 +37,12 @@ void bindArguments(hobbes::cc& ctx, const Args::NameVals& args) { // type-level binding, for [("foo", "bar"), ...]: // class Argument a b | a -> b // instance Argument "foo" "bar" - TClass* tc = new TClass("Argument", 2, TClass::Members(), list(FunDep(list(0), 1)), LexicalAnnotation::null()); + auto* tc = new TClass("Argument", 2, TClass::Members(), list(FunDep(list(0), 1)), LexicalAnnotation::null()); Definitions drainDefs; for (const auto& arg : args) { tc->insert( ctx.typeEnv(), - TCInstancePtr(new TCInstance("Argument", list(MonoTypePtr(TString::make(arg.first)), MonoTypePtr(TString::make(arg.second))), MemberMapping(), LexicalAnnotation::null())), + std::make_shared("Argument", list(MonoTypePtr(TString::make(arg.first)), MonoTypePtr(TString::make(arg.second))), MemberMapping(), LexicalAnnotation::null()), &drainDefs ); } @@ -45,12 +52,12 @@ void bindArguments(hobbes::cc& ctx, const Args::NameVals& args) { // value-level binding // arguments :: [[char]*[char]] // arguments = [("foo", "bar"), ...] - typedef std::pair*, array*> StrPair; - typedef array StrPairs; + using StrPair = std::pair *, array *>; + using StrPairs = array; - StrPairs* arguments = reinterpret_cast(malloc(sizeof(long) + args.size() * sizeof(StrPair))); + auto* arguments = reinterpret_cast(malloc(sizeof(long) + args.size() * sizeof(StrPair))); arguments->size = 0; - for (auto arg : args) { + for (const auto& arg : args) { arguments->data[arguments->size].first = allocGlobalStr(arg.first); arguments->data[arguments->size].second = allocGlobalStr(arg.second); ++arguments->size; @@ -59,17 +66,23 @@ void bindArguments(hobbes::cc& ctx, const Args::NameVals& args) { } // set up the evaluation environment for our cc -evaluator::evaluator(const Args& args) : silent(args.silent), wwwd(0), opts(args.opts) { +evaluator::evaluator(const Args& args) : silent(args.silent), wwwd(nullptr), opts(args.opts) { using namespace hobbes; bindArguments(this->ctx, args.scriptNameVals); bindHiDefs(this->ctx); + const bool ignoreUM = (std::find(opts.cbegin(), opts.cend(), std::string("IgnoreUnreachableMatches")) != opts.cend()); + this->ctx.ignoreUnreachableMatches(ignoreUM); + if (ignoreUM) { + this->ctx.setGatherUnreachableMatchesFn(defPrintUnreachableMatches); + } + // start alternate input services if necessary if (args.replPort > 0) { installNetREPL(args.replPort, &this->ctx, [this](ExprPtr const& e) -> ExprPtr { return hobbes::translateExprWithOpts(this->opts, e); }); } - + if (args.httpdPort > 0) { // run a local web server (for diagnostics and alternate queries) if requested this->wwwd = new WWWServer(args.httpdPort, &this->ctx); @@ -81,7 +94,7 @@ evaluator::~evaluator() { } bool hiddenFileName(const std::string& fname) { - return fname.size() == 0 || fname[0] == '.'; + return fname.empty() || fname[0] == '.'; } bool loadSilently(const std::string& mfile) { @@ -94,7 +107,7 @@ void evaluator::runMachineREPL() { void evaluator::showClass(const std::string& cname) { hobbes::UnqualifierPtr uq = this->ctx.typeEnv()->lookupUnqualifier(cname); - if (const hobbes::TClass* c = dynamic_cast(uq.get())) { + if (const auto* c = dynamic_cast(uq.get())) { c->show(std::cout); } else { throw std::runtime_error("Undefined type class: " + cname); @@ -103,11 +116,11 @@ void evaluator::showClass(const std::string& cname) { void evaluator::showInstances(const std::string& cname) { hobbes::UnqualifierPtr uq = this->ctx.typeEnv()->lookupUnqualifier(cname); - if (const hobbes::TClass* c = dynamic_cast(uq.get())) { - for (auto i : c->instances()) { + if (const auto* c = dynamic_cast(uq.get())) { + for (const auto& i : c->instances()) { i->show(std::cout); } - for (auto i : c->instanceFns()) { + for (const auto& i : c->instanceFns()) { i->show(std::cout); } } else { @@ -158,7 +171,7 @@ void printConstraint(const hobbes::ConstraintPtr& c) { } void printQualType(const hobbes::Constraints& cs, const hobbes::MonoTypePtr& ty) { - if (cs.size() > 0) { + if (!cs.empty()) { printConstraint(cs[0]); for (size_t i = 1; i < cs.size(); ++i) { std::cout << setfgc(colors.stdtextfg) << ", "; @@ -192,7 +205,7 @@ void evaluator::printTypeEnv() { } hobbes::str::seq evaluator::completionsFor(const std::string& prefix) const { - if (prefix.size() == 0) { + if (prefix.empty()) { return hobbes::str::seq(); } else { hobbes::str::seq vars; @@ -220,13 +233,13 @@ void evaluator::printAssembly(const std::string& expr, void (*f)(void*,size_t)) } void evaluator::perfTestExpr(const std::string& expr) { - typedef void (*pvthunk)(); + using pvthunk = void (*)(); pvthunk f = this->ctx.compileFn(readExpr("let x = (" + expr + ") in ()")); f(); const size_t numRuns = 1000; unsigned long nsCSum = 0; - unsigned long nsCMin = static_cast(-1); + auto nsCMin = static_cast(-1); unsigned long nsCMax = 0; for (size_t i = 0; i < numRuns; ++i) { @@ -253,7 +266,7 @@ void evaluator::breakdownEvalExpr(const std::string& expr) { long ust = hobbes::tick() - t0; t0 = hobbes::tick(); - typedef void (*pvthunk)(); + using pvthunk = void (*)(); pvthunk f = this->ctx.compileFn(e); long ct = hobbes::tick() - t0; @@ -283,7 +296,7 @@ bool evaluator::satisfied(const hobbes::ConstraintPtr& c) { } void showSearchResults(const std::string&, const hobbes::SearchEntries& ses) { - if (ses.size() > 0) { + if (!ses.empty()) { std::map stbl; for (const auto& se : ses) { stbl[se.sym] = hobbes::show(se.ty); @@ -314,6 +327,10 @@ void evaluator::searchDefs(const std::string& expr_to_type) { void evaluator::setOption(const std::string& o) { this->opts.push_back(o); + if (o == "IgnoreUnreachableMatches") { + this->ctx.ignoreUnreachableMatches(true); + this->ctx.setGatherUnreachableMatchesFn(defPrintUnreachableMatches); + } } hobbes::ExprPtr evaluator::readExpr(const std::string& x) { diff --git a/bin/hi/evaluator.H b/bin/hi/evaluator.H index 1fe491d56..ad23ebcb8 100644 --- a/bin/hi/evaluator.H +++ b/bin/hi/evaluator.H @@ -7,11 +7,11 @@ namespace hi { -typedef std::vector ModuleFiles; +using ModuleFiles = std::vector; struct Args { - typedef std::map NameVals; - typedef std::vector strs; + using NameVals = std::map; + using strs = std::vector; ModuleFiles mfiles; std::vector evalExprs; diff --git a/bin/hi/funcdefs.C b/bin/hi/funcdefs.C index 02e5bd3d3..7b08d0189 100644 --- a/bin/hi/funcdefs.C +++ b/bin/hi/funcdefs.C @@ -7,13 +7,13 @@ #include #include -#include -#include -#include #include -#include -#include +#include #include +#include +#include +#include +#include namespace hi { @@ -48,7 +48,7 @@ const hobbes::array* showTick(long x) { void enableConsoleCmds(bool f); // spawn sub-processes and support basic I/O -typedef std::pair PIO; +using PIO = std::pair; const PIO* pexec(const hobbes::array* cmd) { PIO* p = hobbes::make(0, 0); @@ -75,13 +75,13 @@ const PIO* pexec(const hobbes::array* cmd) { close(c2p[1]); hobbes::str::seq args = hobbes::str::csplit(hobbes::makeStdString(cmd), " "); - if (args.size() == 0) return p; + if (args.empty()) return p; std::vector argv; - for (size_t i = 0; i < args.size(); ++i) { - argv.push_back(args[i].c_str()); + for (const auto &arg : args) { + argv.push_back(arg.c_str()); } - argv.push_back(0); + argv.push_back(nullptr); execv(args[0].c_str(), const_cast(&argv[0])); exit(0); diff --git a/bin/hi/main.C b/bin/hi/main.C index 96fed7728..93b1cf40f 100644 --- a/bin/hi/main.C +++ b/bin/hi/main.C @@ -6,27 +6,27 @@ #include #include -#include +#include +#include +#include +#include #include -#include +#include #include -#include -#include -#include #include "cio.H" #include "evaluator.H" -#include -#include +#include #include +#include namespace str = hobbes::str; namespace hi { // the one evaluator for this process -evaluator* eval = 0; +evaluator* eval = nullptr; // control color options (these can be tweaked by ~/.hirc) ConsoleColors colors; @@ -106,7 +106,7 @@ void printAnnotatedError(const hobbes::annotated_error& ae, const hobbes::Constr for (const auto& m : ae.messages()) { std::cout << setbold() << setfgc(colors.errorfg) << m.second.lineDesc() << ": " << m.first << "\n"; for (const auto& c : cs) { - if (eval && !eval->satisfied(c)) { + if ((eval != nullptr) && !eval->satisfied(c)) { std::cout << " " << hobbes::show(c) << std::endl; } } @@ -118,8 +118,8 @@ void printAnnotatedError(const hobbes::annotated_error& ae, const hobbes::Constr void printASM(void*,size_t); // show help on supported prompt commands -typedef std::pair CmdDesc; -typedef std::vector CmdDescs; +using CmdDesc = std::pair; +using CmdDescs = std::vector; void showShellHelp(const CmdDescs& cds) { std::string header = "Supported hi commands"; @@ -136,8 +136,8 @@ void showShellHelp(const CmdDescs& cds) { << std::endl; double hw = static_cast(llen - header.size()) / 2.0; - size_t lhw = static_cast(floor(hw)); - size_t rhw = static_cast(ceil(hw)); + auto lhw = static_cast(floor(hw)); + auto rhw = static_cast(ceil(hw)); std::cout << "| " << std::string(lhw, ' ') @@ -194,7 +194,7 @@ void showUnsafeSymbols() { void echoCommandHistory() { const int history_max = 10; HIST_ENTRY** history = history_list(); - if (history) { + if (history != nullptr) { // take the last history_max elements of history int startIndex = history_length > history_max ? history_length - history_max : 0; for (int i = startIndex; i < history_length; ++i) { @@ -217,7 +217,7 @@ char* completionStep(const char*, int state) { if (state >= 0 && size_t(state) < completionMatches.size()) { return strdup(completionMatches[state].c_str()); } else { - return 0; + return nullptr; } } @@ -229,7 +229,7 @@ char** completions(const char* pfx, int start, int) { #ifdef BUILD_LINUX rl_bind_key('\t', rl_abort); #endif - return 0; + return nullptr; } } @@ -281,7 +281,7 @@ void repl(evaluator*) { [](int,void*) { rl_callback_read_char(); }, - 0 + nullptr ); // poll for events and dispatch them @@ -291,11 +291,11 @@ void repl(evaluator*) { void evalLine(char* x) { // preprocess this line from readline std::string line; - if (x) { + if (x != nullptr) { line = str::trim(x); free(x); - if (line.size() > 0) { + if (!line.empty()) { add_history(line.c_str()); } } else { @@ -309,7 +309,7 @@ void evalLine(char* x) { if (line == ":q") { std::cout << resetfmt() << std::flush; exit(0); - } else if (line == "") { + } else if (line.empty()) { return; } else if (line == ":^") { echoCommandHistory(); @@ -430,14 +430,14 @@ unsigned int digitLen(unsigned int x) { template unsigned int sumSize(const C& cs) { unsigned int s = 0; - for (typename C::const_iterator c = cs.begin(); c != cs.end(); ++c) { + for (auto c = cs.begin(); c != cs.end(); ++c) { s += c->size(); } return s; } bool isNum(const std::string& x) { - return x.size() > 0 && x[0] == '0'; + return !x.empty() && x[0] == '0'; } bool isRegister(const std::string& x) { @@ -455,7 +455,7 @@ void printASMArg(const std::string& x) { } unsigned int fmtLen(const str::seq& args) { - if (args.size() == 0) { + if (args.empty()) { return 0; } else if (args.size() == 1) { return args[0].size(); @@ -487,7 +487,7 @@ void printASMTable(const str::seq& insts, const str::seqs& args, unsigned int ma // show the arguments const str::seq& argl = args[i]; - if (argl.size() > 0) { + if (!argl.empty()) { printASMArg(argl[0]); for (unsigned int k = 1; k < argl.size(); ++k) { std::cout << setfgc(colors.argdelimfg) << ", "; @@ -572,7 +572,7 @@ void runProcess(const std::string& cmd, std::ostream& out) { char buf[4096]; int n; - while ((n = read(pio[0], buf, sizeof(buf)))) { + while ((n = read(pio[0], buf, sizeof(buf))) != 0) { out.write(buf, n); } close(pio[0]); @@ -709,9 +709,9 @@ int main(int argc, char** argv) { } // load any modules passed in - if (args.mfiles.size() > 0) { - for (ModuleFiles::const_iterator m = args.mfiles.begin(); m != args.mfiles.end(); ++m) { - eval->loadModule(str::expandPath(*m)); + if (!args.mfiles.empty()) { + for (const auto &mfile : args.mfiles) { + eval->loadModule(str::expandPath(mfile)); } } diff --git a/bin/hi/www.C b/bin/hi/www.C index 0f4553a3d..5ae567a35 100644 --- a/bin/hi/www.C +++ b/bin/hi/www.C @@ -70,11 +70,7 @@ bool catPathToFSPath(const std::string& cat, const std::string& cpath, std::stri } *fsPath = exeDir() + "/../../common/www/" + cat + "/" + cpath; - if (fileExists(*fsPath)) { - return true; - } - - return false; + return fileExists(*fsPath); } // find a www 'system' file @@ -219,7 +215,7 @@ void WWWServer::evalHxpFile(const hobbes::HTTPRequest&, int fd, const std::strin } // utility functions for web processes -typedef hobbes::array cstr; +using cstr = hobbes::array; const cstr* linkTarget(const cstr* p) { using namespace hobbes; @@ -232,7 +228,7 @@ const cstr* slurpFile(const cstr* fpath) { return makeString(str::slurp(f)); } -typedef std::pair cstrpair; +using cstrpair = std::pair; const hobbes::array< const cstr* >* csplit(const cstr* s, const cstr* ss) { using namespace hobbes; @@ -245,7 +241,7 @@ const hobbes::array< const cstr* >* csplit(const cstr* s, const cstr* ss) { } long unixTime() { - return time(0) * (1000 * 1000); + return time(nullptr) * (1000 * 1000); } const cstr* formatJSTime(long x) { @@ -284,8 +280,7 @@ WWWServer::WWWServer(int port, hobbes::cc* c) : c(c) { hobbes::installHTTPD(port, &WWWServer::evalHTTPRequest, this); } -WWWServer::~WWWServer() { -} +WWWServer::~WWWServer() = default; std::string urlDecode(const std::string& x) { using namespace hobbes::str; @@ -317,9 +312,7 @@ std::string htmlEncode(const std::string& x) { using namespace hobbes::str; std::ostringstream ss; - for (size_t i = 0; i < x.size(); ++i) { - char c = x[i]; - + for (const char c : x) { switch (c) { case '&': ss << "&"; @@ -344,7 +337,7 @@ std::string showType(hobbes::cc& c, const hobbes::QualTypePtr& t) { hobbes::QualTypePtr st = hobbes::simplifyVarNames(hobbes::qualtype(cs, t->monoType())); std::ostringstream ss; - if (st->constraints().size() > 0) { + if (!st->constraints().empty()) { ss << htmlEncode(hobbes::show(st->constraints()[0])); for (size_t i = 1; i < st->constraints().size(); ++i) { ss << ", " << htmlEncode(hobbes::show(st->constraints()[i])); @@ -360,8 +353,8 @@ void WWWServer::printDefaultPage(int fd) { b << "hi process
";
 
   b << "

Environment

\n"; - for (auto vty : this->c->typeEnv()->typeEnvTable()) { - if (vty.first.size() > 0 && vty.first[0] != '.') { + for (const auto& vty : this->c->typeEnv()->typeEnvTable()) { + if (!vty.first.empty() && vty.first[0] != '.') { b << ""; } } @@ -377,7 +370,7 @@ void WWWServer::printDefaultPage(int fd) { void WWWServer::printQueryResult(int fd, const std::string& expr) { try { - typedef void (*pprintF)(); + using pprintF = void (*)(); pprintF f = this->c->compileFn("print(" + expr + ")"); // redirect stdout for this evaluation @@ -492,7 +485,7 @@ std::string WWWServer::mimeTypeForExt(const std::string& ext) { std::string line; std::getline(mtypes, line); - if (line.size() > 0 && line[0] != '#') { + if (!line.empty() && line[0] != '#') { using namespace hobbes; str::pair lp = str::lsplit(line, "\t"); @@ -516,8 +509,8 @@ WWWServer::VarBindingDescs* WWWServer::getVarBindingDescs() { auto* result = hobbes::makeArray(tenvTable.size()); size_t i = 0; - for (auto vty : tenvTable) { - if (vty.first.size() > 0 && vty.first[0] != '.') { + for (const auto& vty : tenvTable) { + if (!vty.first.empty() && vty.first[0] != '.') { result->data[i].first = hobbes::makeString(vty.first); result->data[i].second = hobbes::makeString(showType(*this->c, vty.second->instantiate())); ++i; diff --git a/bin/hi/www.H b/bin/hi/www.H index 0a52c40fd..fd11d40b8 100644 --- a/bin/hi/www.H +++ b/bin/hi/www.H @@ -19,17 +19,17 @@ private: void printQueryResult(int, const std::string&); void printFileContents(int, const std::string&); - typedef void (*PrintPageFn)(int fd, const hobbes::array* queryString); + using PrintPageFn = void (*)(int, const hobbes::array *); struct HxpFile { time_t ftime; PrintPageFn f; }; - typedef std::unordered_map HxpFiles; + using HxpFiles = std::unordered_map; HxpFiles hxpFiles; const HxpFile& hxpFile(const std::string& fpath); void evalHxpFile(const hobbes::HTTPRequest&, int fd, const std::string& fpath, const std::string& queryString); - typedef std::map MIMETypes; + using MIMETypes = std::map; MIMETypes mimeTypes; std::string mimeType(const std::string& fpath); std::string mimeTypeForExt(const std::string& ext); @@ -38,8 +38,8 @@ private: static void evalHTTPRequest(const hobbes::HTTPRequest& req, int fd, void* ud); // useful bindings - typedef std::pair*, const hobbes::array*> VarBindingDesc; - typedef hobbes::array VarBindingDescs; + using VarBindingDesc = std::pair *, const hobbes::array *>; + using VarBindingDescs = hobbes::array; VarBindingDescs* getVarBindingDescs(); }; diff --git a/bin/hog/batchrecv.C b/bin/hog/batchrecv.C index d98e33775..3c9d3005a 100644 --- a/bin/hog/batchrecv.C +++ b/bin/hog/batchrecv.C @@ -68,7 +68,7 @@ struct gzbuffer { void decompressChunk() { this->zin.next_out = outb->data(); this->zin.avail_out = outb->size(); - checkZLibRC(inflate(&this->zin, Z_NO_FLUSH) < 0); + checkZLibRC(static_cast(inflate(&this->zin, Z_NO_FLUSH) < 0)); this->off = 0; this->avail = this->outb->size() - this->zin.avail_out; } @@ -141,7 +141,7 @@ DEFINE_STRUCT( (int, remotePort) ); -void runRecvConnection(SessionGroup* sg, NetConnection* pc, std::string dir) { +void runRecvConnection(SessionGroup* sg, NetConnection* pc, const std::string& dir) { std::unique_ptr connection(pc); std::vector inb, outb, txn; outb.resize(1 * 1024 * 1024); // reserve 1MB for buffering @@ -193,7 +193,7 @@ void runRecvConnection(SessionGroup* sg, NetConnection* pc, std::string dir) { } } -[[noreturn]] void runRecvServer(std::unique_ptr server, std::string dir, bool consolidate, hobbes::StoredSeries::StorageMode sm) { +[[noreturn]] void runRecvServer(std::unique_ptr server, const std::string& dir, bool consolidate, hobbes::StoredSeries::StorageMode sm) { SessionGroup* sg = makeSessionGroup(consolidate, sm); std::vector cthreads; diff --git a/bin/hog/batchsend.C b/bin/hog/batchsend.C index 239e5ef36..6f39b0803 100644 --- a/bin/hog/batchsend.C +++ b/bin/hog/batchsend.C @@ -7,14 +7,15 @@ #include #include +#include +#include #include #include -#include +#include #include -#include -#include +#include +#include #include -#include #include #include @@ -64,7 +65,7 @@ struct Destination { std::ostream& operator<<(std::ostream& o, const std::vector& xs) { o << "["; - if (xs.size() > 0) { + if (!xs.empty()) { auto x = xs.begin(); o << "\"" << x->hostport << "\""; ++x; @@ -92,11 +93,11 @@ void sendFileContents(NetConnection& connection, const openfd& sfd) { void sendSegmentFiles(NetConnection& connection, const std::string& localdir) { // poll for segment files - typedef std::map> OrderedSegFiles; + using OrderedSegFiles = std::map>; OrderedSegFiles segfiles; glob_t g; - if (glob((localdir + "/segment-*.gz").c_str(), GLOB_NOSORT, 0, &g) == 0) { + if (glob((localdir + "/segment-*.gz").c_str(), GLOB_NOSORT, nullptr, &g) == 0) { for (size_t i = 0; i < g.gl_pathc; ++i) { struct stat st; if (stat(g.gl_pathv[i], &st) == 0) { @@ -155,7 +156,7 @@ void sendInitMessageToAll(const std::string& groupName, std::vector using IdleFn = std::function; using ReadyFn = std::function; -void sendSegmentFilesToAll(std::vector& destinations, IdleFn idleFn) { +void sendSegmentFilesToAll(std::vector& destinations, const IdleFn& idleFn) { bool yield = false; while (!yield) { for (auto & d : destinations) { @@ -175,7 +176,7 @@ void sendSegmentFilesToAll(std::vector& destinations, IdleFn idleFn } } -void runConnectedSegmentSendingProcess(const std::string& groupName, std::vector& destinations, IdleFn idleFn) { +void runConnectedSegmentSendingProcess(const std::string& groupName, std::vector& destinations, const IdleFn& idleFn) { try { sendInitMessageToAll(groupName, destinations); sendSegmentFilesToAll(destinations, idleFn); @@ -199,7 +200,7 @@ void connect(std::vector& destinations) { } } -void runSegmentSendingProcess(const size_t sessionHash, const std::string groupName, std::vector& destinations, ReadyFn readyFn, IdleFn idleFn) { +void runSegmentSendingProcess(const size_t sessionHash, const std::string& groupName, std::vector& destinations, const ReadyFn& readyFn, const IdleFn& idleFn) { if (destinations.empty()) { out() << "no batchsend host specified, compressed segment files will accumulate locally" << std::endl; } else { @@ -251,16 +252,16 @@ struct BatchSendSession { std::vector detached; std::function finalizer; - BatchSendSession(const size_t sessionHash, const std::string& groupName, const std::string& dir, size_t clevel, const std::vector& sendto, const std::vector detached, const std::function finalizer) - : buffer(0), c(0), sz(0), dir(dir), readerAlive(true), detached(detached), finalizer(finalizer) { + BatchSendSession(const size_t sessionHash, const std::string& groupName, const std::string& dir, size_t clevel, const std::vector& sendto, const std::vector& detached, const std::function& finalizer) + : buffer(nullptr), c(0), sz(0), dir(dir), readerAlive(true), detached(detached), finalizer(finalizer) { for (const auto & hostport : sendto) { auto localdir = ensureDirExists(dir + "/" + hostport + "/"); - destinations.push_back(Destination{localdir, hostport}); + destinations.emplace_back(localdir, hostport); } // start from last segment in directory const auto paths = hobbes::str::paths(dir + "*/segment-*.gz"); - if (paths.size() > 0) { + if (!paths.empty()) { this->c = std::stoi(hobbes::str::rsplit(hobbes::str::rsplit(paths.back(), ".gz").first, "segment-").second); } @@ -277,7 +278,7 @@ struct BatchSendSession { auto idleFn = [this, groupName]() { static thread_local uint64_t count = 0; - if (++count % 16) return; // not checking on each idle cycle + if ((++count % 16) != 0u) return; // not checking on each idle cycle if (!readerAlive && completed()) { this->finalizer(); @@ -289,7 +290,7 @@ struct BatchSendSession { this->sendingThread = std::thread([this, sessionHash, groupName, dir, readerId, readyFn, idleFn]() { const auto senderId = hobbes::storage::thisProcThread(); std::vector senderqueue; - for (auto s : this->detached) { + for (const auto *s : this->detached) { senderqueue.push_back(s->dir); } StatFile::instance().log(SenderRegistration{hobbes::now(), sessionHash, readerId, senderId, this->dir, senderqueue}); @@ -337,7 +338,7 @@ struct BatchSendSession { bool completed() const { return std::all_of(destinations.begin(), destinations.end(), [](const Destination& d) { glob_t g; - auto ret = glob((d.localdir + "/segment-*.gz").c_str(), GLOB_NOSORT, 0, &g); + auto ret = glob((d.localdir + "/segment-*.gz").c_str(), GLOB_NOSORT, nullptr, &g); if (ret == 0) { auto remaining = g.gl_pathc; globfree(&g); @@ -406,7 +407,7 @@ struct SenderGroup { auto it = std::find_if_not(detached.begin(), detached.end(), [](const BatchSendSession* s) { return s->completed(); }); detached.erase(detached.begin(), it); - senders.push_back(std::unique_ptr(new BatchSendSession{sessionHash, name, dir, clevel, sendto, detached, finalizeSenderF})); + senders.push_back(std::make_unique(sessionHash, name, dir, clevel, sendto, detached, finalizeSenderF)); return senders.back().get(); } @@ -423,7 +424,7 @@ std::vector SenderGroup::detached; std::mutex SenderGroup::mutex; void pushLocalData(const hobbes::storage::QueueConnection& qc, const size_t sessionHash, const std::string& groupName, const std::string& partialDir, const std::string& fullDir, const hobbes::storage::ProcThread& readerId, const hobbes::storage::WaitPolicy wp, const RunMode& runMode, std::atomic& conn, const std::function& finalizeSenderF) { - auto sn = SenderGroup::create(sessionHash, groupName, fullDir, runMode.clevel, runMode.sendto, finalizeSenderF); + auto *sn = SenderGroup::create(sessionHash, groupName, fullDir, runMode.clevel, runMode.sendto, finalizeSenderF); const long batchsendtime = runMode.batchsendtime * 1000; const size_t batchsendsize = std::max(10*1024*1024, runMode.batchsendsize); long t0 = hobbes::time(); @@ -442,7 +443,7 @@ void pushLocalData(const hobbes::storage::QueueConnection& qc, const size_t sess } auto timeoutF = [&](const hobbes::storage::reader& reader) { - if (conn == false && *reader.config().wstate == PRIV_HSTORE_STATE_READER_WAITING) { + if (!conn && *reader.config().wstate == PRIV_HSTORE_STATE_READER_WAITING) { // if we are here, the client is disconnected and the queue is drained // detach tcp send session synchronously and shut down the reader SenderGroup::detach(sn); diff --git a/bin/hog/boot/gen/boot.C b/bin/hog/boot/gen/boot.C index 3284e2a74..1e44ef219 100644 --- a/bin/hog/boot/gen/boot.C +++ b/bin/hog/boot/gen/boot.C @@ -7,7 +7,7 @@ namespace hog { #include "bootdata.H" void compileBootCode(hobbes::cc& ctx) { - hobbes::compile(&ctx, ctx.readModule(std::string(reinterpret_cast(___bootdata), ___bootdata_len))); + hobbes::compile(&ctx, ctx.readModule(std::string(reinterpret_cast(_bootdata), _bootdata_len))); } } diff --git a/bin/hog/boot/gen/bootdata.H b/bin/hog/boot/gen/bootdata.H index ee1989a0b..55eb3943e 100644 --- a/bin/hog/boot/gen/bootdata.H +++ b/bin/hog/boot/gen/bootdata.H @@ -1,4 +1,4 @@ -unsigned char ___bootdata[] = { +unsigned char _bootdata[] = { 0x2f, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x72, 0x65, 0x61, 0x64, 0x20, 0x3a, 0x20, 0x49, 0x2f, 0x4f, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x20, 0x70, 0x69, @@ -586,4 +586,4 @@ unsigned char ___bootdata[] = { 0x64, 0x28, 0x74, 0x78, 0x6e, 0x29, 0x3a, 0x3a, 0x28, 0x28, 0x29, 0x2b, 0x74, 0x29, 0x29, 0x0a, 0x0a }; -unsigned int ___bootdata_len = 7025; +unsigned int _bootdata_len = 7025; diff --git a/bin/hog/config.C b/bin/hog/config.C index 55c131add..4decb512a 100644 --- a/bin/hog/config.C +++ b/bin/hog/config.C @@ -112,7 +112,7 @@ RunMode config(int argc, const char** argv) { ++i; while (i < argc && argv[i][0] != '-') { - r.sendto.push_back(argv[i]); + r.sendto.emplace_back(argv[i]); ++i; } --i; @@ -148,7 +148,7 @@ RunMode config(int argc, const char** argv) { } if (r.t == RunMode::local || r.t == RunMode::batchsend) { - if (r.groups.size() == 0) { + if (r.groups.empty()) { throw std::runtime_error("can't record data because no groups have been specified"); } if (::access(r.groupServerDir.c_str(), W_OK) != 0) { diff --git a/bin/hog/config.H b/bin/hog/config.H index c5ed0a085..d01750f27 100644 --- a/bin/hog/config.H +++ b/bin/hog/config.H @@ -41,7 +41,7 @@ struct RunMode { template inline std::ostream& operator<<(std::ostream& o, const std::vector& xs) { o << "["; - if (xs.size() > 0) { + if (!xs.empty()) { auto x = xs.cbegin(); o << "\"" << *x << "\""; ++x; diff --git a/bin/hog/local.C b/bin/hog/local.C index 04f69a383..573e5a31f 100644 --- a/bin/hog/local.C +++ b/bin/hog/local.C @@ -17,7 +17,7 @@ void recordLocalData(SessionGroup* sg, const hobbes::storage::QueueConnection& q using namespace hobbes; auto timeoutF = [&qc,&conn](const storage::reader& reader) { - if (conn == false && *reader.config().wstate == PRIV_HSTORE_STATE_READER_WAITING) { + if (!conn && *reader.config().wstate == PRIV_HSTORE_STATE_READER_WAITING) { throw ShutdownException("SHM reader shutting down, name: " + qc.shmname); } }; diff --git a/bin/hog/main.C b/bin/hog/main.C index 52cff895d..76d992300 100644 --- a/bin/hog/main.C +++ b/bin/hog/main.C @@ -17,7 +17,7 @@ #include "path.H" #include "out.H" -#include +#include namespace hog { @@ -86,7 +86,7 @@ void runGroupHost(const size_t sessionHash, const std::string& groupName, const [sg,groupName,&sessionHash,&m,®](int s) { out() << "new connection for '" << groupName << "'" << std::endl; - int c = accept(s, 0, 0); + int c = accept(s, nullptr, nullptr); if (c != -1) { try { uint32_t version = 0; @@ -118,12 +118,12 @@ void run(const RunMode& m, const std::vector& args) { out() << "hog stat file : " << StatFile::instance().filename() << std::endl; hog::StatFile::instance().log(hog::ProcessEnvironment{hobbes::now(), sessionHash, hobbes::string::from(m), args, hog::SessionType::Enum::Normal}); pullRemoteDataT(m.dir, m.localport, m.consolidate, m.storageMode).join(); - } else if (m.groups.size() > 0) { + } else if (!m.groups.empty()) { out() << "hog stat file : " << StatFile::instance().filename() << std::endl; hog::StatFile::instance().log(hog::ProcessEnvironment{hobbes::now(), sessionHash, hobbes::string::from(m), args, hog::SessionType::Enum::Normal}); std::map> registry; - for (auto g : m.groups) { + for (const auto& g : m.groups) { try { out() << "install a monitor for the '" << g << "' group" << std::endl; runGroupHost(sessionHash, g, m, registry[g]); diff --git a/bin/hog/netconnection.C b/bin/hog/netconnection.C index f0d63709d..ccb58a230 100644 --- a/bin/hog/netconnection.C +++ b/bin/hog/netconnection.C @@ -102,7 +102,7 @@ bool DefaultNetConnection::sendFile(int fd) { off_t size = sb.st_size; off_t offset = 0; - while (size) { + while (size != 0) { const ssize_t sent = sendfile(this->fd, fd, &offset, size); if (sent >= 0) { size -= sent; diff --git a/bin/hog/path.C b/bin/hog/path.C index 8b5a5a76d..97fa18d20 100644 --- a/bin/hog/path.C +++ b/bin/hog/path.C @@ -9,7 +9,7 @@ std::string instantiateDir(const std::string& groupName, const std::string& dir) std::string x = hobbes::str::replace(dir, "$GROUP", groupName); // instantiate date - time_t now = ::time(0); + time_t now = ::time(nullptr); if (const tm* t = localtime(&now)) { std::ostringstream ss; ss << t->tm_year + 1900 << "." << (t->tm_mon < 9 ? "0" : "") << t->tm_mon + 1 << "." << (t->tm_mday < 10 ? "0" : "") << t->tm_mday; diff --git a/bin/hog/recovery.C b/bin/hog/recovery.C index fd78d8afd..57bc2979c 100644 --- a/bin/hog/recovery.C +++ b/bin/hog/recovery.C @@ -43,7 +43,7 @@ template static std::vector retrieveFromStats(hobbes::fregion::reader& r) { std::vector ts; - auto& data = r.series(T::_hmeta_struct_type_name().c_str()); + auto& data = r.series(T::_hmeta_struct_type_name()); T t; while (data.next(&t)) { ts.emplace_back(std::move(t)); @@ -111,7 +111,7 @@ static std::vector recoverSessionInformation() { for (const std::vector::const_iterator& rr : readerRegistrations) { if (sr->readerId == rr->readerId) { // pair together reader and sender regs with matching reader ids - details.readerSenderRegs.push_back(std::make_pair(*rr, *sr)); + details.readerSenderRegs.emplace_back(*rr, *sr); } } } @@ -146,7 +146,7 @@ static bool hasBeenRecovered(const std::vector& sessionRecover static bool hasBeenCorrectlyClosed(const std::vector& senderStates) { // Sender states should be temporally ordered earliest->latest - return senderStates.size() == 0 ? false : senderStates.back().status.value == SenderStatus::Enum::Closed; + return senderStates.empty() ? false : senderStates.back().status.value == SenderStatus::Enum::Closed; } struct RecoveryTask { @@ -301,7 +301,7 @@ void detectFaultAndRecover() { const std::vector tasks = getTasksRequiringRecovery(recoveredDetails); // ignore groups with no associable tasks - if (tasks.size() > 0) { + if (!tasks.empty()) { recoveryTaskGroups.emplace_back(RecoveryTaskGroup{runMode, recoveredDetails.processEnvironment.sessionHash, recoveredDetails.processEnvironment.argv, diff --git a/bin/hog/session.C b/bin/hog/session.C index 2dc00f164..93b86bc2b 100644 --- a/bin/hog/session.C +++ b/bin/hog/session.C @@ -22,7 +22,7 @@ bool hstoreCanRead(storage::Transaction& txn, size_t n) { } const uint8_t* hstoreUnsafeRead(storage::Transaction& txn, size_t n) { - auto p = txn.ptr(); + const auto *p = txn.ptr(); txn.skip(n); return p; } @@ -37,8 +37,8 @@ const uint8_t* hstoreUnsafeReadFixedArray(storage::Transaction& txn, size_t byte } cc* loggerCompiler() { - static cc* c = 0; - if (!c) { + static cc* c = nullptr; + if (c == nullptr) { c = new cc(); c->bind("hstoreCanRead", &hstoreCanRead); c->bind("hstoreUnsafeRead", &hstoreUnsafeRead); @@ -62,7 +62,7 @@ DEFINE_STRUCT( std::string ensureDirExists(const std::string& dirPfx) { hobbes::str::seq ps = hobbes::str::csplit(dirPfx, "/"); std::ostringstream pfx; - if (ps.size() > 0) { + if (!ps.empty()) { for (size_t i = 0; i < (ps.size()-1); ++i) { pfx << ps[i] << "/"; if (mkdir(pfx.str().c_str(), S_IRWXU | S_IRWXG | S_IRWXO) == -1 && errno != EEXIST) { @@ -89,12 +89,12 @@ struct Session { hobbes::writer* db; // sections of the file for structured data - typedef std::vector StoredSeriess; + using StoredSeriess = std::vector; StoredSeriess streams; // functions for actually writing stream data - typedef void (*WriteFn)(hobbes::storage::Transaction*); - typedef std::vector WriteFns; + using WriteFn = void (*)(hobbes::storage::Transaction *); + using WriteFns = std::vector; WriteFns writeFns; @@ -120,7 +120,7 @@ public: std::string ready() { std::string fpath = moveToUniqueFilename(this->tmpPath, this->dirPfx, ".log"); this->tmpPath = ""; - this->f = 0; + this->f = nullptr; return fpath; } @@ -137,7 +137,7 @@ public: AppendFirstMatchingFile(const std::string& dirPfx, storage::CommitMethod cm, const storage::statements& stmts) : dirPfx(dirPfx) { this->f = findMatchingFile(dirPfx, cm, stmts); - if (this->f == 0) { + if (this->f == nullptr) { this->tmpPath = freshTempFile(dirPfx); this->f = new writer(this->tmpPath); } @@ -159,7 +159,7 @@ public: fpath = moveToUniqueFilename(this->tmpPath, this->dirPfx, ".log"); this->tmpPath = ""; } - this->f = 0; + this->f = nullptr; return fpath; } @@ -171,9 +171,9 @@ private: static writer* findMatchingFile(const std::string& dirPfx, storage::CommitMethod cm, const storage::statements& stmts) { glob_t g; - if (glob((dirPfx + "*.log").c_str(), GLOB_NOSORT, 0, &g) == 0) { + if (glob((dirPfx + "*.log").c_str(), GLOB_NOSORT, nullptr, &g) == 0) { for (size_t i = 0; i < g.gl_pathc; ++i) { - writer* f = 0; + writer* f = nullptr; try { f = new writer(g.gl_pathv[i]); if (fileMatchesStatements(f, cm, stmts)) { @@ -188,7 +188,7 @@ private: globfree(&g); } - return 0; // couldn't find any matching file + return nullptr; // couldn't find any matching file } static bool fileMatchesStatements(writer* f, storage::CommitMethod cm, const storage::statements& stmts) { @@ -261,7 +261,7 @@ ProcessTxnF initStorageSession(Session* s, const std::string& dirPfx, storage::P // allocate space for every log statement Variant::Members txnEntries; - for (auto stmt : stmts) { + for (const auto& stmt : stmts) { MonoTypePtr pty = decode(stmt.type); out << " ==> " << stmt.name << " :: " << show(pty) << " (#" << stmt.id << ")" << std::endl; if (s->streams.size() <= stmt.id) { @@ -269,7 +269,7 @@ ProcessTxnF initStorageSession(Session* s, const std::string& dirPfx, storage::P s->writeFns.resize(stmt.id + 1); } - auto ss = new StoredSeries(c, s->db, stmt.name, pty, 10000, sm); + auto *ss = new StoredSeries(c, s->db, stmt.name, pty, 10000, sm); std::string writefn = "write_" + str::from(hobbes::time()) + "_" + stmt.name; ss->bindAs(c, writefn); @@ -379,7 +379,7 @@ ProcessTxnF initStorageSession(Session* s, const std::string& dirPfx, storage::P // support merging log session data where type structures are identical class SessionGroup { public: - virtual ~SessionGroup() { } + virtual ~SessionGroup() = default; virtual ProcessTxnF appendStorageSession(const std::string& dirPfx, hobbes::storage::PipeQOS qos, hobbes::storage::CommitMethod cm, const hobbes::storage::statements& stmts) = 0; }; @@ -388,7 +388,7 @@ public: ConsolidateGroup(hobbes::StoredSeries::StorageMode sm) : sm(sm) { } - ProcessTxnF appendStorageSession(const std::string& dirPfx, hobbes::storage::PipeQOS qos, hobbes::storage::CommitMethod cm, const hobbes::storage::statements& stmts) { + ProcessTxnF appendStorageSession(const std::string& dirPfx, hobbes::storage::PipeQOS qos, hobbes::storage::CommitMethod cm, const hobbes::storage::statements& stmts) override { std::lock_guard slock(this->m); for (auto* cs : this->sessions) { if (dirPfx == cs->dirPfx && qos == cs->qos && cm == cs->cm && stmts == cs->stmts) { @@ -433,8 +433,8 @@ public: SimpleGroup(hobbes::StoredSeries::StorageMode sm) : sm(sm) { } - ProcessTxnF appendStorageSession(const std::string& dirPfx, hobbes::storage::PipeQOS qos, hobbes::storage::CommitMethod cm, const hobbes::storage::statements& stmts) { - Session* s = new Session; + ProcessTxnF appendStorageSession(const std::string& dirPfx, hobbes::storage::PipeQOS qos, hobbes::storage::CommitMethod cm, const hobbes::storage::statements& stmts) override { + auto* s = new Session; return initStorageSession(s, dirPfx, qos, cm, stmts, this->sm); } private: diff --git a/bin/hog/session.H b/bin/hog/session.H index 39fc8edaa..544c83bbf 100644 --- a/bin/hog/session.H +++ b/bin/hog/session.H @@ -19,7 +19,7 @@ namespace hog { class SessionGroup; SessionGroup* makeSessionGroup(bool consolidate = false, hobbes::StoredSeries::StorageMode sm = hobbes::StoredSeries::Raw); -typedef std::function ProcessTxnF; +using ProcessTxnF = std::function; ProcessTxnF appendStorageSession(SessionGroup*, const std::string& dirPfx, hobbes::storage::PipeQOS qos, hobbes::storage::CommitMethod cm, const hobbes::storage::statements& stmts); // common way to prepare output directories from dir prefix patterns diff --git a/doc/en/examples/simplerepl.rst b/doc/en/examples/simplerepl.rst index 21f540fce..d59b1cac6 100755 --- a/doc/en/examples/simplerepl.rst +++ b/doc/en/examples/simplerepl.rst @@ -25,7 +25,7 @@ Here's the full code listing. Afterwards we'll dig into all the parts one by one typedef std::pair*> Writer; Writer* getWriter(){ - return hobbes::make(34, hobbes::makeString("Sam")); + return hobbes::make(34, hobbes::makeString("Sam")); } hobbes::array* getWriters(){ @@ -123,7 +123,7 @@ Binding custom datatypes (const hobbes::array*, name) ); - typedef std::pair*> Writer1; + typedef std::pair*> Writer; Writer* getWriter(){ return hobbes::make(34, hobbes::makeString("Sam")); @@ -186,7 +186,7 @@ Function pointers return pf(x, x); } -The basic mechanism by which work is abstracted, and how we can externalise behaviour from Hobbes - allowing us to interact with Hobbes functionality from outside the environment. In this case we expect ``binaryIntFn`` to be called with two items - firstly, a function which takes two ``int``s and returns an ``int``, and secondly an ``int``. +The basic mechanism by which work is abstracted, and how we can externalise behaviour from Hobbes - allowing us to interact with Hobbes functionality from outside the environment. In this case we expect ``binaryIntFn`` to be called with two items - firstly, a function which takes two ``int``\s and returns an ``int``, and secondly an ``int``. The result of the application of the function with the second argument twice is then returned to Hobbes as an ``int``. diff --git a/doc/en/language/controlflow.rst b/doc/en/language/controlflow.rst index d0b950404..c866c5764 100755 --- a/doc/en/language/controlflow.rst +++ b/doc/en/language/controlflow.rst @@ -138,7 +138,7 @@ This matching-and-binding logic can be generalised to arrays, too: :: match [("sam", 2013), ("james", 2012), ("stephen", 2010)] with - | [_ (n, 2012), _] -> show(n) + | [_, (n, 2012), _] -> show(n) | _ -> show("none") And, because of the way character arrays are matched, even to regular expressions: @@ -367,4 +367,4 @@ Finally, let's wrap all that up with a match and a for comprehension: :: > let start=1; end=4 in match [i | i <- [start..end], i % 2 == 0] with | [2, 4] -> "evens" | _ -> "odds" - evens \ No newline at end of file + evens diff --git a/doc/en/language/polymorphism.rst b/doc/en/language/polymorphism.rst index 54f221861..4f8ae0ba4 100755 --- a/doc/en/language/polymorphism.rst +++ b/doc/en/language/polymorphism.rst @@ -42,7 +42,7 @@ The types of the variables are left out, yet Hobbes will quite happily figure ou Hobbes has simply inferred this about those types from the context in which they're used. This is in stark contrast to languates where types are restricted on what interfaces they implement. -Many other type classes are available in the :ref:`Hobbes standard library `. We've already seen an implementation of the equivalence typeclass ``equiv``. Others include ``multiply`` (applied to types which have a ``*``) and ``print`` (for types whose values can be printed). +Many other type classes are available in the :ref:`Hobbes standard library `. We've already seen an implementation of the equivalence typeclass ``Equiv``. Others include ``Multiply`` (applied to types which have a ``*``) and ``Print`` (for types whose values can be printed). .. _type_annotations: @@ -120,4 +120,4 @@ We can take this one step further: Remember that, in our lambda syntax, this can be read as "A function which takes x and returns x.Name" - i.e. the only thing we know about the type of x is that it has a member called Name. Hi will then give names to those two as-yet unnamed types: it calls them 'a' and 'b'. -Note that Hobbes has inferred the type restriction on b: It's whatever type the value of "a.Name" is. This function will work for *any* type that has a member called ``Name``, which can be of any type! \ No newline at end of file +Note that Hobbes has inferred the type restriction on b: It's whatever type the value of "a.Name" is. This function will work for *any* type that has a member called ``Name``, which can be of any type! diff --git a/flake.lock b/flake.lock index b5e53972e..bb7acad89 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "flake-utils": { "locked": { - "lastModified": 1609935452, - "narHash": "sha256-McwA/tAnnS8LaAdEoONBsdKFHuOpHMxKqpMCU1wL7H4=", + "lastModified": 1619345332, + "narHash": "sha256-qHnQkEp1uklKTpx3MvKtY6xzgcqXDsz5nLilbbuL+3A=", "owner": "numtide", "repo": "flake-utils", - "rev": "8088c6dbe86a7e6e6396c83e43020e8a1edb08d5", + "rev": "2ebf2558e5bf978c7fb8ea927dfaed8fefab2e28", "type": "github" }, "original": { @@ -17,11 +17,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1609899452, - "narHash": "sha256-JXi5v4lygRyZjv238bKoPFrQiTAurwcL3XqOo2ZCOLg=", + "lastModified": 1619586859, + "narHash": "sha256-8DiULA5rhWipZm0Wc9IjqG03jfYSigWFYZWXUVK1ZSI=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "a3ab47ec9067b5f9fccda506fc8641484c3d8e73", + "rev": "267761cf44498f9e1aa81dbdb92d77d5873dd9f6", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index af30ac84d..8b9ab9903 100644 --- a/flake.nix +++ b/flake.nix @@ -1,6 +1,6 @@ { description = "A language and an embedded JIT compiler"; - + inputs.flake-utils.url = "github:numtide/flake-utils"; outputs = { self, nixpkgs, flake-utils }: @@ -11,16 +11,16 @@ inherit system; version = "${nixpkgs.lib.substring 0 8 self.lastModifiedDate}.${self.shortRev or "dirty"}"; src = self; - llvmVersions = [ 6 8 9 10 11 ]; + llvmVersions = [ 6 8 9 10 11 12 ]; gccConstraints = [ { gccVersion = 6; llvmVersions = [ 6 8 9 ]; } - { gccVersion = 8; llvmVersions = [ 6 8 9 10 11 ]; } - { gccVersion = 9; llvmVersions = [ 6 8 9 10 11 ]; } - { gccVersion = 10; llvmVersions = [ 6 8 9 10 11 ]; } + { gccVersion = 8; llvmVersions = [ 6 8 9 10 11 12 ]; } + { gccVersion = 9; llvmVersions = [ 6 8 9 10 11 12 ]; } + { gccVersion = 10; llvmVersions = [ 6 8 9 10 11 12 ]; } ]; }) ]; - + pkgs = import nixpkgs { inherit system overlays; }; diff --git a/include/hobbes/boot/gen/bootdata.H b/include/hobbes/boot/gen/bootdata.H index 430b7a882..57c0b9068 100644 --- a/include/hobbes/boot/gen/bootdata.H +++ b/include/hobbes/boot/gen/bootdata.H @@ -1,4 +1,4 @@ -unsigned char __amapping_hob[] = { +unsigned char _amapping_hob[] = { 0x0a, 0x2f, 0x2a, 0x0a, 0x20, 0x20, 0x42, 0x61, 0x73, 0x69, 0x63, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x69, 0x6e, @@ -455,8 +455,8 @@ unsigned char __amapping_hob[] = { 0x72, 0x61, 0x79, 0x56, 0x69, 0x65, 0x77, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x61, 0x64, 0x0a }; -unsigned int __amapping_hob_len = 5451; -unsigned char __arith_hob[] = { +unsigned int _amapping_hob_len = 5451; +unsigned char _arith_hob[] = { 0x2f, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x61, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x65, 0x74, 0x69, 0x63, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x0a, 0x20, 0x2a, 0x2f, 0x0a, 0x0a, 0x2f, 0x2f, @@ -1007,8 +1007,8 @@ unsigned char __arith_hob[] = { 0x20, 0x78, 0x20, 0x25, 0x20, 0x28, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x28, 0x79, 0x29, 0x20, 0x3a, 0x3a, 0x20, 0x62, 0x29, 0x0a, 0x0a }; -unsigned int __arith_hob_len = 6588; -unsigned char __convert_hob[] = { +unsigned int _arith_hob_len = 6588; +unsigned char _convert_hob[] = { 0x2f, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x20, 0x3a, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x22, 0x6d, 0x65, 0x61, 0x6e, 0x69, 0x6e, 0x67, 0x2d, 0x70, 0x72, 0x65, 0x73, @@ -1407,8 +1407,8 @@ unsigned char __convert_hob[] = { 0x54, 0x61, 0x69, 0x6c, 0x28, 0x73, 0x72, 0x63, 0x29, 0x2c, 0x20, 0x64, 0x73, 0x74, 0x29, 0x3b, 0x7d, 0x0a, 0x0a }; -unsigned int __convert_hob_len = 4759; -unsigned char __eq_hob[] = { +unsigned int _convert_hob_len = 4759; +unsigned char _eq_hob[] = { 0x2f, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x65, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x2f, 0x65, 0x71, 0x75, 0x69, 0x76, 0x61, 0x6c, 0x65, 0x6e, 0x63, 0x65, 0x2f, 0x6e, 0x65, 0x61, 0x72, 0x6e, 0x65, 0x73, 0x73, 0x20, @@ -1753,8 +1753,8 @@ unsigned char __eq_hob[] = { 0x28, 0x61, 0x73, 0x2c, 0x20, 0x62, 0x73, 0x2c, 0x20, 0x30, 0x4c, 0x29, 0x0a, 0x0a }; -unsigned int __eq_hob_len = 4106; -unsigned char __eqord_hob[] = { +unsigned int _eq_hob_len = 4106; +unsigned char _eqord_hob[] = { 0x2f, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x0a, 0x20, 0x2a, 0x2f, 0x0a, 0x63, 0x6c, 0x61, 0x73, 0x73, @@ -2395,8 +2395,8 @@ unsigned char __eqord_hob[] = { 0x20, 0x20, 0x78, 0x20, 0x3e, 0x3d, 0x20, 0x28, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x28, 0x79, 0x29, 0x3a, 0x3a, 0x61, 0x29, 0x0a, 0x0a }; -unsigned int __eqord_hob_len = 7668; -unsigned char __farray_hob[] = { +unsigned int _eqord_hob_len = 7668; +unsigned char _farray_hob[] = { 0x0a, 0x2f, 0x2f, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x61, 0x6c, 0x6c, 0x69, @@ -3430,8 +3430,8 @@ unsigned char __farray_hob[] = { 0x29, 0x0a, 0x7d, 0x0a, 0x7b, 0x2d, 0x23, 0x20, 0x53, 0x41, 0x46, 0x45, 0x20, 0x75, 0x6e, 0x7a, 0x69, 0x70, 0x20, 0x23, 0x2d, 0x7d, 0x0a, 0x0a }; -unsigned int __farray_hob_len = 12384; -unsigned char __farrfilt_hob[] = { +unsigned int _farray_hob_len = 12384; +unsigned char _farrfilt_hob[] = { 0x2f, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x66, 0x61, 0x72, 0x72, 0x66, 0x69, 0x6c, 0x74, 0x20, 0x3a, 0x20, 0x65, 0x66, 0x66, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, @@ -4169,8 +4169,8 @@ unsigned char __farrfilt_hob[] = { 0x20, 0x74, 0x61, 0x6b, 0x65, 0x55, 0x6e, 0x74, 0x69, 0x6c, 0x52, 0x20, 0x23, 0x2d, 0x7d, 0x0a, 0x0a }; -unsigned int __farrfilt_hob_len = 8825; -unsigned char __flip_hob[] = { +unsigned int _farrfilt_hob_len = 8825; +unsigned char _flip_hob[] = { 0x0a, 0x2f, 0x2f, 0x20, 0x66, 0x6c, 0x69, 0x70, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x61, 0x20, @@ -4238,8 +4238,8 @@ unsigned char __flip_hob[] = { 0x20, 0x5b, 0x61, 0x74, 0x5d, 0x2c, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x61, 0x69, 0x6c, 0x28, 0x79, 0x29, 0x29, 0x0a, 0x0a }; -unsigned int __flip_hob_len = 791; -unsigned char __fstrfns_hob[] = { +unsigned int _flip_hob_len = 791; +unsigned char _fstrfns_hob[] = { 0x0a, 0x66, 0x69, 0x6e, 0x64, 0x53, 0x75, 0x62, 0x73, 0x65, 0x71, 0x53, 0x74, 0x65, 0x70, 0x20, 0x3a, 0x3a, 0x20, 0x28, 0x45, 0x71, 0x75, 0x69, 0x76, 0x20, 0x61, 0x20, 0x62, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x28, 0x5b, @@ -4290,8 +4290,8 @@ unsigned char __fstrfns_hob[] = { 0x68, 0x28, 0x73, 0x73, 0x29, 0x2c, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, 0x73, 0x29, 0x29, 0x29, 0x0a, 0x0a }; -unsigned int __fstrfns_hob_len = 584; -unsigned char __hasdef_hob[] = { +unsigned int _fstrfns_hob_len = 584; +unsigned char _hasdef_hob[] = { 0x2f, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x0a, 0x20, 0x2a, 0x2f, 0x0a, 0x0a, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x48, 0x61, 0x73, 0x44, 0x65, 0x66, 0x20, 0x61, 0x20, 0x77, 0x68, @@ -4313,8 +4313,8 @@ unsigned char __hasdef_hob[] = { 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x64, 0x65, 0x66, 0x20, 0x3d, 0x20, 0x7c, 0x31, 0x3d, 0x64, 0x65, 0x66, 0x7c, 0x0a, 0x0a }; -unsigned int __hasdef_hob_len = 239; -unsigned char __list_hob[] = { +unsigned int _hasdef_hob_len = 239; +unsigned char _list_hob[] = { 0x0a, 0x2f, 0x2f, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x6e, 0x69, 0x6c, 0x20, 0x3a, 0x3a, 0x20, 0x28, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x28, 0x5e, 0x78, 0x2e, @@ -4740,8 +4740,8 @@ unsigned char __list_hob[] = { 0x20, 0x30, 0x4c, 0x2c, 0x20, 0x69, 0x2c, 0x20, 0x65, 0x29, 0x29, 0x29, 0x0a }; -unsigned int __list_hob_len = 5077; -unsigned char __lookup_hob[] = { +unsigned int _list_hob_len = 5077; +unsigned char _lookup_hob[] = { 0x2f, 0x2a, 0x0a, 0x20, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x20, 0x3a, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x2a, 0x2f, 0x0a, @@ -4850,8 +4850,8 @@ unsigned char __lookup_hob[] = { 0x6f, 0x6b, 0x75, 0x70, 0x28, 0x6b, 0x2c, 0x20, 0x76, 0x73, 0x29, 0x7c, 0x0a, 0x0a }; -unsigned int __lookup_hob_len = 1274; -unsigned char __maybe_hob[] = { +unsigned int _lookup_hob_len = 1274; +unsigned char _maybe_hob[] = { 0x2f, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x6d, 0x61, 0x79, 0x62, 0x65, 0x0a, 0x20, 0x2a, 0x2f, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x5b, 0x64, 0x6f, 0x63, 0x5d, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x73, @@ -5287,8 +5287,8 @@ unsigned char __maybe_hob[] = { 0x65, 0x6e, 0x75, 0x6d, 0x20, 0x3d, 0x20, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x43, 0x61, 0x73, 0x74, 0x0a, 0x0a }; -unsigned int __maybe_hob_len = 5203; -unsigned char __patterns_hob[] = { +unsigned int _maybe_hob_len = 5203; +unsigned char _patterns_hob[] = { 0x2f, 0x2a, 0x0a, 0x20, 0x20, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x63, 0x61, 0x73, 0x65, 0x73, 0x20, 0x6f, 0x66, @@ -5716,8 +5716,8 @@ unsigned char __patterns_hob[] = { 0x20, 0x78, 0x73, 0x20, 0x3d, 0x20, 0x6d, 0x66, 0x6c, 0x61, 0x74, 0x74, 0x65, 0x6e, 0x28, 0x78, 0x73, 0x5b, 0x30, 0x3a, 0x5d, 0x29, 0x0a, 0x0a }; -unsigned int __patterns_hob_len = 5112; -unsigned char __proccodec_hob[] = { +unsigned int _patterns_hob_len = 5112; +unsigned char _proccodec_hob[] = { 0x0a, 0x2f, 0x2f, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x72, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x77, 0x72, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x61, 0x6c, 0x75, @@ -6156,8 +6156,8 @@ unsigned char __proccodec_hob[] = { 0x73, 0x61, 0x66, 0x65, 0x43, 0x61, 0x73, 0x74, 0x28, 0x78, 0x29, 0x3a, 0x3a, 0x72, 0x29, 0x0a, 0x0a }; -unsigned int __proccodec_hob_len = 5237; -unsigned char __read_hob[] = { +unsigned int _proccodec_hob_len = 5237; +unsigned char _read_hob[] = { 0x2f, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x20, 0x64, 0x65, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x73, @@ -6254,8 +6254,8 @@ unsigned char __read_hob[] = { 0x22, 0x22, 0x29, 0x20, 0x7c, 0x20, 0x5f, 0x20, 0x2d, 0x3e, 0x20, 0x6e, 0x6f, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x0a, 0x0a }; -unsigned int __read_hob_len = 1136; -unsigned char __set_hob[] = { +unsigned int _read_hob_len = 1136; +unsigned char _set_hob[] = { 0x2f, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x73, 0x65, 0x74, 0x73, 0x0a, 0x20, 0x2a, 0x2f, 0x0a, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x53, 0x65, 0x74, 0x20, 0x61, 0x20, 0x73, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, @@ -6393,8 +6393,8 @@ unsigned char __set_hob[] = { 0x20, 0x69, 0x6e, 0x20, 0x78, 0x73, 0x20, 0x7c, 0x20, 0x5f, 0x20, 0x2d, 0x3e, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x0a, 0x0a }; -unsigned int __set_hob_len = 1629; -unsigned char __show_hob[] = { +unsigned int _set_hob_len = 1629; +unsigned char _show_hob[] = { 0x2f, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x64, 0x69, 0x73, 0x70, @@ -6629,496 +6629,500 @@ unsigned char __show_hob[] = { 0x20, 0x53, 0x68, 0x6f, 0x77, 0x20, 0x74, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x20, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x28, 0x75, 0x6e, 0x70, 0x61, 0x63, 0x6b, - 0x45, 0x6e, 0x75, 0x6d, 0x28, 0x65, 0x29, 0x29, 0x0a, 0x0a, 0x2f, 0x2f, - 0x20, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, - 0x73, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, - 0x41, 0x72, 0x72, 0x61, 0x79, 0x20, 0x63, 0x73, 0x20, 0x63, 0x68, 0x61, - 0x72, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x53, 0x68, 0x6f, 0x77, 0x20, 0x63, + 0x45, 0x6e, 0x75, 0x6d, 0x28, 0x65, 0x29, 0x29, 0x0a, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x53, 0x68, 0x6f, 0x77, 0x20, 0x28, + 0x28, 0x70, 0x65, 0x6e, 0x75, 0x6d, 0x20, 0x61, 0x20, 0x76, 0x29, 0x29, + 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x73, 0x68, 0x6f, + 0x77, 0x20, 0x3d, 0x20, 0x70, 0x65, 0x6e, 0x75, 0x6d, 0x53, 0x68, 0x6f, + 0x77, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, + 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x6f, 0x72, 0x20, + 0x61, 0x72, 0x72, 0x61, 0x79, 0x73, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x20, 0x28, 0x41, 0x72, 0x72, 0x61, 0x79, 0x20, 0x63, + 0x73, 0x20, 0x63, 0x68, 0x61, 0x72, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x53, + 0x68, 0x6f, 0x77, 0x20, 0x63, 0x73, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, + 0x0a, 0x20, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x20, 0x63, 0x73, 0x20, 0x3d, + 0x20, 0x73, 0x68, 0x6f, 0x77, 0x28, 0x63, 0x73, 0x5b, 0x30, 0x3a, 0x5d, + 0x29, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, + 0x41, 0x72, 0x72, 0x61, 0x79, 0x20, 0x62, 0x73, 0x20, 0x62, 0x79, 0x74, + 0x65, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x53, 0x68, 0x6f, 0x77, 0x20, 0x62, 0x73, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x73, 0x68, - 0x6f, 0x77, 0x20, 0x63, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x68, 0x6f, 0x77, - 0x28, 0x63, 0x73, 0x5b, 0x30, 0x3a, 0x5d, 0x29, 0x0a, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, 0x41, 0x72, 0x72, 0x61, 0x79, - 0x20, 0x62, 0x73, 0x20, 0x62, 0x79, 0x74, 0x65, 0x29, 0x20, 0x3d, 0x3e, - 0x20, 0x53, 0x68, 0x6f, 0x77, 0x20, 0x62, 0x73, 0x20, 0x77, 0x68, 0x65, - 0x72, 0x65, 0x0a, 0x20, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x20, 0x62, 0x73, - 0x20, 0x3d, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x28, 0x62, 0x73, 0x5b, 0x30, - 0x3a, 0x5d, 0x29, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x20, 0x28, 0x53, 0x68, 0x6f, 0x77, 0x20, 0x61, 0x29, 0x20, 0x3d, 0x3e, - 0x20, 0x53, 0x68, 0x6f, 0x77, 0x20, 0x5b, 0x61, 0x5d, 0x20, 0x77, 0x68, - 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x20, 0x78, - 0x73, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x5b, - 0x22, 0x5b, 0x22, 0x2c, 0x20, 0x63, 0x64, 0x65, 0x6c, 0x69, 0x6d, 0x28, - 0x6d, 0x61, 0x70, 0x28, 0x73, 0x68, 0x6f, 0x77, 0x2c, 0x78, 0x73, 0x29, - 0x2c, 0x20, 0x22, 0x2c, 0x20, 0x22, 0x29, 0x2c, 0x20, 0x22, 0x5d, 0x22, - 0x5d, 0x29, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, - 0x28, 0x41, 0x72, 0x72, 0x61, 0x79, 0x20, 0x61, 0x73, 0x20, 0x61, 0x2c, - 0x20, 0x53, 0x68, 0x6f, 0x77, 0x20, 0x61, 0x29, 0x20, 0x3d, 0x3e, 0x20, - 0x53, 0x68, 0x6f, 0x77, 0x20, 0x61, 0x73, 0x20, 0x77, 0x68, 0x65, 0x72, - 0x65, 0x0a, 0x20, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x20, 0x78, 0x73, 0x20, - 0x3d, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x28, 0x78, 0x73, 0x5b, 0x30, 0x3a, - 0x5d, 0x29, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x73, 0x65, 0x72, 0x69, 0x61, - 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x6f, 0x72, - 0x20, 0x66, 0x69, 0x78, 0x65, 0x64, 0x2d, 0x6c, 0x65, 0x6e, 0x67, 0x74, - 0x68, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x73, 0x0a, 0x63, 0x6c, 0x61, - 0x73, 0x73, 0x20, 0x53, 0x68, 0x6f, 0x77, 0x46, 0x69, 0x78, 0x65, 0x64, - 0x41, 0x72, 0x72, 0x4f, 0x66, 0x20, 0x65, 0x20, 0x6e, 0x20, 0x77, 0x68, - 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x46, 0x41, - 0x20, 0x3a, 0x3a, 0x20, 0x28, 0x5b, 0x3a, 0x65, 0x7c, 0x6e, 0x3a, 0x5d, - 0x2c, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x2c, 0x20, 0x6c, 0x6f, 0x6e, 0x67, - 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x5b, 0x63, 0x68, 0x61, 0x72, 0x5d, 0x0a, - 0x0a, 0x66, 0x69, 0x78, 0x65, 0x64, 0x43, 0x41, 0x54, 0x6f, 0x53, 0x74, - 0x72, 0x20, 0x3a, 0x3a, 0x20, 0x28, 0x5b, 0x3a, 0x63, 0x68, 0x61, 0x72, - 0x7c, 0x6e, 0x3a, 0x5d, 0x2c, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x2c, 0x20, - 0x6c, 0x6f, 0x6e, 0x67, 0x2c, 0x20, 0x5b, 0x63, 0x68, 0x61, 0x72, 0x5d, - 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x5b, 0x63, 0x68, 0x61, 0x72, 0x5d, 0x0a, - 0x66, 0x69, 0x78, 0x65, 0x64, 0x43, 0x41, 0x54, 0x6f, 0x53, 0x74, 0x72, - 0x20, 0x63, 0x73, 0x20, 0x69, 0x20, 0x65, 0x20, 0x72, 0x20, 0x3d, 0x0a, - 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x69, 0x20, 0x3d, 0x3d, 0x20, 0x65, - 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, - 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x20, 0x28, - 0x73, 0x61, 0x65, 0x6c, 0x65, 0x6d, 0x28, 0x63, 0x73, 0x2c, 0x20, 0x69, - 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x5c, 0x30, 0x27, 0x29, 0x20, 0x74, - 0x68, 0x65, 0x6e, 0x20, 0x64, 0x6f, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x53, 0x65, 0x74, 0x4c, 0x65, - 0x6e, 0x67, 0x74, 0x68, 0x28, 0x72, 0x2c, 0x20, 0x69, 0x29, 0x3b, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, - 0x0a, 0x20, 0x20, 0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x64, 0x6f, - 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x5b, 0x69, 0x5d, 0x20, - 0x3c, 0x2d, 0x20, 0x73, 0x61, 0x65, 0x6c, 0x65, 0x6d, 0x28, 0x63, 0x73, - 0x2c, 0x20, 0x69, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, - 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x69, 0x78, 0x65, 0x64, 0x43, 0x41, - 0x54, 0x6f, 0x53, 0x74, 0x72, 0x28, 0x63, 0x73, 0x2c, 0x20, 0x69, 0x2b, - 0x31, 0x2c, 0x20, 0x65, 0x2c, 0x20, 0x72, 0x29, 0x0a, 0x20, 0x20, 0x7d, - 0x0a, 0x7b, 0x2d, 0x23, 0x20, 0x55, 0x4e, 0x53, 0x41, 0x46, 0x45, 0x20, - 0x66, 0x69, 0x78, 0x65, 0x64, 0x43, 0x41, 0x54, 0x6f, 0x53, 0x74, 0x72, - 0x20, 0x23, 0x2d, 0x7d, 0x0a, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x20, 0x53, 0x68, 0x6f, 0x77, 0x46, 0x69, 0x78, 0x65, 0x64, - 0x41, 0x72, 0x72, 0x4f, 0x66, 0x20, 0x63, 0x68, 0x61, 0x72, 0x20, 0x6e, + 0x6f, 0x77, 0x20, 0x62, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x68, 0x6f, 0x77, + 0x28, 0x62, 0x73, 0x5b, 0x30, 0x3a, 0x5d, 0x29, 0x0a, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, 0x53, 0x68, 0x6f, 0x77, 0x20, + 0x61, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x53, 0x68, 0x6f, 0x77, 0x20, 0x5b, + 0x61, 0x5d, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x73, + 0x68, 0x6f, 0x77, 0x20, 0x78, 0x73, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, + 0x63, 0x61, 0x74, 0x28, 0x5b, 0x22, 0x5b, 0x22, 0x2c, 0x20, 0x63, 0x64, + 0x65, 0x6c, 0x69, 0x6d, 0x28, 0x6d, 0x61, 0x70, 0x28, 0x73, 0x68, 0x6f, + 0x77, 0x2c, 0x78, 0x73, 0x29, 0x2c, 0x20, 0x22, 0x2c, 0x20, 0x22, 0x29, + 0x2c, 0x20, 0x22, 0x5d, 0x22, 0x5d, 0x29, 0x0a, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, 0x41, 0x72, 0x72, 0x61, 0x79, 0x20, + 0x61, 0x73, 0x20, 0x61, 0x2c, 0x20, 0x53, 0x68, 0x6f, 0x77, 0x20, 0x61, + 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x53, 0x68, 0x6f, 0x77, 0x20, 0x61, 0x73, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x73, 0x68, 0x6f, - 0x77, 0x46, 0x41, 0x20, 0x63, 0x73, 0x20, 0x69, 0x20, 0x65, 0x20, 0x3d, - 0x20, 0x22, 0x5c, 0x22, 0x22, 0x20, 0x2b, 0x2b, 0x20, 0x66, 0x69, 0x78, - 0x65, 0x64, 0x43, 0x41, 0x54, 0x6f, 0x53, 0x74, 0x72, 0x28, 0x63, 0x73, - 0x2c, 0x20, 0x69, 0x2c, 0x20, 0x65, 0x2c, 0x20, 0x6e, 0x65, 0x77, 0x41, - 0x72, 0x72, 0x61, 0x79, 0x28, 0x65, 0x29, 0x29, 0x20, 0x2b, 0x2b, 0x20, - 0x22, 0x5c, 0x22, 0x22, 0x0a, 0x0a, 0x73, 0x68, 0x6f, 0x77, 0x53, 0x41, - 0x52, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x3a, 0x3a, 0x20, 0x28, 0x61, 0x20, - 0x2d, 0x3e, 0x20, 0x5b, 0x63, 0x68, 0x61, 0x72, 0x5d, 0x2c, 0x20, 0x5b, - 0x3a, 0x61, 0x7c, 0x6e, 0x3a, 0x5d, 0x2c, 0x20, 0x6c, 0x6f, 0x6e, 0x67, - 0x2c, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x2c, 0x20, 0x5b, 0x5b, 0x63, 0x68, - 0x61, 0x72, 0x5d, 0x5d, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x5b, 0x5b, 0x63, - 0x68, 0x61, 0x72, 0x5d, 0x5d, 0x0a, 0x73, 0x68, 0x6f, 0x77, 0x53, 0x41, - 0x52, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x66, 0x20, - 0x78, 0x73, 0x20, 0x69, 0x20, 0x65, 0x20, 0x72, 0x20, 0x3d, 0x0a, 0x20, - 0x20, 0x69, 0x66, 0x20, 0x28, 0x69, 0x20, 0x3d, 0x3d, 0x20, 0x65, 0x29, - 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x0a, - 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x20, 0x7b, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x72, 0x5b, 0x69, 0x5d, 0x20, 0x3c, 0x2d, 0x20, - 0x73, 0x68, 0x6f, 0x77, 0x66, 0x28, 0x73, 0x61, 0x65, 0x6c, 0x65, 0x6d, - 0x28, 0x78, 0x73, 0x2c, 0x20, 0x69, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x68, 0x6f, - 0x77, 0x53, 0x41, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x28, 0x73, 0x68, 0x6f, - 0x77, 0x66, 0x2c, 0x20, 0x78, 0x73, 0x2c, 0x20, 0x69, 0x2b, 0x31, 0x2c, - 0x20, 0x65, 0x2c, 0x20, 0x72, 0x29, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x7b, - 0x2d, 0x23, 0x20, 0x55, 0x4e, 0x53, 0x41, 0x46, 0x45, 0x20, 0x73, 0x68, - 0x6f, 0x77, 0x53, 0x41, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x23, 0x2d, - 0x7d, 0x0a, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, - 0x53, 0x68, 0x6f, 0x77, 0x46, 0x69, 0x78, 0x65, 0x64, 0x41, 0x72, 0x72, - 0x4f, 0x66, 0x20, 0x62, 0x79, 0x74, 0x65, 0x20, 0x6e, 0x20, 0x77, 0x68, + 0x77, 0x20, 0x78, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x28, + 0x78, 0x73, 0x5b, 0x30, 0x3a, 0x5d, 0x29, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, + 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x66, 0x69, 0x78, 0x65, 0x64, 0x2d, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, + 0x73, 0x0a, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x53, 0x68, 0x6f, 0x77, + 0x46, 0x69, 0x78, 0x65, 0x64, 0x41, 0x72, 0x72, 0x4f, 0x66, 0x20, 0x65, + 0x20, 0x6e, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x73, + 0x68, 0x6f, 0x77, 0x46, 0x41, 0x20, 0x3a, 0x3a, 0x20, 0x28, 0x5b, 0x3a, + 0x65, 0x7c, 0x6e, 0x3a, 0x5d, 0x2c, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x2c, + 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x5b, 0x63, + 0x68, 0x61, 0x72, 0x5d, 0x0a, 0x0a, 0x66, 0x69, 0x78, 0x65, 0x64, 0x43, + 0x41, 0x54, 0x6f, 0x53, 0x74, 0x72, 0x20, 0x3a, 0x3a, 0x20, 0x28, 0x5b, + 0x3a, 0x63, 0x68, 0x61, 0x72, 0x7c, 0x6e, 0x3a, 0x5d, 0x2c, 0x20, 0x6c, + 0x6f, 0x6e, 0x67, 0x2c, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x2c, 0x20, 0x5b, + 0x63, 0x68, 0x61, 0x72, 0x5d, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x5b, 0x63, + 0x68, 0x61, 0x72, 0x5d, 0x0a, 0x66, 0x69, 0x78, 0x65, 0x64, 0x43, 0x41, + 0x54, 0x6f, 0x53, 0x74, 0x72, 0x20, 0x63, 0x73, 0x20, 0x69, 0x20, 0x65, + 0x20, 0x72, 0x20, 0x3d, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x69, + 0x20, 0x3d, 0x3d, 0x20, 0x65, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x72, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, + 0x20, 0x69, 0x66, 0x20, 0x28, 0x73, 0x61, 0x65, 0x6c, 0x65, 0x6d, 0x28, + 0x63, 0x73, 0x2c, 0x20, 0x69, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x5c, + 0x30, 0x27, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x64, 0x6f, 0x20, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, + 0x53, 0x65, 0x74, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, 0x72, 0x2c, + 0x20, 0x69, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x72, 0x0a, 0x20, 0x20, 0x7d, 0x20, 0x65, 0x6c, + 0x73, 0x65, 0x20, 0x64, 0x6f, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x72, 0x5b, 0x69, 0x5d, 0x20, 0x3c, 0x2d, 0x20, 0x73, 0x61, 0x65, 0x6c, + 0x65, 0x6d, 0x28, 0x63, 0x73, 0x2c, 0x20, 0x69, 0x29, 0x3b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x69, + 0x78, 0x65, 0x64, 0x43, 0x41, 0x54, 0x6f, 0x53, 0x74, 0x72, 0x28, 0x63, + 0x73, 0x2c, 0x20, 0x69, 0x2b, 0x31, 0x2c, 0x20, 0x65, 0x2c, 0x20, 0x72, + 0x29, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x7b, 0x2d, 0x23, 0x20, 0x55, 0x4e, + 0x53, 0x41, 0x46, 0x45, 0x20, 0x66, 0x69, 0x78, 0x65, 0x64, 0x43, 0x41, + 0x54, 0x6f, 0x53, 0x74, 0x72, 0x20, 0x23, 0x2d, 0x7d, 0x0a, 0x0a, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x53, 0x68, 0x6f, 0x77, + 0x46, 0x69, 0x78, 0x65, 0x64, 0x41, 0x72, 0x72, 0x4f, 0x66, 0x20, 0x63, + 0x68, 0x61, 0x72, 0x20, 0x6e, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, + 0x20, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x46, 0x41, 0x20, 0x63, 0x73, 0x20, + 0x69, 0x20, 0x65, 0x20, 0x3d, 0x20, 0x22, 0x5c, 0x22, 0x22, 0x20, 0x2b, + 0x2b, 0x20, 0x66, 0x69, 0x78, 0x65, 0x64, 0x43, 0x41, 0x54, 0x6f, 0x53, + 0x74, 0x72, 0x28, 0x63, 0x73, 0x2c, 0x20, 0x69, 0x2c, 0x20, 0x65, 0x2c, + 0x20, 0x6e, 0x65, 0x77, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, 0x65, 0x29, + 0x29, 0x20, 0x2b, 0x2b, 0x20, 0x22, 0x5c, 0x22, 0x22, 0x0a, 0x0a, 0x73, + 0x68, 0x6f, 0x77, 0x53, 0x41, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x3a, + 0x3a, 0x20, 0x28, 0x61, 0x20, 0x2d, 0x3e, 0x20, 0x5b, 0x63, 0x68, 0x61, + 0x72, 0x5d, 0x2c, 0x20, 0x5b, 0x3a, 0x61, 0x7c, 0x6e, 0x3a, 0x5d, 0x2c, + 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x2c, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x2c, + 0x20, 0x5b, 0x5b, 0x63, 0x68, 0x61, 0x72, 0x5d, 0x5d, 0x29, 0x20, 0x2d, + 0x3e, 0x20, 0x5b, 0x5b, 0x63, 0x68, 0x61, 0x72, 0x5d, 0x5d, 0x0a, 0x73, + 0x68, 0x6f, 0x77, 0x53, 0x41, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x73, + 0x68, 0x6f, 0x77, 0x66, 0x20, 0x78, 0x73, 0x20, 0x69, 0x20, 0x65, 0x20, + 0x72, 0x20, 0x3d, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x69, 0x20, + 0x3d, 0x3d, 0x20, 0x65, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x72, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, + 0x64, 0x6f, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x5b, 0x69, + 0x5d, 0x20, 0x3c, 0x2d, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x66, 0x28, 0x73, + 0x61, 0x65, 0x6c, 0x65, 0x6d, 0x28, 0x78, 0x73, 0x2c, 0x20, 0x69, 0x29, + 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x53, 0x41, 0x52, 0x61, 0x6e, 0x67, + 0x65, 0x28, 0x73, 0x68, 0x6f, 0x77, 0x66, 0x2c, 0x20, 0x78, 0x73, 0x2c, + 0x20, 0x69, 0x2b, 0x31, 0x2c, 0x20, 0x65, 0x2c, 0x20, 0x72, 0x29, 0x0a, + 0x20, 0x20, 0x7d, 0x0a, 0x7b, 0x2d, 0x23, 0x20, 0x55, 0x4e, 0x53, 0x41, + 0x46, 0x45, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x53, 0x41, 0x52, 0x61, 0x6e, + 0x67, 0x65, 0x20, 0x23, 0x2d, 0x7d, 0x0a, 0x0a, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x20, 0x53, 0x68, 0x6f, 0x77, 0x46, 0x69, 0x78, + 0x65, 0x64, 0x41, 0x72, 0x72, 0x4f, 0x66, 0x20, 0x62, 0x79, 0x74, 0x65, + 0x20, 0x6e, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x73, + 0x68, 0x6f, 0x77, 0x46, 0x41, 0x20, 0x62, 0x73, 0x20, 0x69, 0x20, 0x65, + 0x20, 0x3d, 0x20, 0x22, 0x30, 0x78, 0x22, 0x20, 0x2b, 0x2b, 0x20, 0x63, + 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x73, 0x68, 0x6f, 0x77, 0x53, 0x41, + 0x52, 0x61, 0x6e, 0x67, 0x65, 0x28, 0x73, 0x68, 0x6f, 0x77, 0x42, 0x79, + 0x74, 0x65, 0x56, 0x2c, 0x20, 0x62, 0x73, 0x2c, 0x20, 0x69, 0x2c, 0x20, + 0x65, 0x2c, 0x20, 0x6e, 0x65, 0x77, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, + 0x65, 0x29, 0x29, 0x29, 0x0a, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x20, 0x28, 0x53, 0x68, 0x6f, 0x77, 0x20, 0x61, 0x29, 0x20, + 0x3d, 0x3e, 0x20, 0x53, 0x68, 0x6f, 0x77, 0x46, 0x69, 0x78, 0x65, 0x64, + 0x41, 0x72, 0x72, 0x4f, 0x66, 0x20, 0x61, 0x20, 0x6e, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x46, 0x41, - 0x20, 0x62, 0x73, 0x20, 0x69, 0x20, 0x65, 0x20, 0x3d, 0x20, 0x22, 0x30, - 0x78, 0x22, 0x20, 0x2b, 0x2b, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, - 0x28, 0x73, 0x68, 0x6f, 0x77, 0x53, 0x41, 0x52, 0x61, 0x6e, 0x67, 0x65, - 0x28, 0x73, 0x68, 0x6f, 0x77, 0x42, 0x79, 0x74, 0x65, 0x56, 0x2c, 0x20, - 0x62, 0x73, 0x2c, 0x20, 0x69, 0x2c, 0x20, 0x65, 0x2c, 0x20, 0x6e, 0x65, - 0x77, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, 0x65, 0x29, 0x29, 0x29, 0x0a, - 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, 0x53, - 0x68, 0x6f, 0x77, 0x20, 0x61, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x53, 0x68, - 0x6f, 0x77, 0x46, 0x69, 0x78, 0x65, 0x64, 0x41, 0x72, 0x72, 0x4f, 0x66, - 0x20, 0x61, 0x20, 0x6e, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, - 0x20, 0x73, 0x68, 0x6f, 0x77, 0x46, 0x41, 0x20, 0x63, 0x73, 0x20, 0x69, - 0x20, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, - 0x5b, 0x22, 0x5b, 0x3a, 0x22, 0x2c, 0x20, 0x63, 0x64, 0x65, 0x6c, 0x69, - 0x6d, 0x28, 0x73, 0x68, 0x6f, 0x77, 0x53, 0x41, 0x52, 0x61, 0x6e, 0x67, - 0x65, 0x28, 0x73, 0x68, 0x6f, 0x77, 0x2c, 0x20, 0x63, 0x73, 0x2c, 0x20, - 0x69, 0x2c, 0x20, 0x65, 0x2c, 0x20, 0x6e, 0x65, 0x77, 0x41, 0x72, 0x72, - 0x61, 0x79, 0x28, 0x65, 0x29, 0x29, 0x2c, 0x20, 0x22, 0x2c, 0x20, 0x22, - 0x29, 0x2c, 0x20, 0x22, 0x3a, 0x5d, 0x22, 0x5d, 0x29, 0x0a, 0x0a, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, 0x53, 0x68, 0x6f, - 0x77, 0x46, 0x69, 0x78, 0x65, 0x64, 0x41, 0x72, 0x72, 0x4f, 0x66, 0x20, - 0x61, 0x20, 0x6e, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x53, 0x68, 0x6f, 0x77, - 0x20, 0x5b, 0x3a, 0x61, 0x7c, 0x6e, 0x3a, 0x5d, 0x20, 0x77, 0x68, 0x65, - 0x72, 0x65, 0x0a, 0x20, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x20, 0x78, 0x73, - 0x20, 0x3d, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x46, 0x41, 0x28, 0x78, 0x73, - 0x2c, 0x20, 0x30, 0x4c, 0x2c, 0x20, 0x73, 0x61, 0x6c, 0x65, 0x6e, 0x67, - 0x74, 0x68, 0x28, 0x78, 0x73, 0x29, 0x29, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, - 0x73, 0x68, 0x6f, 0x77, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x73, 0x0a, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, 0x53, 0x68, 0x6f, - 0x77, 0x20, 0x61, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x53, 0x68, 0x6f, 0x77, - 0x20, 0x28, 0x5e, 0x78, 0x2e, 0x28, 0x28, 0x29, 0x2b, 0x28, 0x61, 0x2a, - 0x78, 0x29, 0x29, 0x29, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, - 0x20, 0x73, 0x68, 0x6f, 0x77, 0x20, 0x78, 0x73, 0x20, 0x3d, 0x20, 0x63, - 0x61, 0x73, 0x65, 0x20, 0x75, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x28, 0x78, - 0x73, 0x29, 0x20, 0x6f, 0x66, 0x20, 0x7c, 0x30, 0x3a, 0x5f, 0x3d, 0x22, - 0x5b, 0x5d, 0x22, 0x2c, 0x20, 0x31, 0x3a, 0x70, 0x3d, 0x73, 0x68, 0x6f, - 0x77, 0x28, 0x70, 0x2e, 0x30, 0x29, 0x2b, 0x2b, 0x22, 0x3a, 0x22, 0x2b, - 0x2b, 0x73, 0x68, 0x6f, 0x77, 0x28, 0x70, 0x2e, 0x31, 0x29, 0x7c, 0x0a, - 0x0a, 0x2f, 0x2f, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x20, 0x72, 0x65, 0x63, - 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x69, 0x72, 0x20, 0x6f, 0x6e, - 0x65, 0x2d, 0x73, 0x74, 0x65, 0x70, 0x20, 0x75, 0x6e, 0x72, 0x6f, 0x6c, - 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x73, 0x20, 0x73, 0x68, 0x6f, 0x77, - 0x61, 0x62, 0x6c, 0x65, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x20, 0x28, 0x61, 0x20, 0x7e, 0x20, 0x62, 0x2c, 0x20, 0x53, 0x68, - 0x6f, 0x77, 0x20, 0x62, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x53, 0x68, 0x6f, - 0x77, 0x20, 0x61, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, - 0x73, 0x68, 0x6f, 0x77, 0x20, 0x78, 0x20, 0x3d, 0x20, 0x73, 0x68, 0x6f, - 0x77, 0x28, 0x75, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x28, 0x78, 0x29, 0x29, - 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x20, 0x74, 0x68, - 0x72, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x72, - 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x0a, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, 0x53, 0x68, 0x6f, 0x77, - 0x20, 0x61, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x53, 0x68, 0x6f, 0x77, 0x20, - 0x61, 0x40, 0x66, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, - 0x73, 0x68, 0x6f, 0x77, 0x20, 0x78, 0x20, 0x3d, 0x20, 0x73, 0x68, 0x6f, - 0x77, 0x28, 0x6c, 0x6f, 0x61, 0x64, 0x28, 0x78, 0x29, 0x29, 0x0a, 0x0a, - 0x2f, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, - 0x63, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x0a, 0x20, - 0x2a, 0x2f, 0x0a, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x50, 0x72, 0x69, - 0x6e, 0x74, 0x20, 0x61, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, - 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x3a, 0x3a, 0x20, 0x61, 0x20, - 0x2d, 0x3e, 0x20, 0x28, 0x29, 0x0a, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x28, 0x29, - 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, - 0x6e, 0x74, 0x20, 0x5f, 0x20, 0x3d, 0x20, 0x28, 0x29, 0x0a, 0x0a, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x50, 0x72, 0x69, 0x6e, - 0x74, 0x20, 0x5b, 0x62, 0x79, 0x74, 0x65, 0x5d, 0x20, 0x77, 0x68, 0x65, - 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x62, - 0x73, 0x20, 0x3d, 0x20, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x73, - 0x68, 0x6f, 0x77, 0x28, 0x62, 0x73, 0x29, 0x29, 0x0a, 0x0a, 0x2f, 0x2f, - 0x20, 0x77, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x6c, 0x61, 0x74, - 0x65, 0x72, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x68, 0x6f, - 0x77, 0x20, 0x63, 0x65, 0x72, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x62, 0x65, 0x20, 0x70, - 0x72, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x73, 0x0a, 0x2f, 0x2f, 0x20, 0x61, 0x74, 0x20, 0x6c, - 0x65, 0x61, 0x73, 0x74, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, - 0x74, 0x68, 0x6f, 0x73, 0x65, 0x20, 0x63, 0x61, 0x73, 0x65, 0x73, 0x20, - 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x61, 0x70, - 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x73, - 0x2c, 0x20, 0x73, 0x6f, 0x20, 0x77, 0x65, 0x20, 0x6e, 0x65, 0x65, 0x64, - 0x20, 0x74, 0x6f, 0x20, 0x74, 0x72, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x70, - 0x72, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x73, 0x20, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x73, 0x20, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x20, 0x74, 0x6f, 0x20, - 0x74, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, - 0x69, 0x6e, 0x74, 0x20, 0x61, 0x73, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, - 0x73, 0x0a, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x50, 0x72, 0x69, 0x6e, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x73, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x20, 0x61, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, - 0x72, 0x69, 0x6e, 0x74, 0x41, 0x73, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x20, + 0x20, 0x63, 0x73, 0x20, 0x69, 0x20, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, + 0x6e, 0x63, 0x61, 0x74, 0x28, 0x5b, 0x22, 0x5b, 0x3a, 0x22, 0x2c, 0x20, + 0x63, 0x64, 0x65, 0x6c, 0x69, 0x6d, 0x28, 0x73, 0x68, 0x6f, 0x77, 0x53, + 0x41, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x28, 0x73, 0x68, 0x6f, 0x77, 0x2c, + 0x20, 0x63, 0x73, 0x2c, 0x20, 0x69, 0x2c, 0x20, 0x65, 0x2c, 0x20, 0x6e, + 0x65, 0x77, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, 0x65, 0x29, 0x29, 0x2c, + 0x20, 0x22, 0x2c, 0x20, 0x22, 0x29, 0x2c, 0x20, 0x22, 0x3a, 0x5d, 0x22, + 0x5d, 0x29, 0x0a, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x20, 0x28, 0x53, 0x68, 0x6f, 0x77, 0x46, 0x69, 0x78, 0x65, 0x64, 0x41, + 0x72, 0x72, 0x4f, 0x66, 0x20, 0x61, 0x20, 0x6e, 0x29, 0x20, 0x3d, 0x3e, + 0x20, 0x53, 0x68, 0x6f, 0x77, 0x20, 0x5b, 0x3a, 0x61, 0x7c, 0x6e, 0x3a, + 0x5d, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x73, 0x68, + 0x6f, 0x77, 0x20, 0x78, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x68, 0x6f, 0x77, + 0x46, 0x41, 0x28, 0x78, 0x73, 0x2c, 0x20, 0x30, 0x4c, 0x2c, 0x20, 0x73, + 0x61, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, 0x78, 0x73, 0x29, 0x29, + 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x20, 0x6c, 0x69, + 0x73, 0x74, 0x73, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x20, 0x28, 0x53, 0x68, 0x6f, 0x77, 0x20, 0x61, 0x29, 0x20, 0x3d, 0x3e, + 0x20, 0x53, 0x68, 0x6f, 0x77, 0x20, 0x28, 0x5e, 0x78, 0x2e, 0x28, 0x28, + 0x29, 0x2b, 0x28, 0x61, 0x2a, 0x78, 0x29, 0x29, 0x29, 0x20, 0x77, 0x68, + 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x20, 0x78, + 0x73, 0x20, 0x3d, 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x75, 0x6e, 0x72, + 0x6f, 0x6c, 0x6c, 0x28, 0x78, 0x73, 0x29, 0x20, 0x6f, 0x66, 0x20, 0x7c, + 0x30, 0x3a, 0x5f, 0x3d, 0x22, 0x5b, 0x5d, 0x22, 0x2c, 0x20, 0x31, 0x3a, + 0x70, 0x3d, 0x73, 0x68, 0x6f, 0x77, 0x28, 0x70, 0x2e, 0x30, 0x29, 0x2b, + 0x2b, 0x22, 0x3a, 0x22, 0x2b, 0x2b, 0x73, 0x68, 0x6f, 0x77, 0x28, 0x70, + 0x2e, 0x31, 0x29, 0x7c, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x73, 0x68, 0x6f, + 0x77, 0x20, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, + 0x69, 0x72, 0x20, 0x6f, 0x6e, 0x65, 0x2d, 0x73, 0x74, 0x65, 0x70, 0x20, + 0x75, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x73, + 0x20, 0x73, 0x68, 0x6f, 0x77, 0x61, 0x62, 0x6c, 0x65, 0x0a, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, 0x61, 0x20, 0x7e, 0x20, + 0x62, 0x2c, 0x20, 0x53, 0x68, 0x6f, 0x77, 0x20, 0x62, 0x29, 0x20, 0x3d, + 0x3e, 0x20, 0x53, 0x68, 0x6f, 0x77, 0x20, 0x61, 0x20, 0x77, 0x68, 0x65, + 0x72, 0x65, 0x0a, 0x20, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x20, 0x78, 0x20, + 0x3d, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x28, 0x75, 0x6e, 0x72, 0x6f, 0x6c, + 0x6c, 0x28, 0x78, 0x29, 0x29, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x73, 0x68, + 0x6f, 0x77, 0x20, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x20, 0x66, + 0x69, 0x6c, 0x65, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x73, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, + 0x28, 0x53, 0x68, 0x6f, 0x77, 0x20, 0x61, 0x29, 0x20, 0x3d, 0x3e, 0x20, + 0x53, 0x68, 0x6f, 0x77, 0x20, 0x61, 0x40, 0x66, 0x20, 0x77, 0x68, 0x65, + 0x72, 0x65, 0x0a, 0x20, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x20, 0x78, 0x20, + 0x3d, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x28, 0x6c, 0x6f, 0x61, 0x64, 0x28, + 0x78, 0x29, 0x29, 0x0a, 0x0a, 0x2f, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x69, 0x6e, 0x67, 0x0a, 0x20, 0x2a, 0x2f, 0x0a, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x20, 0x77, 0x68, + 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x3a, 0x3a, 0x20, 0x61, 0x20, 0x2d, 0x3e, 0x20, 0x28, 0x29, 0x0a, 0x0a, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, 0x50, 0x72, - 0x69, 0x6e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x73, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x20, 0x61, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x50, 0x72, 0x69, - 0x6e, 0x74, 0x20, 0x61, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, - 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x70, 0x72, 0x69, - 0x6e, 0x74, 0x41, 0x73, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x0a, 0x0a, 0x2f, - 0x2f, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x72, 0x72, 0x61, - 0x79, 0x73, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, - 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x5b, 0x63, 0x68, 0x61, 0x72, 0x5d, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x50, 0x72, 0x69, + 0x6e, 0x74, 0x20, 0x28, 0x29, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, + 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x5f, 0x20, 0x3d, 0x20, + 0x28, 0x29, 0x0a, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x5b, 0x62, 0x79, 0x74, 0x65, + 0x5d, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x20, 0x62, 0x73, 0x20, 0x3d, 0x20, 0x70, 0x75, 0x74, + 0x53, 0x74, 0x72, 0x28, 0x73, 0x68, 0x6f, 0x77, 0x28, 0x62, 0x73, 0x29, + 0x29, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x77, 0x65, 0x20, 0x77, 0x69, 0x6c, + 0x6c, 0x20, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x20, 0x64, 0x65, 0x66, 0x69, + 0x6e, 0x65, 0x20, 0x68, 0x6f, 0x77, 0x20, 0x63, 0x65, 0x72, 0x74, 0x61, + 0x69, 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x20, 0x63, 0x61, 0x6e, + 0x20, 0x62, 0x65, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x20, + 0x61, 0x73, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x0a, 0x2f, 0x2f, + 0x20, 0x61, 0x74, 0x20, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x20, 0x6f, 0x6e, + 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x6f, 0x73, 0x65, 0x20, 0x63, + 0x61, 0x73, 0x65, 0x73, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x6f, 0x76, + 0x65, 0x72, 0x6c, 0x61, 0x70, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, + 0x72, 0x72, 0x61, 0x79, 0x73, 0x2c, 0x20, 0x73, 0x6f, 0x20, 0x77, 0x65, + 0x20, 0x6e, 0x65, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x72, 0x79, + 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x73, + 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x20, 0x70, 0x72, 0x69, 0x6f, + 0x72, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, + 0x74, 0x6f, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x73, 0x20, + 0x61, 0x72, 0x72, 0x61, 0x79, 0x73, 0x0a, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x73, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x20, 0x77, 0x68, 0x65, 0x72, + 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x41, 0x73, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x20, 0x3a, 0x3a, 0x20, 0x61, 0x20, 0x2d, 0x3e, + 0x20, 0x28, 0x29, 0x0a, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x20, 0x28, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x41, 0x73, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x29, 0x20, 0x3d, + 0x3e, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x20, 0x77, 0x68, + 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, + 0x3d, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x41, 0x73, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x73, 0x0a, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x5b, + 0x63, 0x68, 0x61, 0x72, 0x5d, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, + 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x63, 0x73, 0x20, 0x3d, + 0x20, 0x64, 0x6f, 0x20, 0x7b, 0x20, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, + 0x28, 0x22, 0x5c, 0x22, 0x22, 0x29, 0x3b, 0x20, 0x70, 0x75, 0x74, 0x53, + 0x74, 0x72, 0x28, 0x63, 0x73, 0x29, 0x3b, 0x20, 0x70, 0x75, 0x74, 0x53, + 0x74, 0x72, 0x28, 0x22, 0x5c, 0x22, 0x22, 0x29, 0x3b, 0x20, 0x7d, 0x0a, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, 0x41, 0x72, + 0x72, 0x61, 0x79, 0x20, 0x63, 0x73, 0x20, 0x63, 0x68, 0x61, 0x72, 0x29, + 0x20, 0x3d, 0x3e, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x63, 0x73, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, - 0x6e, 0x74, 0x20, 0x63, 0x73, 0x20, 0x3d, 0x20, 0x64, 0x6f, 0x20, 0x7b, - 0x20, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x22, 0x5c, 0x22, 0x22, - 0x29, 0x3b, 0x20, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x63, 0x73, - 0x29, 0x3b, 0x20, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x22, 0x5c, - 0x22, 0x22, 0x29, 0x3b, 0x20, 0x7d, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x20, 0x28, 0x41, 0x72, 0x72, 0x61, 0x79, 0x20, 0x63, - 0x73, 0x20, 0x63, 0x68, 0x61, 0x72, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x50, - 0x72, 0x69, 0x6e, 0x74, 0x20, 0x63, 0x73, 0x20, 0x77, 0x68, 0x65, 0x72, - 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x63, 0x73, - 0x20, 0x3d, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x63, 0x73, 0x5b, - 0x30, 0x3a, 0x5d, 0x29, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x20, 0x28, 0x41, 0x72, 0x72, 0x61, 0x79, 0x20, 0x62, 0x73, 0x20, - 0x62, 0x79, 0x74, 0x65, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x50, 0x72, 0x69, - 0x6e, 0x74, 0x20, 0x62, 0x73, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, - 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x62, 0x73, 0x20, 0x3d, - 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x62, 0x73, 0x5b, 0x30, 0x3a, - 0x5d, 0x29, 0x0a, 0x0a, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x41, 0x72, 0x72, - 0x61, 0x79, 0x20, 0x3a, 0x3a, 0x20, 0x28, 0x50, 0x72, 0x69, 0x6e, 0x74, - 0x20, 0x61, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x28, 0x5b, 0x61, 0x5d, 0x2c, - 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x28, 0x29, - 0x0a, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x41, 0x72, 0x72, 0x61, 0x79, 0x20, - 0x78, 0x73, 0x20, 0x69, 0x20, 0x3d, 0x0a, 0x20, 0x20, 0x69, 0x66, 0x20, - 0x28, 0x69, 0x20, 0x3d, 0x3d, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, - 0x28, 0x78, 0x73, 0x29, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x28, 0x29, 0x0a, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x20, 0x7b, 0x20, 0x70, 0x75, - 0x74, 0x53, 0x74, 0x72, 0x28, 0x22, 0x2c, 0x20, 0x22, 0x29, 0x3b, 0x20, - 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x78, 0x73, 0x5b, 0x69, 0x5d, 0x29, - 0x3b, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x41, 0x72, 0x72, 0x61, 0x79, - 0x28, 0x78, 0x73, 0x2c, 0x20, 0x69, 0x2b, 0x31, 0x4c, 0x29, 0x3b, 0x20, - 0x7d, 0x0a, 0x7b, 0x2d, 0x23, 0x20, 0x55, 0x4e, 0x53, 0x41, 0x46, 0x45, - 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x41, 0x72, 0x72, 0x61, 0x79, 0x20, - 0x23, 0x2d, 0x7d, 0x0a, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x20, 0x28, 0x41, 0x72, 0x72, 0x61, 0x79, 0x20, 0x61, 0x73, 0x20, - 0x61, 0x2c, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x29, 0x20, - 0x3d, 0x3e, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x73, 0x20, - 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, - 0x74, 0x20, 0x78, 0x73, 0x20, 0x3d, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6e, - 0x3d, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x78, 0x73, 0x29, 0x20, 0x69, 0x6e, - 0x20, 0x69, 0x66, 0x20, 0x28, 0x6e, 0x3d, 0x3d, 0x30, 0x29, 0x20, 0x74, - 0x68, 0x65, 0x6e, 0x20, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x22, - 0x5b, 0x5d, 0x22, 0x29, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x64, 0x6f, - 0x20, 0x7b, 0x20, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x22, 0x5b, - 0x22, 0x29, 0x3b, 0x20, 0x61, 0x78, 0x73, 0x3d, 0x65, 0x6c, 0x65, 0x6d, - 0x65, 0x6e, 0x74, 0x73, 0x28, 0x78, 0x73, 0x2c, 0x20, 0x30, 0x4c, 0x2c, - 0x20, 0x6e, 0x29, 0x3b, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x61, - 0x78, 0x73, 0x5b, 0x30, 0x5d, 0x29, 0x3b, 0x20, 0x70, 0x72, 0x69, 0x6e, - 0x74, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, 0x61, 0x78, 0x73, 0x2c, 0x20, - 0x31, 0x4c, 0x29, 0x3b, 0x20, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, - 0x22, 0x5d, 0x22, 0x29, 0x3b, 0x20, 0x7d, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, - 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x73, 0x20, - 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x0a, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, 0x50, 0x72, 0x69, 0x6e, + 0x6e, 0x74, 0x20, 0x63, 0x73, 0x20, 0x3d, 0x20, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x28, 0x63, 0x73, 0x5b, 0x30, 0x3a, 0x5d, 0x29, 0x0a, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, 0x41, 0x72, 0x72, 0x61, + 0x79, 0x20, 0x62, 0x73, 0x20, 0x62, 0x79, 0x74, 0x65, 0x29, 0x20, 0x3d, + 0x3e, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x62, 0x73, 0x20, 0x77, + 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x20, 0x62, 0x73, 0x20, 0x3d, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, + 0x62, 0x73, 0x5b, 0x30, 0x3a, 0x5d, 0x29, 0x0a, 0x0a, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x41, 0x72, 0x72, 0x61, 0x79, 0x20, 0x3a, 0x3a, 0x20, 0x28, + 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x29, 0x20, 0x3d, 0x3e, 0x20, + 0x28, 0x5b, 0x61, 0x5d, 0x2c, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x29, 0x20, + 0x2d, 0x3e, 0x20, 0x28, 0x29, 0x0a, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x41, + 0x72, 0x72, 0x61, 0x79, 0x20, 0x78, 0x73, 0x20, 0x69, 0x20, 0x3d, 0x0a, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x69, 0x20, 0x3d, 0x3d, 0x20, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, 0x78, 0x73, 0x29, 0x29, 0x20, 0x74, + 0x68, 0x65, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x28, 0x29, 0x0a, 0x20, + 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, + 0x20, 0x7b, 0x20, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x22, 0x2c, + 0x20, 0x22, 0x29, 0x3b, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x78, + 0x73, 0x5b, 0x69, 0x5d, 0x29, 0x3b, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, 0x78, 0x73, 0x2c, 0x20, 0x69, 0x2b, + 0x31, 0x4c, 0x29, 0x3b, 0x20, 0x7d, 0x0a, 0x7b, 0x2d, 0x23, 0x20, 0x55, + 0x4e, 0x53, 0x41, 0x46, 0x45, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x41, + 0x72, 0x72, 0x61, 0x79, 0x20, 0x23, 0x2d, 0x7d, 0x0a, 0x0a, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, 0x41, 0x72, 0x72, 0x61, + 0x79, 0x20, 0x61, 0x73, 0x20, 0x61, 0x2c, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x50, 0x72, 0x69, 0x6e, - 0x74, 0x20, 0x28, 0x5e, 0x78, 0x2e, 0x28, 0x28, 0x29, 0x2b, 0x28, 0x61, - 0x2a, 0x78, 0x29, 0x29, 0x29, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, - 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x78, 0x73, 0x20, 0x3d, - 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x75, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, - 0x28, 0x78, 0x73, 0x29, 0x20, 0x6f, 0x66, 0x20, 0x7c, 0x30, 0x3a, 0x5f, - 0x3d, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x22, 0x5b, 0x5d, 0x22, - 0x29, 0x2c, 0x20, 0x31, 0x3a, 0x70, 0x3d, 0x6c, 0x65, 0x74, 0x20, 0x5f, - 0x20, 0x3d, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x70, 0x2e, 0x30, - 0x29, 0x3b, 0x20, 0x5f, 0x20, 0x3d, 0x20, 0x70, 0x75, 0x74, 0x53, 0x74, - 0x72, 0x28, 0x22, 0x3a, 0x22, 0x29, 0x20, 0x69, 0x6e, 0x20, 0x70, 0x72, - 0x69, 0x6e, 0x74, 0x28, 0x70, 0x2e, 0x31, 0x29, 0x7c, 0x0a, 0x0a, 0x2f, - 0x2f, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x72, 0x65, 0x63, 0x6f, - 0x72, 0x64, 0x73, 0x0a, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x50, 0x72, - 0x69, 0x6e, 0x74, 0x52, 0x20, 0x61, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, + 0x74, 0x20, 0x61, 0x73, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, + 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x78, 0x73, 0x20, 0x3d, 0x20, + 0x6c, 0x65, 0x74, 0x20, 0x6e, 0x3d, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x78, + 0x73, 0x29, 0x20, 0x69, 0x6e, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6e, 0x3d, + 0x3d, 0x30, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x70, 0x75, 0x74, + 0x53, 0x74, 0x72, 0x28, 0x22, 0x5b, 0x5d, 0x22, 0x29, 0x20, 0x65, 0x6c, + 0x73, 0x65, 0x20, 0x64, 0x6f, 0x20, 0x7b, 0x20, 0x70, 0x75, 0x74, 0x53, + 0x74, 0x72, 0x28, 0x22, 0x5b, 0x22, 0x29, 0x3b, 0x20, 0x61, 0x78, 0x73, + 0x3d, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x28, 0x78, 0x73, + 0x2c, 0x20, 0x30, 0x4c, 0x2c, 0x20, 0x6e, 0x29, 0x3b, 0x20, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x28, 0x61, 0x78, 0x73, 0x5b, 0x30, 0x5d, 0x29, 0x3b, + 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, + 0x61, 0x78, 0x73, 0x2c, 0x20, 0x31, 0x4c, 0x29, 0x3b, 0x20, 0x70, 0x75, + 0x74, 0x53, 0x74, 0x72, 0x28, 0x22, 0x5d, 0x22, 0x29, 0x3b, 0x20, 0x7d, + 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x6c, + 0x69, 0x73, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69, 0x6e, + 0x67, 0x73, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, + 0x28, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x29, 0x20, 0x3d, 0x3e, + 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x28, 0x5e, 0x78, 0x2e, 0x28, + 0x28, 0x29, 0x2b, 0x28, 0x61, 0x2a, 0x78, 0x29, 0x29, 0x29, 0x20, 0x77, + 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x20, 0x78, 0x73, 0x20, 0x3d, 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x75, + 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x28, 0x78, 0x73, 0x29, 0x20, 0x6f, 0x66, + 0x20, 0x7c, 0x30, 0x3a, 0x5f, 0x3d, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, + 0x28, 0x22, 0x5b, 0x5d, 0x22, 0x29, 0x2c, 0x20, 0x31, 0x3a, 0x70, 0x3d, + 0x6c, 0x65, 0x74, 0x20, 0x5f, 0x20, 0x3d, 0x20, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x28, 0x70, 0x2e, 0x30, 0x29, 0x3b, 0x20, 0x5f, 0x20, 0x3d, 0x20, + 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x22, 0x3a, 0x22, 0x29, 0x20, + 0x69, 0x6e, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x70, 0x2e, 0x31, + 0x29, 0x7c, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x20, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x0a, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x52, 0x20, 0x61, 0x20, + 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x72, 0x65, 0x63, 0x20, 0x3a, 0x3a, 0x20, 0x28, 0x62, 0x6f, 0x6f, + 0x6c, 0x2c, 0x61, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x28, 0x29, 0x0a, 0x0a, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x50, 0x72, 0x69, + 0x6e, 0x74, 0x52, 0x20, 0x28, 0x29, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x72, 0x65, 0x63, 0x20, - 0x3a, 0x3a, 0x20, 0x28, 0x62, 0x6f, 0x6f, 0x6c, 0x2c, 0x61, 0x29, 0x20, - 0x2d, 0x3e, 0x20, 0x28, 0x29, 0x0a, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x52, 0x20, 0x28, - 0x29, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, - 0x69, 0x6e, 0x74, 0x72, 0x65, 0x63, 0x20, 0x5f, 0x20, 0x5f, 0x20, 0x3d, - 0x20, 0x28, 0x29, 0x0a, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x20, 0x28, 0x72, 0x3d, 0x7b, 0x61, 0x2a, 0x72, 0x72, 0x7d, 0x2c, - 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x2c, 0x20, 0x50, 0x72, - 0x69, 0x6e, 0x74, 0x52, 0x20, 0x72, 0x72, 0x29, 0x20, 0x3d, 0x3e, 0x20, - 0x50, 0x72, 0x69, 0x6e, 0x74, 0x52, 0x20, 0x72, 0x20, 0x77, 0x68, 0x65, - 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x72, 0x65, - 0x63, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x72, 0x20, 0x3d, 0x20, - 0x64, 0x6f, 0x7b, 0x69, 0x66, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, - 0x74, 0x68, 0x65, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x65, 0x6c, 0x73, 0x65, - 0x20, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x22, 0x2c, 0x20, 0x22, - 0x29, 0x3b, 0x20, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x72, 0x65, - 0x63, 0x6f, 0x72, 0x64, 0x48, 0x65, 0x61, 0x64, 0x4c, 0x61, 0x62, 0x65, - 0x6c, 0x28, 0x72, 0x29, 0x29, 0x3b, 0x20, 0x70, 0x75, 0x74, 0x53, 0x74, - 0x72, 0x28, 0x22, 0x3d, 0x22, 0x29, 0x3b, 0x20, 0x70, 0x72, 0x69, 0x6e, - 0x74, 0x28, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x48, 0x65, 0x61, 0x64, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x72, 0x29, 0x29, 0x3b, 0x20, 0x70, - 0x72, 0x69, 0x6e, 0x74, 0x72, 0x65, 0x63, 0x28, 0x66, 0x61, 0x6c, 0x73, - 0x65, 0x2c, 0x20, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x61, 0x69, - 0x6c, 0x28, 0x72, 0x29, 0x29, 0x3b, 0x7d, 0x0a, 0x0a, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, 0x50, 0x72, 0x69, 0x6e, 0x74, - 0x52, 0x20, 0x72, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x50, 0x72, 0x69, 0x6e, - 0x74, 0x20, 0x72, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, - 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x78, 0x20, 0x3d, 0x20, 0x64, 0x6f, - 0x7b, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x22, 0x7b, 0x22, 0x29, - 0x3b, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x72, 0x65, 0x63, 0x28, 0x74, - 0x72, 0x75, 0x65, 0x2c, 0x20, 0x78, 0x29, 0x3b, 0x20, 0x70, 0x75, 0x74, - 0x53, 0x74, 0x72, 0x28, 0x22, 0x7d, 0x22, 0x29, 0x3b, 0x7d, 0x0a, 0x0a, - 0x2f, 0x2f, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x74, 0x75, 0x70, - 0x6c, 0x65, 0x73, 0x0a, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x50, 0x72, - 0x69, 0x6e, 0x74, 0x54, 0x20, 0x61, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, - 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x74, 0x75, 0x70, 0x20, - 0x3a, 0x3a, 0x20, 0x28, 0x62, 0x6f, 0x6f, 0x6c, 0x2c, 0x61, 0x29, 0x20, - 0x2d, 0x3e, 0x20, 0x28, 0x29, 0x0a, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x54, 0x20, 0x28, - 0x29, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, - 0x69, 0x6e, 0x74, 0x74, 0x75, 0x70, 0x20, 0x5f, 0x20, 0x5f, 0x20, 0x3d, - 0x20, 0x28, 0x29, 0x0a, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x20, 0x28, 0x70, 0x3d, 0x28, 0x61, 0x2a, 0x74, 0x29, 0x2c, 0x20, - 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x2c, 0x20, 0x50, 0x72, 0x69, - 0x6e, 0x74, 0x54, 0x20, 0x74, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x50, 0x72, - 0x69, 0x6e, 0x74, 0x54, 0x20, 0x70, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, + 0x5f, 0x20, 0x5f, 0x20, 0x3d, 0x20, 0x28, 0x29, 0x0a, 0x0a, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, 0x72, 0x3d, 0x7b, 0x61, + 0x2a, 0x72, 0x72, 0x7d, 0x2c, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, + 0x61, 0x2c, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x52, 0x20, 0x72, 0x72, + 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x52, 0x20, + 0x72, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x72, 0x65, 0x63, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, + 0x20, 0x72, 0x20, 0x3d, 0x20, 0x64, 0x6f, 0x7b, 0x69, 0x66, 0x20, 0x66, + 0x69, 0x72, 0x73, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x28, 0x29, + 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, + 0x28, 0x22, 0x2c, 0x20, 0x22, 0x29, 0x3b, 0x20, 0x70, 0x75, 0x74, 0x53, + 0x74, 0x72, 0x28, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x48, 0x65, 0x61, + 0x64, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x28, 0x72, 0x29, 0x29, 0x3b, 0x20, + 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x22, 0x3d, 0x22, 0x29, 0x3b, + 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x72, 0x65, 0x63, 0x6f, 0x72, + 0x64, 0x48, 0x65, 0x61, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x72, + 0x29, 0x29, 0x3b, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x72, 0x65, 0x63, + 0x28, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x20, 0x72, 0x65, 0x63, 0x6f, + 0x72, 0x64, 0x54, 0x61, 0x69, 0x6c, 0x28, 0x72, 0x29, 0x29, 0x3b, 0x7d, + 0x0a, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, + 0x50, 0x72, 0x69, 0x6e, 0x74, 0x52, 0x20, 0x72, 0x29, 0x20, 0x3d, 0x3e, + 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x72, 0x20, 0x77, 0x68, 0x65, + 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x78, + 0x20, 0x3d, 0x20, 0x64, 0x6f, 0x7b, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, + 0x28, 0x22, 0x7b, 0x22, 0x29, 0x3b, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x72, 0x65, 0x63, 0x28, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x20, 0x78, 0x29, + 0x3b, 0x20, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x22, 0x7d, 0x22, + 0x29, 0x3b, 0x7d, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x20, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x73, 0x0a, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x54, 0x20, 0x61, 0x20, + 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x74, 0x75, 0x70, 0x20, 0x3a, 0x3a, 0x20, 0x28, 0x62, 0x6f, 0x6f, + 0x6c, 0x2c, 0x61, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x28, 0x29, 0x0a, 0x0a, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x50, 0x72, 0x69, + 0x6e, 0x74, 0x54, 0x20, 0x28, 0x29, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x74, 0x75, 0x70, 0x20, - 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x70, 0x20, 0x3d, 0x20, 0x64, 0x6f, - 0x7b, 0x69, 0x66, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x74, 0x68, - 0x65, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x70, - 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x22, 0x2c, 0x20, 0x22, 0x29, 0x3b, - 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x70, 0x2e, 0x30, 0x29, 0x3b, - 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x74, 0x75, 0x70, 0x28, 0x66, 0x61, - 0x6c, 0x73, 0x65, 0x2c, 0x20, 0x74, 0x75, 0x70, 0x6c, 0x65, 0x54, 0x61, - 0x69, 0x6c, 0x28, 0x70, 0x29, 0x29, 0x3b, 0x7d, 0x0a, 0x0a, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, 0x50, 0x72, 0x69, 0x6e, - 0x74, 0x54, 0x20, 0x70, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x50, 0x72, 0x69, - 0x6e, 0x74, 0x20, 0x70, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, - 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x70, 0x20, 0x3d, 0x20, 0x64, - 0x6f, 0x7b, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x22, 0x28, 0x22, - 0x29, 0x3b, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x74, 0x75, 0x70, 0x28, - 0x74, 0x72, 0x75, 0x65, 0x2c, 0x20, 0x70, 0x29, 0x3b, 0x20, 0x70, 0x75, - 0x74, 0x53, 0x74, 0x72, 0x28, 0x22, 0x29, 0x22, 0x29, 0x3b, 0x7d, 0x0a, - 0x0a, 0x2f, 0x2f, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x27, 0x6d, 0x61, 0x79, - 0x62, 0x65, 0x27, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2c, 0x20, 0x77, - 0x65, 0x20, 0x64, 0x6f, 0x6e, 0x27, 0x74, 0x20, 0x6e, 0x65, 0x65, 0x64, - 0x20, 0x74, 0x6f, 0x20, 0x73, 0x65, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x20, 0x73, 0x74, 0x72, 0x75, - 0x63, 0x74, 0x75, 0x72, 0x65, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x20, 0x28, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x29, - 0x20, 0x3d, 0x3e, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x28, 0x28, - 0x29, 0x2b, 0x61, 0x29, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, - 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x6d, 0x20, 0x3d, 0x20, 0x63, - 0x61, 0x73, 0x65, 0x20, 0x6d, 0x20, 0x6f, 0x66, 0x20, 0x7c, 0x30, 0x3a, - 0x5f, 0x3d, 0x28, 0x29, 0x2c, 0x31, 0x3a, 0x78, 0x3d, 0x70, 0x72, 0x69, - 0x6e, 0x74, 0x28, 0x78, 0x29, 0x7c, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x70, - 0x72, 0x69, 0x6e, 0x74, 0x20, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, - 0x73, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, - 0x69, 0x63, 0x20, 0x63, 0x61, 0x73, 0x65, 0x0a, 0x63, 0x6c, 0x61, 0x73, - 0x73, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x50, 0x61, - 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x61, 0x20, 0x77, 0x68, 0x65, 0x72, - 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x72, - 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x3a, 0x3a, 0x20, 0x61, - 0x20, 0x2d, 0x3e, 0x20, 0x28, 0x29, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x72, - 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x28, 0x29, 0x20, 0x77, - 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, - 0x56, 0x61, 0x72, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x3d, - 0x20, 0x69, 0x64, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x20, 0x28, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x29, 0x20, 0x3d, - 0x3e, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x50, 0x61, - 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x61, 0x20, 0x77, 0x68, 0x65, 0x72, - 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x72, - 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x78, 0x20, 0x3d, 0x20, - 0x64, 0x6f, 0x20, 0x7b, 0x20, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, - 0x22, 0x3d, 0x22, 0x29, 0x3b, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, - 0x78, 0x29, 0x3b, 0x20, 0x7d, 0x0a, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x20, 0x28, 0x76, 0x3d, 0x7c, 0x68, 0x2b, 0x30, 0x7c, - 0x2c, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x68, 0x29, 0x20, 0x3d, - 0x3e, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x76, 0x20, 0x77, 0x68, + 0x5f, 0x20, 0x5f, 0x20, 0x3d, 0x20, 0x28, 0x29, 0x0a, 0x0a, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, 0x70, 0x3d, 0x28, 0x61, + 0x2a, 0x74, 0x29, 0x2c, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x61, + 0x2c, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x54, 0x20, 0x74, 0x29, 0x20, + 0x3d, 0x3e, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x54, 0x20, 0x70, 0x20, + 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x74, 0x75, 0x70, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x70, + 0x20, 0x3d, 0x20, 0x64, 0x6f, 0x7b, 0x69, 0x66, 0x20, 0x66, 0x69, 0x72, + 0x73, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x65, + 0x6c, 0x73, 0x65, 0x20, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x22, + 0x2c, 0x20, 0x22, 0x29, 0x3b, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, + 0x70, 0x2e, 0x30, 0x29, 0x3b, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x74, + 0x75, 0x70, 0x28, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x20, 0x74, 0x75, + 0x70, 0x6c, 0x65, 0x54, 0x61, 0x69, 0x6c, 0x28, 0x70, 0x29, 0x29, 0x3b, + 0x7d, 0x0a, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, + 0x28, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x54, 0x20, 0x70, 0x29, 0x20, 0x3d, + 0x3e, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x70, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, - 0x76, 0x20, 0x3d, 0x20, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x53, - 0x70, 0x6c, 0x69, 0x74, 0x28, 0x76, 0x2c, 0x20, 0x5c, 0x68, 0x2e, 0x64, - 0x6f, 0x7b, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x22, 0x7c, 0x22, - 0x29, 0x3b, 0x20, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x76, 0x61, - 0x72, 0x69, 0x61, 0x6e, 0x74, 0x48, 0x65, 0x61, 0x64, 0x4c, 0x61, 0x62, - 0x65, 0x6c, 0x28, 0x76, 0x29, 0x29, 0x3b, 0x20, 0x70, 0x72, 0x69, 0x6e, - 0x74, 0x56, 0x61, 0x72, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x28, - 0x68, 0x29, 0x3b, 0x20, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x22, - 0x7c, 0x22, 0x29, 0x3b, 0x7d, 0x2c, 0x20, 0x74, 0x6f, 0x43, 0x6c, 0x6f, - 0x73, 0x75, 0x72, 0x65, 0x28, 0x5c, 0x5f, 0x2e, 0x28, 0x29, 0x29, 0x29, - 0x0a, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, - 0x76, 0x3d, 0x7c, 0x68, 0x2b, 0x74, 0x7c, 0x2c, 0x20, 0x50, 0x72, 0x69, - 0x6e, 0x74, 0x20, 0x68, 0x2c, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, - 0x74, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, - 0x76, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, - 0x69, 0x6e, 0x74, 0x20, 0x76, 0x20, 0x3d, 0x20, 0x76, 0x61, 0x72, 0x69, - 0x61, 0x6e, 0x74, 0x53, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x76, 0x2c, 0x20, - 0x5c, 0x68, 0x2e, 0x64, 0x6f, 0x7b, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, - 0x28, 0x22, 0x7c, 0x22, 0x29, 0x3b, 0x20, 0x70, 0x75, 0x74, 0x53, 0x74, - 0x72, 0x28, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x48, 0x65, 0x61, - 0x64, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x28, 0x76, 0x29, 0x29, 0x3b, 0x20, + 0x70, 0x20, 0x3d, 0x20, 0x64, 0x6f, 0x7b, 0x70, 0x75, 0x74, 0x53, 0x74, + 0x72, 0x28, 0x22, 0x28, 0x22, 0x29, 0x3b, 0x20, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x74, 0x75, 0x70, 0x28, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x20, 0x70, + 0x29, 0x3b, 0x20, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x22, 0x29, + 0x22, 0x29, 0x3b, 0x7d, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x66, 0x6f, 0x72, + 0x20, 0x27, 0x6d, 0x61, 0x79, 0x62, 0x65, 0x27, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2c, 0x20, 0x77, 0x65, 0x20, 0x64, 0x6f, 0x6e, 0x27, 0x74, + 0x20, 0x6e, 0x65, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x65, 0x65, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, + 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x0a, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, 0x50, 0x72, 0x69, + 0x6e, 0x74, 0x20, 0x61, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x50, 0x72, 0x69, + 0x6e, 0x74, 0x20, 0x28, 0x28, 0x29, 0x2b, 0x61, 0x29, 0x20, 0x77, 0x68, + 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, + 0x6d, 0x20, 0x3d, 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x6d, 0x20, 0x6f, + 0x66, 0x20, 0x7c, 0x30, 0x3a, 0x5f, 0x3d, 0x28, 0x29, 0x2c, 0x31, 0x3a, + 0x78, 0x3d, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x78, 0x29, 0x7c, 0x0a, + 0x0a, 0x2f, 0x2f, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x76, 0x61, + 0x72, 0x69, 0x61, 0x6e, 0x74, 0x73, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x20, 0x63, 0x61, 0x73, 0x65, + 0x0a, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, + 0x56, 0x61, 0x72, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x61, + 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x56, 0x61, 0x72, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, + 0x20, 0x3a, 0x3a, 0x20, 0x61, 0x20, 0x2d, 0x3e, 0x20, 0x28, 0x29, 0x0a, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x50, 0x72, 0x69, + 0x6e, 0x74, 0x56, 0x61, 0x72, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, + 0x20, 0x28, 0x29, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x50, 0x61, 0x79, 0x6c, - 0x6f, 0x61, 0x64, 0x28, 0x68, 0x29, 0x3b, 0x20, 0x70, 0x75, 0x74, 0x53, - 0x74, 0x72, 0x28, 0x22, 0x7c, 0x22, 0x29, 0x3b, 0x7d, 0x2c, 0x20, 0x74, - 0x6f, 0x43, 0x6c, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x28, 0x70, 0x72, 0x69, - 0x6e, 0x74, 0x29, 0x29, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x70, 0x72, 0x69, - 0x6e, 0x74, 0x20, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, - 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, - 0x65, 0x69, 0x72, 0x20, 0x6f, 0x6e, 0x65, 0x2d, 0x73, 0x74, 0x65, 0x70, - 0x20, 0x75, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x69, - 0x73, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x0a, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, 0x61, 0x20, - 0x7e, 0x20, 0x62, 0x2c, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x62, - 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x61, + 0x6f, 0x61, 0x64, 0x20, 0x3d, 0x20, 0x69, 0x64, 0x0a, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, 0x50, 0x72, 0x69, 0x6e, 0x74, + 0x20, 0x61, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, + 0x56, 0x61, 0x72, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x61, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, - 0x6e, 0x74, 0x20, 0x78, 0x20, 0x3d, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, - 0x28, 0x75, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x28, 0x78, 0x29, 0x29, 0x0a, - 0x0a, 0x2f, 0x2f, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x70, 0x72, - 0x69, 0x6e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, - 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x0a, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, 0x50, 0x72, - 0x69, 0x6e, 0x74, 0x20, 0x61, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x50, 0x72, - 0x69, 0x6e, 0x74, 0x20, 0x61, 0x40, 0x66, 0x20, 0x77, 0x68, 0x65, 0x72, - 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x78, 0x20, - 0x3d, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x6c, 0x6f, 0x61, 0x64, + 0x6e, 0x74, 0x56, 0x61, 0x72, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, + 0x20, 0x78, 0x20, 0x3d, 0x20, 0x64, 0x6f, 0x20, 0x7b, 0x20, 0x70, 0x75, + 0x74, 0x53, 0x74, 0x72, 0x28, 0x22, 0x3d, 0x22, 0x29, 0x3b, 0x20, 0x70, + 0x72, 0x69, 0x6e, 0x74, 0x28, 0x78, 0x29, 0x3b, 0x20, 0x7d, 0x0a, 0x0a, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, 0x76, 0x3d, + 0x7c, 0x68, 0x2b, 0x30, 0x7c, 0x2c, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, + 0x20, 0x68, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, + 0x20, 0x76, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, + 0x72, 0x69, 0x6e, 0x74, 0x20, 0x76, 0x20, 0x3d, 0x20, 0x76, 0x61, 0x72, + 0x69, 0x61, 0x6e, 0x74, 0x53, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x76, 0x2c, + 0x20, 0x5c, 0x68, 0x2e, 0x64, 0x6f, 0x7b, 0x70, 0x75, 0x74, 0x53, 0x74, + 0x72, 0x28, 0x22, 0x7c, 0x22, 0x29, 0x3b, 0x20, 0x70, 0x75, 0x74, 0x53, + 0x74, 0x72, 0x28, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x48, 0x65, + 0x61, 0x64, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x28, 0x76, 0x29, 0x29, 0x3b, + 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x50, 0x61, 0x79, + 0x6c, 0x6f, 0x61, 0x64, 0x28, 0x68, 0x29, 0x3b, 0x20, 0x70, 0x75, 0x74, + 0x53, 0x74, 0x72, 0x28, 0x22, 0x7c, 0x22, 0x29, 0x3b, 0x7d, 0x2c, 0x20, + 0x74, 0x6f, 0x43, 0x6c, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x28, 0x5c, 0x5f, + 0x2e, 0x28, 0x29, 0x29, 0x29, 0x0a, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x20, 0x28, 0x76, 0x3d, 0x7c, 0x68, 0x2b, 0x74, 0x7c, + 0x2c, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x68, 0x2c, 0x20, 0x50, + 0x72, 0x69, 0x6e, 0x74, 0x20, 0x74, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x50, + 0x72, 0x69, 0x6e, 0x74, 0x20, 0x76, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, + 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x76, 0x20, 0x3d, + 0x20, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x53, 0x70, 0x6c, 0x69, + 0x74, 0x28, 0x76, 0x2c, 0x20, 0x5c, 0x68, 0x2e, 0x64, 0x6f, 0x7b, 0x70, + 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x22, 0x7c, 0x22, 0x29, 0x3b, 0x20, + 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x76, 0x61, 0x72, 0x69, 0x61, + 0x6e, 0x74, 0x48, 0x65, 0x61, 0x64, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x28, + 0x76, 0x29, 0x29, 0x3b, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x56, 0x61, + 0x72, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x28, 0x68, 0x29, 0x3b, + 0x20, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x22, 0x7c, 0x22, 0x29, + 0x3b, 0x7d, 0x2c, 0x20, 0x74, 0x6f, 0x43, 0x6c, 0x6f, 0x73, 0x75, 0x72, + 0x65, 0x28, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x29, 0x29, 0x0a, 0x0a, 0x2f, + 0x2f, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x72, 0x65, 0x63, 0x75, + 0x72, 0x73, 0x69, 0x76, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x20, + 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x69, 0x72, 0x20, 0x6f, 0x6e, 0x65, + 0x2d, 0x73, 0x74, 0x65, 0x70, 0x20, 0x75, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, + 0x69, 0x6e, 0x67, 0x20, 0x69, 0x73, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x20, 0x28, 0x61, 0x20, 0x7e, 0x20, 0x62, 0x2c, 0x20, 0x50, 0x72, + 0x69, 0x6e, 0x74, 0x20, 0x62, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x50, 0x72, + 0x69, 0x6e, 0x74, 0x20, 0x61, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, + 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x78, 0x20, 0x3d, 0x20, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x75, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x28, 0x78, 0x29, 0x29, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x70, 0x72, 0x69, - 0x6e, 0x74, 0x20, 0x62, 0x69, 0x74, 0x20, 0x76, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x73, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, - 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x62, 0x69, 0x74, 0x76, 0x65, 0x63, + 0x6e, 0x74, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x73, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x20, 0x28, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x29, 0x20, + 0x3d, 0x3e, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x40, 0x66, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, - 0x6e, 0x74, 0x20, 0x62, 0x76, 0x20, 0x3d, 0x20, 0x62, 0x76, 0x50, 0x72, - 0x69, 0x6e, 0x74, 0x54, 0x28, 0x62, 0x76, 0x2c, 0x20, 0x30, 0x4c, 0x2c, - 0x20, 0x62, 0x76, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, 0x62, 0x76, - 0x29, 0x29, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, - 0x20, 0x61, 0x6e, 0x79, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x6c, - 0x73, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x27, 0x73, 0x20, 0x73, 0x68, - 0x6f, 0x77, 0x61, 0x62, 0x6c, 0x65, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x20, 0x28, 0x53, 0x68, 0x6f, 0x77, 0x20, 0x61, 0x29, - 0x20, 0x3d, 0x3e, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x20, - 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, - 0x74, 0x20, 0x78, 0x20, 0x3d, 0x20, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, - 0x28, 0x73, 0x68, 0x6f, 0x77, 0x28, 0x78, 0x29, 0x29, 0x0a, 0x0a, 0x2f, - 0x2f, 0x20, 0x77, 0x65, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x20, 0x75, 0x70, - 0x20, 0x64, 0x6f, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, - 0x73, 0x75, 0x72, 0x70, 0x72, 0x69, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x79, - 0x20, 0x6f, 0x66, 0x74, 0x65, 0x6e, 0x0a, 0x70, 0x72, 0x69, 0x6e, 0x74, - 0x6c, 0x6e, 0x20, 0x3a, 0x3a, 0x20, 0x28, 0x50, 0x72, 0x69, 0x6e, 0x74, - 0x20, 0x61, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x61, 0x20, 0x2d, 0x3e, 0x20, - 0x28, 0x29, 0x0a, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x6c, 0x6e, 0x20, 0x78, - 0x20, 0x3d, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x5f, 0x20, 0x3d, 0x20, 0x70, - 0x72, 0x69, 0x6e, 0x74, 0x28, 0x78, 0x29, 0x20, 0x69, 0x6e, 0x20, 0x70, - 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x22, 0x5c, 0x6e, 0x22, 0x29, 0x0a, - 0x0a, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x4c, 0x6e, 0x20, 0x3a, 0x3a, - 0x20, 0x5b, 0x63, 0x68, 0x61, 0x72, 0x5d, 0x20, 0x2d, 0x3e, 0x20, 0x28, - 0x29, 0x0a, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x4c, 0x6e, 0x20, 0x78, - 0x20, 0x3d, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x5f, 0x20, 0x3d, 0x20, 0x70, - 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x78, 0x29, 0x20, 0x69, 0x6e, 0x20, - 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x22, 0x5c, 0x6e, 0x22, 0x29, - 0x0a, 0x0a, 0x2f, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x67, 0x65, 0x6e, 0x65, - 0x72, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x66, 0x6f, - 0x72, 0x6d, 0x61, 0x74, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, - 0x20, 0x28, 0x65, 0x2e, 0x67, 0x2e, 0x3a, 0x20, 0x60, 0x78, 0x20, 0x3d, - 0x20, 0x24, 0x78, 0x60, 0x20, 0x3d, 0x3e, 0x20, 0x22, 0x78, 0x20, 0x3d, - 0x20, 0x22, 0x20, 0x2b, 0x2b, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, - 0x28, 0x78, 0x29, 0x29, 0x0a, 0x20, 0x2a, 0x2f, 0x0a, 0x63, 0x6c, 0x61, - 0x73, 0x73, 0x20, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x61, 0x20, - 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x6d, - 0x61, 0x74, 0x20, 0x3a, 0x3a, 0x20, 0x61, 0x20, 0x2d, 0x3e, 0x20, 0x5b, - 0x63, 0x68, 0x61, 0x72, 0x5d, 0x0a, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x20, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x5b, - 0x63, 0x68, 0x61, 0x72, 0x5d, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, - 0x20, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x3d, 0x20, 0x69, - 0x64, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, - 0x41, 0x72, 0x72, 0x61, 0x79, 0x20, 0x63, 0x73, 0x20, 0x63, 0x68, 0x61, - 0x72, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, - 0x20, 0x63, 0x73, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, - 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x63, 0x73, 0x20, 0x3d, 0x20, - 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x63, 0x73, 0x5b, 0x30, 0x3a, - 0x5d, 0x29, 0x0a, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x20, 0x28, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x61, 0x29, 0x20, - 0x3d, 0x3e, 0x20, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x61, 0x40, - 0x66, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x66, 0x6f, - 0x72, 0x6d, 0x61, 0x74, 0x20, 0x78, 0x20, 0x3d, 0x20, 0x66, 0x6f, 0x72, - 0x6d, 0x61, 0x74, 0x28, 0x6c, 0x6f, 0x61, 0x64, 0x28, 0x78, 0x29, 0x29, - 0x0a, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, - 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x61, 0x29, 0x20, 0x3d, 0x3e, - 0x20, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x28, 0x28, 0x29, 0x2b, - 0x61, 0x29, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x66, - 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x6d, 0x78, 0x20, 0x3d, 0x20, 0x6d, - 0x61, 0x74, 0x63, 0x68, 0x20, 0x6d, 0x78, 0x20, 0x77, 0x69, 0x74, 0x68, - 0x20, 0x7c, 0x20, 0x7c, 0x31, 0x3d, 0x78, 0x7c, 0x20, 0x2d, 0x3e, 0x20, - 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x78, 0x29, 0x20, 0x7c, 0x20, - 0x5f, 0x20, 0x2d, 0x3e, 0x20, 0x22, 0x22, 0x0a, 0x0a, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, 0x53, 0x68, 0x6f, 0x77, 0x20, + 0x6e, 0x74, 0x20, 0x78, 0x20, 0x3d, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x28, 0x6c, 0x6f, 0x61, 0x64, 0x28, 0x78, 0x29, 0x29, 0x0a, 0x0a, 0x2f, + 0x2f, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x62, 0x69, 0x74, 0x20, + 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x0a, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x20, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x62, + 0x69, 0x74, 0x76, 0x65, 0x63, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, + 0x20, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x62, 0x76, 0x20, 0x3d, + 0x20, 0x62, 0x76, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x54, 0x28, 0x62, 0x76, + 0x2c, 0x20, 0x30, 0x4c, 0x2c, 0x20, 0x62, 0x76, 0x4c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x28, 0x62, 0x76, 0x29, 0x29, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x6e, 0x79, 0x74, 0x68, 0x69, + 0x6e, 0x67, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, + 0x27, 0x73, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x61, 0x62, 0x6c, 0x65, 0x0a, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, 0x53, 0x68, + 0x6f, 0x77, 0x20, 0x61, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x50, 0x72, 0x69, + 0x6e, 0x74, 0x20, 0x61, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, + 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x78, 0x20, 0x3d, 0x20, 0x70, + 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x73, 0x68, 0x6f, 0x77, 0x28, 0x78, + 0x29, 0x29, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x77, 0x65, 0x20, 0x77, 0x69, + 0x6e, 0x64, 0x20, 0x75, 0x70, 0x20, 0x64, 0x6f, 0x69, 0x6e, 0x67, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x20, 0x73, 0x75, 0x72, 0x70, 0x72, 0x69, 0x73, + 0x69, 0x6e, 0x67, 0x6c, 0x79, 0x20, 0x6f, 0x66, 0x74, 0x65, 0x6e, 0x0a, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x6c, 0x6e, 0x20, 0x3a, 0x3a, 0x20, 0x28, + 0x50, 0x72, 0x69, 0x6e, 0x74, 0x20, 0x61, 0x29, 0x20, 0x3d, 0x3e, 0x20, + 0x61, 0x20, 0x2d, 0x3e, 0x20, 0x28, 0x29, 0x0a, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x6c, 0x6e, 0x20, 0x78, 0x20, 0x3d, 0x20, 0x6c, 0x65, 0x74, 0x20, + 0x5f, 0x20, 0x3d, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x78, 0x29, + 0x20, 0x69, 0x6e, 0x20, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x22, + 0x5c, 0x6e, 0x22, 0x29, 0x0a, 0x0a, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, + 0x4c, 0x6e, 0x20, 0x3a, 0x3a, 0x20, 0x5b, 0x63, 0x68, 0x61, 0x72, 0x5d, + 0x20, 0x2d, 0x3e, 0x20, 0x28, 0x29, 0x0a, 0x70, 0x75, 0x74, 0x53, 0x74, + 0x72, 0x4c, 0x6e, 0x20, 0x78, 0x20, 0x3d, 0x20, 0x6c, 0x65, 0x74, 0x20, + 0x5f, 0x20, 0x3d, 0x20, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x78, + 0x29, 0x20, 0x69, 0x6e, 0x20, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, + 0x22, 0x5c, 0x6e, 0x22, 0x29, 0x0a, 0x0a, 0x2f, 0x2a, 0x0a, 0x20, 0x2a, + 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, + 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, + 0x6f, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x28, 0x65, 0x2e, 0x67, 0x2e, 0x3a, + 0x20, 0x60, 0x78, 0x20, 0x3d, 0x20, 0x24, 0x78, 0x60, 0x20, 0x3d, 0x3e, + 0x20, 0x22, 0x78, 0x20, 0x3d, 0x20, 0x22, 0x20, 0x2b, 0x2b, 0x20, 0x66, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x78, 0x29, 0x29, 0x0a, 0x20, 0x2a, + 0x2f, 0x0a, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x46, 0x6f, 0x72, 0x6d, + 0x61, 0x74, 0x20, 0x61, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, + 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x3a, 0x3a, 0x20, 0x61, + 0x20, 0x2d, 0x3e, 0x20, 0x5b, 0x63, 0x68, 0x61, 0x72, 0x5d, 0x0a, 0x0a, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x46, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x20, 0x5b, 0x63, 0x68, 0x61, 0x72, 0x5d, 0x20, 0x77, + 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x20, 0x3d, 0x20, 0x69, 0x64, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x20, 0x28, 0x41, 0x72, 0x72, 0x61, 0x79, 0x20, 0x63, + 0x73, 0x20, 0x63, 0x68, 0x61, 0x72, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x46, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x63, 0x73, 0x20, 0x77, 0x68, 0x65, + 0x72, 0x65, 0x0a, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, + 0x63, 0x73, 0x20, 0x3d, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, + 0x63, 0x73, 0x5b, 0x30, 0x3a, 0x5d, 0x29, 0x0a, 0x0a, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, 0x46, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x20, 0x61, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x46, 0x6f, 0x72, 0x6d, + 0x61, 0x74, 0x20, 0x61, 0x40, 0x66, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, + 0x0a, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x78, 0x20, + 0x3d, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x6c, 0x6f, 0x61, + 0x64, 0x28, 0x78, 0x29, 0x29, 0x0a, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x20, 0x28, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x61, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, - 0x20, 0x61, 0x20, 0x77, 0x68, 0x65, 0x72, 0x65, 0x0a, 0x20, 0x20, 0x66, - 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x68, 0x6f, 0x77, - 0x0a, 0x0a + 0x20, 0x28, 0x28, 0x29, 0x2b, 0x61, 0x29, 0x20, 0x77, 0x68, 0x65, 0x72, + 0x65, 0x0a, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x6d, + 0x78, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x20, 0x6d, 0x78, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x7c, 0x20, 0x7c, 0x31, 0x3d, 0x78, + 0x7c, 0x20, 0x2d, 0x3e, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, + 0x78, 0x29, 0x20, 0x7c, 0x20, 0x5f, 0x20, 0x2d, 0x3e, 0x20, 0x22, 0x22, + 0x0a, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, + 0x53, 0x68, 0x6f, 0x77, 0x20, 0x61, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x46, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x61, 0x20, 0x77, 0x68, 0x65, 0x72, + 0x65, 0x0a, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x3d, + 0x20, 0x73, 0x68, 0x6f, 0x77, 0x0a, 0x0a }; -unsigned int __show_hob_len = 8642; -unsigned char __sort_hob[] = { +unsigned int _show_hob_len = 8695; +unsigned char _sort_hob[] = { 0x2f, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x61, 0x20, 0x62, 0x61, 0x73, 0x69, 0x63, 0x20, 0x69, 0x6e, 0x2d, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x20, 0x71, 0x75, 0x69, 0x63, 0x6b, 0x73, 0x6f, 0x72, 0x74, 0x20, 0x6f, 0x6e, 0x20, @@ -7493,8 +7497,8 @@ unsigned char __sort_hob[] = { 0x64, 0x53, 0x75, 0x62, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x23, 0x2d, 0x7d, 0x0a, 0x0a }; -unsigned int __sort_hob_len = 4467; -unsigned char __sscan_hob[] = { +unsigned int _sort_hob_len = 4467; +unsigned char _sscan_hob[] = { 0x2f, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x20, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x73, 0x63, 0x61, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, @@ -8244,8 +8248,8 @@ unsigned char __sscan_hob[] = { 0x63, 0x74, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x6c, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x23, 0x2d, 0x7d, 0x0a, 0x0a }; -unsigned int __sscan_hob_len = 8971; -unsigned char __storage_hob[] = { +unsigned int _sscan_hob_len = 8971; +unsigned char _storage_hob[] = { 0x0a, 0x2f, 0x2f, 0x20, 0x61, 0x73, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x6e, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x77, 0x65, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x20, @@ -9353,8 +9357,8 @@ unsigned char __storage_hob[] = { 0x74, 0x29, 0x2c, 0x20, 0x30, 0x4c, 0x2c, 0x20, 0x69, 0x2c, 0x20, 0x65, 0x29, 0x29, 0x29, 0x0a, 0x0a }; -unsigned int __storage_hob_len = 13265; -unsigned char __storeslmap_hob[] = { +unsigned int _storage_hob_len = 13265; +unsigned char _storeslmap_hob[] = { 0x2f, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x6c, 0x6d, 0x61, 0x70, 0x20, 0x3a, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x62, 0x61, 0x73, 0x69, 0x63, 0x20, 0x71, 0x75, 0x65, @@ -9456,8 +9460,8 @@ unsigned char __storeslmap_hob[] = { 0x6e, 0x74, 0x73, 0x28, 0x78, 0x73, 0x2c, 0x20, 0x30, 0x4c, 0x2c, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x78, 0x73, 0x29, 0x29, 0x29, 0x0a, 0x0a }; -unsigned int __storeslmap_hob_len = 1200; -unsigned char __streams_hob[] = { +unsigned int _storeslmap_hob_len = 1200; +unsigned char _streams_hob[] = { 0x0a, 0x2f, 0x2f, 0x20, 0x61, 0x20, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x20, 0x69, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x69, 0x6e, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x65, 0x20, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, @@ -9620,8 +9624,8 @@ unsigned char __streams_hob[] = { 0x3b, 0x20, 0x70, 0x75, 0x74, 0x53, 0x74, 0x72, 0x28, 0x22, 0x2e, 0x2e, 0x2e, 0x22, 0x29, 0x3b, 0x20, 0x7d, 0x0a, 0x0a }; -unsigned int __streams_hob_len = 1928; -unsigned char __strings_hob[] = { +unsigned int _streams_hob_len = 1928; +unsigned char _strings_hob[] = { 0x2f, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, @@ -9670,8 +9674,8 @@ unsigned char __strings_hob[] = { 0x3d, 0x3d, 0x3d, 0x20, 0x6c, 0x63, 0x61, 0x73, 0x65, 0x28, 0x62, 0x73, 0x29, 0x0a, 0x0a }; -unsigned int __strings_hob_len = 555; -unsigned char __table_hob[] = { +unsigned int _strings_hob_len = 555; +unsigned char _table_hob[] = { 0x2f, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x0a, 0x20, 0x2a, 0x2f, 0x0a, @@ -10315,8 +10319,8 @@ unsigned char __table_hob[] = { 0x69, 0x70, 0x70, 0x65, 0x64, 0x28, 0x66, 0x6c, 0x69, 0x70, 0x28, 0x78, 0x29, 0x29, 0x0a }; -unsigned int __table_hob_len = 7695; -unsigned char __zstorage_hob[] = { +unsigned int _table_hob_len = 7695; +unsigned char _zstorage_hob[] = { 0x2f, 0x2f, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x28, 0x74, 0x2f, 0x70, 0x3a, 0x3a, 0x78, 0x29, 0x20, 0x3d, 0x3e, 0x20, 0x53, 0x4c, 0x6f, 0x6f, @@ -12056,60 +12060,60 @@ unsigned char __zstorage_hob[] = { 0x28, 0x66, 0x2c, 0x20, 0x78, 0x73, 0x5b, 0x30, 0x3a, 0x5d, 0x29, 0x0a, 0x0a }; -unsigned int __zstorage_hob_len = 20845; +unsigned int _zstorage_hob_len = 20845; unsigned char* module_defs[] = { -__amapping_hob, -__arith_hob, -__convert_hob, -__eq_hob, -__eqord_hob, -__farray_hob, -__farrfilt_hob, -__flip_hob, -__fstrfns_hob, -__hasdef_hob, -__list_hob, -__lookup_hob, -__maybe_hob, -__patterns_hob, -__proccodec_hob, -__read_hob, -__set_hob, -__show_hob, -__sort_hob, -__sscan_hob, -__storage_hob, -__storeslmap_hob, -__streams_hob, -__strings_hob, -__table_hob, -__zstorage_hob, -0 }; +_amapping_hob, +_arith_hob, +_convert_hob, +_eq_hob, +_eqord_hob, +_farray_hob, +_farrfilt_hob, +_flip_hob, +_fstrfns_hob, +_hasdef_hob, +_list_hob, +_lookup_hob, +_maybe_hob, +_patterns_hob, +_proccodec_hob, +_read_hob, +_set_hob, +_show_hob, +_sort_hob, +_sscan_hob, +_storage_hob, +_storeslmap_hob, +_streams_hob, +_strings_hob, +_table_hob, +_zstorage_hob, +nullptr }; unsigned int module_lens[] = { -__amapping_hob_len, -__arith_hob_len, -__convert_hob_len, -__eq_hob_len, -__eqord_hob_len, -__farray_hob_len, -__farrfilt_hob_len, -__flip_hob_len, -__fstrfns_hob_len, -__hasdef_hob_len, -__list_hob_len, -__lookup_hob_len, -__maybe_hob_len, -__patterns_hob_len, -__proccodec_hob_len, -__read_hob_len, -__set_hob_len, -__show_hob_len, -__sort_hob_len, -__sscan_hob_len, -__storage_hob_len, -__storeslmap_hob_len, -__streams_hob_len, -__strings_hob_len, -__table_hob_len, -__zstorage_hob_len, -0 }; +_amapping_hob_len, +_arith_hob_len, +_convert_hob_len, +_eq_hob_len, +_eqord_hob_len, +_farray_hob_len, +_farrfilt_hob_len, +_flip_hob_len, +_fstrfns_hob_len, +_hasdef_hob_len, +_list_hob_len, +_lookup_hob_len, +_maybe_hob_len, +_patterns_hob_len, +_proccodec_hob_len, +_read_hob_len, +_set_hob_len, +_show_hob_len, +_sort_hob_len, +_sscan_hob_len, +_storage_hob_len, +_storeslmap_hob_len, +_streams_hob_len, +_strings_hob_len, +_table_hob_len, +_zstorage_hob_len, +0u }; diff --git a/include/hobbes/cfregion.H b/include/hobbes/cfregion.H index 36892274d..518ec069e 100644 --- a/include/hobbes/cfregion.H +++ b/include/hobbes/cfregion.H @@ -38,8 +38,8 @@ namespace hobbes { namespace fregion { // parameters for arithmetic coding and modeling struct arithn { - typedef uint32_t code; - typedef uint32_t freq; + using code = uint32_t; + using freq = uint32_t; static constexpr uint32_t cbits = 16; static constexpr code cmax = (code(1) << cbits) - code(1); @@ -109,7 +109,7 @@ struct cwbitstream { size_t* batchNode; // allocate an initial batch and prepare to write bits - cwbitstream(imagefile* file) : file(file), buffer(0), seg(0), batchNode(0) { + cwbitstream(imagefile* file) : file(file), buffer(nullptr), seg(nullptr), batchNode(nullptr) { } // initialize a root node from a pair of model states (init and final) @@ -126,7 +126,7 @@ struct cwbitstream { // seek to the last buffer (where the next pointer goes to the null batch node) if (this->batchNode[0] == 1) { - size_t* nextNode = reinterpret_cast(mapFileData(this->file, this->batchNode[2], 3*sizeof(size_t))); + auto* nextNode = reinterpret_cast(mapFileData(this->file, this->batchNode[2], 3*sizeof(size_t))); while (nextNode[0] == 1) { unmapFileData(this->file, this->batchNode, 3*sizeof(size_t)); this->batchNode = nextNode; @@ -167,7 +167,7 @@ struct cwbitstream { // start a new segment within the current batch void stepSegment() { this->seg->nextRef = findSpace(this->file, pagetype::data, sizeof(cbatchseg), sizeof(size_t)); - cbatchseg* newseg = reinterpret_cast(mapFileData(this->file, this->seg->nextRef, sizeof(cbatchseg))); + auto* newseg = reinterpret_cast(mapFileData(this->file, this->seg->nextRef, sizeof(cbatchseg))); unmapFileData(this->file, this->seg, sizeof(cbatchseg)); this->seg = newseg; this->buffer->bitIndex = 0; @@ -176,7 +176,7 @@ struct cwbitstream { // start a new buffer with a given initial model uint64_t stepBuffer(uint64_t initModel, uint64_t scratchModel) { // release the old batch - if (this->buffer) { + if (this->buffer != nullptr) { unmapFileData(this->file, this->buffer, sizeof(cbatch)); } @@ -197,7 +197,7 @@ struct cwbitstream { // allocate a new node to hold this new batch size_t nodeSize = 3 * sizeof(size_t); size_t nodeLoc = findSpace(this->file, pagetype::data, nodeSize, sizeof(size_t)); - size_t* newNode = reinterpret_cast(mapFileData(this->file, nodeLoc, nodeSize)); + auto* newNode = reinterpret_cast(mapFileData(this->file, nodeLoc, nodeSize)); newNode[0] = 1; newNode[1] = batchRef; @@ -362,7 +362,7 @@ struct crbitstream { } // the current batch and segment we're compressing out of - const cbatch* buffer; + const cbatch* buffer = nullptr; const cbatchseg* seg; // the (read) arithmetic encoder state @@ -382,7 +382,7 @@ struct crbitstream { this->seg = reinterpret_cast(mapFileData(this->file, this->seg->nextRef, sizeof(cbatchseg))); this->bitIndex = 0; } - bool bit = this->seg->bits[this->bitIndex>>3]&(1<<((this->bitIndex)%8)); + bool bit = (this->seg->bits[this->bitIndex>>3]&(1<<((this->bitIndex)%8))) != 0; ++this->bitIndex; return bit; } @@ -451,8 +451,8 @@ struct crbitstream { template struct cumFreqState { - typedef uint16_t index_t; - typedef uint16_t symbol; + using index_t = uint16_t; + using symbol = uint16_t; static constexpr index_t symbolCount = static_cast(maxSymbol)+1; static constexpr symbol esc = static_cast(symbolCount); @@ -503,10 +503,10 @@ template template struct dmodel0 : public cumFreqState { public: - typedef cumFreqState CFS; - typedef typename CFS::index_t index_t; - typedef typename CFS::symbol symbol; - typedef typename CFS::CModel CModel; + using CFS = cumFreqState; + using index_t = typename CFS::index_t; + using symbol = typename CFS::symbol; + using CModel = typename CFS::CModel; static constexpr index_t symbolCount = CFS::symbolCount; static constexpr symbol esc = CFS::esc; @@ -598,8 +598,8 @@ template // nothing compresses to nothing (that's a positive statement) template <> struct compress { - typedef int PModel; - typedef int CModel; + using PModel = int; + using CModel = int; static void init(const PModel&, CModel*) { } static void write(cwbitstream*, PModel*, CModel*, unit) { } @@ -609,10 +609,10 @@ template <> // compressed a fixed set of values, cast to a (possibly larger) type template struct compressFixedSet { - typedef dmodel0 M; - typedef typename M::PModel PModel; - typedef typename M::CModel CModel; - typedef typename M::symbol symbol; + using M = dmodel0; + using PModel = typename M::PModel; + using CModel = typename M::CModel; + using symbol = typename M::symbol; static const arithn::code escRange = static_cast(maxSym)+1; @@ -621,7 +621,7 @@ template } static void write(cwbitstream* bits, PModel* pm, CModel* cm, AsSym s) { - uint8_t c = static_cast(s); + auto c = static_cast(s); arithn::code clow, chigh; if (M::find(cm, c, &clow, &chigh)) { bits->write(clow, chigh, M::interval(cm)); @@ -641,7 +641,7 @@ template rbits->shift(clow, chigh, M::interval(cm)); if (s == M::esc) { - symbol nc = static_cast(rbits->svalue(escRange)); + auto nc = static_cast(rbits->svalue(escRange)); rbits->shift(nc, nc+1, escRange); M::add(pm, cm, nc); *c = static_cast(static_cast(nc)); @@ -704,11 +704,11 @@ template <> struct compress : public compressByteSeq { }; // to compress floating point numbers, treat them like a structure {sign:bool, exp:b, val:nat} template struct compressFloat { - typedef compress CSign; - typedef compress CExp; - typedef compress CVal; - typedef tuple PModel; - typedef tuple CModel; + using CSign = compress; + using CExp = compress; + using CVal = compress; + using PModel = tuple; + using CModel = tuple; static void init(const PModel& pm, CModel* cm) { CSign::init(pm.template at<0>(), &cm->template at<0>()); @@ -749,13 +749,13 @@ template <> struct compress : public compressByteSeq { }; #endif // compress tuples, pairs and structures -template struct PModelOf { typedef typename compress::PModel type; }; -template struct CModelOf { typedef typename compress::CModel type; }; +template struct PModelOf { using type = typename compress::PModel; }; +template struct CModelOf { using type = typename compress::CModel; }; template struct compressTuple { - typedef typename nth::type H; - typedef compressTuple Recurse; + using H = typename nth::type; + using Recurse = compressTuple; static void init(const PModel& pm, CModel* cm) { compress::init(pm.template at(), &cm->template at()); @@ -779,9 +779,9 @@ template template struct compress> { - typedef typename fmap>::type PModel; - typedef typename fmap>::type CModel; - typedef compressTuple<0, sizeof...(Fields), PModel, CModel, Fields...> Reflect; + using PModel = typename fmap>::type; + using CModel = typename fmap>::type; + using Reflect = compressTuple<0, sizeof...(Fields), PModel, CModel, Fields...>; static void init(const PModel& pm, CModel* cm) { Reflect::init(pm, cm); } static void write(cwbitstream* bits, PModel* pm, CModel* cm, const tuple& t) { Reflect::write(bits, pm, cm, t); } @@ -790,10 +790,10 @@ template template struct compress> { - typedef std::pair T; - typedef tuple TT; - typedef typename compress::PModel PModel; - typedef typename compress::CModel CModel; + using T = std::pair; + using TT = tuple; + using PModel = typename compress::PModel; + using CModel = typename compress::CModel; static void init(const PModel& pm, CModel* cm) { compress::init(pm, cm); } static void write(cwbitstream* bits, PModel* pm, CModel* cm, const T& t) { compress::write(bits, pm, cm, *reinterpret_cast(&t)); } @@ -802,9 +802,9 @@ template template struct compress::type> { - typedef typename T::as_tuple_type TT; - typedef typename compress::PModel PModel; - typedef typename compress::CModel CModel; + using TT = typename T::as_tuple_type; + using PModel = typename compress::PModel; + using CModel = typename compress::CModel; static void init(const PModel& pm, CModel* cm) { compress::init(pm, cm); } static void write(cwbitstream* bits, PModel* pm, CModel* cm, const T& t) { compress::write(bits, pm, cm, *reinterpret_cast(&t)); } @@ -815,8 +815,8 @@ template // these behave like dependent pairs of a size N followed by N values template struct compressSequence { - typedef std::pair::PModel, typename compress::PModel> PModel; - typedef std::pair::CModel, typename compress::CModel> CModel; + using PModel = std::pair::PModel, typename compress::PModel>; + using CModel = std::pair::CModel, typename compress::CModel>; static void init(const PModel& pm, CModel* cm) { compress::init(pm.first, &cm->first); @@ -853,15 +853,15 @@ template }; template struct compressEnum::type> : public compressFixedSet(C)-1, uint8_t> { - typedef uint8_t element; + using element = uint8_t; }; template struct compress::type> { - typedef compressEnum R; - typedef typename R::PModel PModel; - typedef typename R::CModel CModel; - typedef typename R::element element; + using R = compressEnum; + using PModel = typename R::PModel; + using CModel = typename R::CModel; + using element = typename R::element; static void init(const PModel& pm, CModel* cm) { R::init(pm, cm); @@ -878,8 +878,8 @@ template template struct variantCompressor { - typedef typename M::first_type PModel; - typedef typename M::second_type CModel; + using PModel = typename M::first_type; + using CModel = typename M::second_type; static void fn(T* p, cwbitstream* bits, PModel* pm, CModel* cm) { compress::write(bits, &pm->template at(), &cm->template at(), *p); @@ -887,8 +887,8 @@ template }; template struct variantDecompressor { - typedef typename M::first_type PModel; - typedef typename M::second_type CModel; + using PModel = typename M::first_type; + using CModel = typename M::second_type; static void fn(T* p, crbitstream* rbits, PModel* pm, CModel* cm) { new (p) T(); @@ -898,19 +898,19 @@ template template struct compress> { - typedef compressEnum TagC; - typedef typename TagC::PModel TagPModel; - typedef typename TagC::CModel TagCModel; - typedef typename TagC::element TagElement; + using TagC = compressEnum; + using TagPModel = typename TagC::PModel; + using TagCModel = typename TagC::CModel; + using TagElement = typename TagC::element; - typedef typename fmap>::type PayloadPModel; - typedef typename fmap>::type PayloadCModel; - typedef compressTuple<0, sizeof...(Ctors), PayloadPModel, PayloadCModel, Ctors...> PayloadReflect; + using PayloadPModel = typename fmap>::type; + using PayloadCModel = typename fmap>::type; + using PayloadReflect = compressTuple<0, sizeof...(Ctors), PayloadPModel, PayloadCModel, Ctors...>; - typedef std::pair PModel; - typedef std::pair CModel; + using PModel = std::pair; + using CModel = std::pair; - typedef std::pair PayloadModels; + using PayloadModels = std::pair; static void init(const PModel& pm, CModel* cm) { TagC::init(pm.first, &cm->first); @@ -930,9 +930,9 @@ template template struct compress::type> { - typedef typename T::as_variant_type VT; - typedef typename compress::PModel PModel; - typedef typename compress::CModel CModel; + using VT = typename T::as_variant_type; + using PModel = typename compress::PModel; + using CModel = typename compress::CModel; static void init(const PModel& pm, CModel* cm) { compress::init(pm, cm); } static void write(cwbitstream* bits, PModel* pm, CModel* cm, const T& t) { compress::write(bits, pm, cm, *reinterpret_cast(&t)); } @@ -941,9 +941,9 @@ template template struct compress::type> { - typedef typename T::type RT; - typedef typename compress::PModel PModel; - typedef typename compress::CModel CModel; + using RT = typename T::type; + using PModel = typename compress::PModel; + using CModel = typename compress::CModel; static void init(const PModel& pm, CModel* cm) { compress::init(pm, cm); } static void write(cwbitstream* bits, PModel* pm, CModel* cm, const T& t) { compress::write(bits, pm, cm, *reinterpret_cast(&t)); } @@ -963,7 +963,7 @@ inline ty::desc storedBitSeqType() { ty::desc bt = store::storeType(); if (bt->tid == PRIV_HPPF_TYCTOR_STRUCT) { - ty::Struct* s = reinterpret_cast(bt.get()); + auto* s = reinterpret_cast(bt.get()); size_t pc = 0; for (auto& f : s->fields) { @@ -986,7 +986,7 @@ inline ty::desc storedCompressedSeqTypeDef(const ty::desc& t, const ty::desc& mo ty::desc bt = store::storeType(); if (bt->tid == PRIV_HPPF_TYCTOR_STRUCT) { - ty::Struct* s = reinterpret_cast(bt.get()); + auto* s = reinterpret_cast(bt.get()); size_t pc = 0; for (auto& f : s->fields) { @@ -1025,7 +1025,7 @@ inline size_t inferCompressedBatchSize(const bytes& bs) { ty::desc t = ty::decode(bs); if (t->tid == PRIV_HPPF_TYCTOR_TAPP) { - auto ap = reinterpret_cast(t.get()); + const auto *ap = reinterpret_cast(t.get()); if (ap->f->tid == PRIV_HPPF_TYCTOR_PRIM && ap->args.size() == 3) { if (reinterpret_cast(ap->f.get())->n == "cseq") { @@ -1049,8 +1049,8 @@ inline size_t inferCompressedBatchSize(const bytes& bs) { template class cwseries : public seriesi { public: - typedef typename compress::PModel PModel; - typedef typename compress::CModel CModel; + using PModel = typename compress::PModel; + using CModel = typename compress::CModel; cwseries(imagefile* f, const std::string& seqname, size_t maxBatchSize) : tdef(ty::elimFileRefs(store::storeType())), f(f), seqname(seqname), batchSize(maxBatchSize), out(f) { // determine sequence types @@ -1068,7 +1068,7 @@ template // define the sequence and prepare to write to it size_t headNodeRef = findSpace(this->f, pagetype::data, sizeof(size_t), sizeof(size_t)); - size_t* headNode = reinterpret_cast(mapFileData(this->f, headNodeRef, sizeof(size_t))); + auto* headNode = reinterpret_cast(mapFileData(this->f, headNodeRef, sizeof(size_t))); *headNode = this->out.initFresh(initModelRef, this->scratchModelRef); addBinding(this->f, this->seqname, ty::encoding(this->stdef), headNodeRef); unmapFileData(this->f, headNode, sizeof(size_t)); @@ -1076,7 +1076,7 @@ template throw std::runtime_error("Can't write to sequence " + seqname + " as type '" + ty::show(this->stdef) + "', already defined as type '" + ty::show(ty::decode(b->second.type)) + "'"); } else { // load the head batch and initialize from it - size_t* headNode = reinterpret_cast(mapFileData(this->f, b->second.offset, sizeof(size_t))); + auto* headNode = reinterpret_cast(mapFileData(this->f, b->second.offset, sizeof(size_t))); this->scratchModelRef = this->out.initFromRoot(*headNode, sizeof(PModel)); this->scratchModel = reinterpret_cast(mapFileData(this->f, this->scratchModelRef, sizeof(PModel))); @@ -1084,12 +1084,11 @@ template unmapFileData(this->f, headNode, sizeof(size_t)); } } - ~cwseries() { - } + ~cwseries() = default; cwseries(const cwseries&) = delete; cwseries& operator=(const cwseries&) = delete; - const ty::desc& typeDef() const { return this->tdef; } + const ty::desc& typeDef() const override { return this->tdef; } const std::string& name() const { return this->seqname; } imagefile* file() const { return this->f; } @@ -1102,7 +1101,7 @@ template // allocate/initialize the model for this bitstream segment (from the terminal state of the scratch model for the previous segment) uint64_t newScratchModelRef = findSpace(this->f, pagetype::data, sizeof(PModel), sizeof(size_t)); - PModel* newScratchModel = reinterpret_cast(mapFileData(this->f, newScratchModelRef, sizeof(PModel))); + auto* newScratchModel = reinterpret_cast(mapFileData(this->f, newScratchModelRef, sizeof(PModel))); memcpy(reinterpret_cast(newScratchModel), this->scratchModel, sizeof(PModel)); unmapFileData(this->f, this->scratchModel, sizeof(PModel)); @@ -1162,7 +1161,7 @@ public: write(this->f, static_cast(0x0d)); } private: - typedef std::map wseriess; + using wseriess = std::map; imagefile* f; wseriess ss; }; @@ -1171,8 +1170,8 @@ private: template class crseries : public seriesi { public: - typedef typename compress::PModel PModel; - typedef typename compress::CModel CModel; + using PModel = typename compress::PModel; + using CModel = typename compress::CModel; crseries(imagefile* f, const std::string& seqname, const binding& b) : tdef(ty::elimFileRefs(store::storeType())), f(f), batchSize(inferCompressedBatchSize(b.type)), readState(f) { // determine value and sequence types @@ -1189,10 +1188,9 @@ template } crseries(imagefile* f, const std::string& seqname) : crseries(f, seqname, loadBinding(f, seqname)) { } - ~crseries() { - } + ~crseries() = default; - const ty::desc& typeDef() const { return this->tdef; } + const ty::desc& typeDef() const override { return this->tdef; } imagefile* file() const { return this->f; } bool next(T* x) { @@ -1232,7 +1230,7 @@ template void loadReadState(uint64_t root) { while (root != 0) { - uint64_t* d = reinterpret_cast(mapFileData(this->f, root, 3*sizeof(uint64_t))); + auto* d = reinterpret_cast(mapFileData(this->f, root, 3*sizeof(uint64_t))); if (d[0] == 0) { root = 0; } else { @@ -1251,14 +1249,14 @@ template } if (this->batches.size() == 0) { - this->readState.buffer = 0; + this->readState.buffer = nullptr; return false; } else { // load this compressed data segment this->readState.reset(reinterpret_cast(mapFileData(this->f, this->batches.front(), sizeof(cbatch)))); // initialize the model for this batch - const uint8_t* modelState = reinterpret_cast(mapFileData(this->f, this->readState.buffer->initModel, sizeof(PModel))); + const auto* modelState = reinterpret_cast(mapFileData(this->f, this->readState.buffer->initModel, sizeof(PModel))); memcpy(reinterpret_cast(&this->scratchModel), modelState, sizeof(PModel)); unmapFileData(this->f, reinterpret_cast(modelState), sizeof(PModel)); compress::init(this->scratchModel, &this->scratchModelState); @@ -1301,7 +1299,7 @@ public: return rordering(this->f, name); } private: - typedef std::map rseriess; + using rseriess = std::map; imagefile* f; rseriess ss; }; diff --git a/include/hobbes/convert.H b/include/hobbes/convert.H index 9ca97840f..448870c9a 100644 --- a/include/hobbes/convert.H +++ b/include/hobbes/convert.H @@ -7,6 +7,7 @@ #define HOBBES_CONVERT_H_INCLUDED #include "reflect.H" +#include #include #include #include @@ -30,7 +31,7 @@ template // and maps into a statically-known type template struct convFn { - typedef std::function type; + using type = std::function; }; ///////////////////////// @@ -101,7 +102,7 @@ SCAST_CONVERT("double", double, ("char", char), ("byte", uint8_t), ("short", int template struct into> { static typename convFn>::type from(const ty::desc& t) { - const ty::FArr* pfa = reinterpret_cast(t.get()); + const auto* pfa = reinterpret_cast(t.get()); if (t->tid != PRIV_HPPF_TYCTOR_FIXEDARR) { throw std::runtime_error("Can't convert from " + ty::show(t) + " to " + hobbes::string::demangle>()); @@ -137,8 +138,8 @@ template template struct StructConvField { struct type { - typedef T value_type; - typedef typename convFn::type convert_fn; + using value_type = T; + using convert_fn = typename convFn::type; size_t srcOffset; size_t dstOffset; @@ -204,8 +205,8 @@ template // the inductive case (apply at the pointed-to field, then continue walking the struct) template struct ApplyStructConvF, i, n> { - typedef typename nth::type H; - typedef ApplyStructConvF, i+1, n> Recurse; + using H = typename nth::type; + using Recurse = ApplyStructConvF, i + 1, n>; static void apply(const ConvFns& cfns, const void* src, tuple* dst) { const auto& cfn = cfns.template at(); @@ -217,15 +218,15 @@ template template struct into::type> { static typename convFn::type from(const ty::desc& t) { - const ty::Struct* pr = reinterpret_cast(t.get()); + const auto* pr = reinterpret_cast(t.get()); if (t->tid != PRIV_HPPF_TYCTOR_STRUCT) { throw std::runtime_error("Can't convert from " + ty::show(t) + " due to kind mismatch (not a struct)"); } else { - typedef typename T::as_tuple_type TT; + using TT = typename T::as_tuple_type; // prepare the conversion map out of the source into the dest - typedef typename fmap::type StructConvF; + using StructConvF = typename fmap::type; StructConvF scf; MakeStructConvF::init(pr, &scf); @@ -246,8 +247,8 @@ template // a variant conversion function over a variant type holds conversion functions at every possible ctor/payload template struct VariantConvF { - typedef std::function CtorConvF; - typedef std::unordered_map Ctors; + using CtorConvF = std::function; + using Ctors = std::unordered_map; Ctors ctors; size_t srcPayloadOffset; @@ -281,7 +282,7 @@ template struct MakeVariantConvF, VariantConvF, i, n> { static void init(const ty::Variant* srcTy, VariantConvF* convFs) { - typedef typename nth::type H; + using H = typename nth::type; // figure out how to convert just this constructor (if possible) if (const ty::Variant::Ctor* srcCtor = namedCtor(srcTy, DstVariantT::template _hmeta_ctor_name())) { @@ -301,12 +302,12 @@ template ctors.size(); ++k) { - if (ty->ctors[k].at<0>() == cname) { - return &ty->ctors[k]; + for (const auto &ctor : ty->ctors) { + if (ctor.at<0>() == cname) { + return &ctor; } } - return 0; + return nullptr; } }; @@ -314,12 +315,12 @@ template struct into::type> { static typename convFn::type from(const ty::desc& t) { - const ty::Variant* pv = reinterpret_cast(t.get()); + const auto* pv = reinterpret_cast(t.get()); if (t->tid != PRIV_HPPF_TYCTOR_VARIANT) { throw std::runtime_error("Can't convert from " + ty::show(t) + " due to kind mismatch (not a variant)"); } else { - typedef typename T::as_variant_type VT; + using VT = typename T::as_variant_type; // prepare the conversion map out of the source into the dest VariantConvF vcf; diff --git a/include/hobbes/db/file.H b/include/hobbes/db/file.H index 479b4b379..be79f7925 100644 --- a/include/hobbes/db/file.H +++ b/include/hobbes/db/file.H @@ -50,9 +50,9 @@ template // a dbseq is a linked list sequence just like 'seq' except that its links are file offsets rather than memory offsets template struct dbseq { - typedef fileref*> link_t; - typedef std::pair cons_t; - typedef variant rep_t; + using link_t = fileref *>; + using cons_t = std::pair; + using rep_t = variant; rep_t data; @@ -77,48 +77,48 @@ template // determine representation type (this is necessary to differentiate types represented by value or reference) template struct frefty { - typedef T type; - typedef T* ptr; + using type = T; + using ptr = T *; }; template struct frefty< array > { - typedef array* type; - typedef array* ptr; + using type = array *; + using ptr = array *; }; template struct frefty< array* > { - typedef array* type; - typedef array* ptr; + using type = array *; + using ptr = array *; }; template struct frefty< dbseq > { - typedef dbseq* type; - typedef dbseq* ptr; + using type = dbseq *; + using ptr = dbseq *; }; template struct frefty< dbseq* > { - typedef dbseq* type; - typedef dbseq* ptr; + using type = dbseq *; + using ptr = dbseq *; }; template struct frefty< recursive > { - typedef recursive* type; - typedef recursive* ptr; + using type = recursive *; + using ptr = recursive *; }; template struct frefty< recursive* > { - typedef recursive* type; - typedef recursive* ptr; + using type = recursive *; + using ptr = recursive *; }; // common typedefs -typedef fileref*> strref; +using strref = fileref *>; // what is the size of a type as represented in storage? size_t storageSizeOf(const MonoTypePtr&); @@ -128,7 +128,7 @@ class cc; // data file details are internally defined namespace fregion { struct imagefile; } -typedef fregion::imagefile imagefile; +using imagefile = fregion::imagefile; // a db reader can only read data from a file class reader { @@ -173,9 +173,9 @@ public: unsafeUnloadArray(xs, sizeof(T)); } private: - typedef std::vector StoredOffsets; - typedef std::vector StoredOffsetElemSizes; - typedef std::vector StoredOffsetSizes; + using StoredOffsets = std::vector; + using StoredOffsetElemSizes = std::vector; + using StoredOffsetSizes = std::vector; StoredOffsets storedOffsets; StoredOffsetSizes storedOffElemSizes; @@ -184,14 +184,14 @@ public: // to speed up dynamic lookups of top-level variables at runtime // (this allows an external user to skip string matching and type structure analysis) inline unsigned int pushOffset(uint64_t offset, const MonoTypePtr& ty) { - unsigned int r = static_cast(this->storedOffsets.size()); + auto r = static_cast(this->storedOffsets.size()); this->storedOffsets.push_back(offset); if (const Array* a = is(ty)) { this->storedOffElemSizes.push_back(1 + storageSizeOf(a->type())); } else { this->storedOffElemSizes.push_back(0); } - this->storedOffSizes.push_back((is(ty)||storedAsDArray(ty)) ? 0 : storageSizeOf(ty)); + this->storedOffSizes.push_back(((is(ty) != nullptr)||storedAsDArray(ty)) ? 0 : storageSizeOf(ty)); return r; } @@ -236,8 +236,8 @@ public: int unsafeGetFD() const; public: // helpful diagnostic functions - typedef std::pair PageEntry; - typedef array PageEntries; + using PageEntry = std::pair; + using PageEntries = array; PageEntries* pageEntries() const; protected: @@ -247,7 +247,7 @@ protected: MonoTypePtr type; uint64_t offset; }; - typedef std::unordered_map SBindings; + using SBindings = std::unordered_map; SBindings sbindings; void addSBinding(const std::string&, const MonoTypePtr&, uint64_t); }; @@ -287,7 +287,7 @@ public: template fileref::value_type>*> store(TIter b, TIter e) { - typedef typename std::iterator_traits::value_type T; + using T = typename std::iterator_traits::value_type; size_t len = e - b; array* r = store(len); for (size_t i = 0; i < len; ++i) { diff --git a/include/hobbes/db/series.H b/include/hobbes/db/series.H index 48f82acd5..dd0f1351d 100644 --- a/include/hobbes/db/series.H +++ b/include/hobbes/db/series.H @@ -15,7 +15,7 @@ namespace hobbes { -typedef uint64_t ufileref; +using ufileref = uint64_t; // A -> (A) MonoTypePtr entuple(const MonoTypePtr&); @@ -75,7 +75,7 @@ private: uint64_t batchNode; uint64_t* headNodeRef; - typedef void (*StoreFn)(writer*, const void*, void*); + using StoreFn = void (*)(writer *, const void *, void *); StoreFn storeFn; void consBatchNode(uint64_t nextPtr); @@ -91,10 +91,10 @@ public: CompressedStoredSeries(cc*, writer*, const std::string&, const MonoTypePtr&, size_t); ~CompressedStoredSeries(); - typedef void (*CWriteFn)(UCWriter*, void*, const void*); - typedef uint8_t* (*CAllocM)(writer*); - typedef void (*CPrepM)(UCWriter*,uint8_t*); - typedef void (*CDeallocM)(uint8_t*); + using CWriteFn = void (*)(UCWriter *, void *, const void *); + using CAllocM = uint8_t *(*)(writer *); + using CPrepM = void (*)(UCWriter *, uint8_t *); + using CDeallocM = void (*)(uint8_t *); // where has this series been placed? ufileref rootRef() const; @@ -113,7 +113,7 @@ public: // (assumes that this series will live at least as long as the bound function is usable) void bindAs(cc*, const std::string&); private: - typedef std::pair ModelTypes; + using ModelTypes = std::pair; writer* outputFile; MonoTypePtr recordType; @@ -170,8 +170,8 @@ public: private: StorageMode sm; union { - char rss[sizeof(RawStoredSeries)]; - char css[sizeof(CompressedStoredSeries)]; + alignas(RawStoredSeries) char rss[sizeof(RawStoredSeries)]; + alignas(CompressedStoredSeries) char css[sizeof(CompressedStoredSeries)]; } storage; }; diff --git a/include/hobbes/eval/cc.H b/include/hobbes/eval/cc.H index b786142ea..ed41f8d1f 100644 --- a/include/hobbes/eval/cc.H +++ b/include/hobbes/eval/cc.H @@ -2,80 +2,95 @@ #ifndef HOBBES_EVAL_CC_HPP_INCLUDED #define HOBBES_EVAL_CC_HPP_INCLUDED +#include +#include #include -#include +#include #include +#include #include -#include -#include #include +#include #include -#include -#include #include #include #include -#include +#include #include -#include #include -#include +#include #include +#include namespace hobbes { // protect access to hobbes/llvm resources between threads class hlock { public: - hlock(); ~hlock(); + hlock(); + ~hlock(); }; class phlock { public: phlock(); void release(); ~phlock(); + private: bool f; }; // parameter parsing for the 'compileFn' family of functions -typedef std::function ExprParser; +using ExprParser = std::function; -template - struct PArgl { - }; -template <> - struct PArgl { - static str::seq names(const ExprPtr&) { return str::seq(); } - static ExprPtr expr(const ExprParser&, const ExprPtr& e) { return e; } - }; -template <> - struct PArgl { - static str::seq names(const std::string&) { return str::seq(); } - static ExprPtr expr(const ExprParser& p, const std::string& e) { return p(e); } - }; -template <> - struct PArgl { - static str::seq names(char*) { return str::seq(); } - static ExprPtr expr(const ExprParser& p, char* e) { return p(std::string(e)); } - }; -template <> - struct PArgl { - static str::seq names(const char*) { return str::seq(); } - static ExprPtr expr(const ExprParser& p, const char* e) { return p(std::string(e)); } - }; -template - struct PArgl { - static str::seq names(const char* x, const NamesAndExpr& ... args) { str::seq r = PArgl::names(args...); r.insert(r.begin(), std::string(x)); return r; } - static ExprPtr expr(const ExprParser& p, const char*, const NamesAndExpr& ... args) { return PArgl::expr(p, args...); } - }; -template - struct PArgl { - static str::seq names(const std::string& x, const NamesAndExpr& ... args) { str::seq r = PArgl::names(args...); r.insert(r.begin(), x); return r; } - static ExprPtr expr(const ExprParser& p, const std::string&, const NamesAndExpr& ... args) { return PArgl::expr(p, args...); } - }; +template struct PArgl {}; +template <> struct PArgl { + static str::seq names(const ExprPtr &) { return str::seq(); } + static ExprPtr expr(const ExprParser &, const ExprPtr &e) { return e; } +}; +template <> struct PArgl { + static str::seq names(const std::string &) { return str::seq(); } + static ExprPtr expr(const ExprParser &p, const std::string &e) { + return p(e); + } +}; +template <> struct PArgl { + static str::seq names(char *) { return str::seq(); } + static ExprPtr expr(const ExprParser &p, char *e) { + return p(std::string(e)); + } +}; +template <> struct PArgl { + static str::seq names(const char *) { return str::seq(); } + static ExprPtr expr(const ExprParser &p, const char *e) { + return p(std::string(e)); + } +}; +template +struct PArgl { + static str::seq names(const char *x, const NamesAndExpr &...args) { + str::seq r = PArgl::names(args...); + r.insert(r.begin(), std::string(x)); + return r; + } + static ExprPtr expr(const ExprParser &p, const char *, + const NamesAndExpr &...args) { + return PArgl::expr(p, args...); + } +}; +template struct PArgl { + static str::seq names(const std::string &x, const NamesAndExpr &...args) { + str::seq r = PArgl::names(args...); + r.insert(r.begin(), x); + return r; + } + static ExprPtr expr(const ExprParser &p, const std::string &, + const NamesAndExpr &...args) { + return PArgl::expr(p, args...); + } +}; // the main compiler class cc : public typedb { @@ -84,164 +99,204 @@ public: virtual ~cc(); // parse expressions - typedef ModulePtr (*readModuleFileFn)(cc*, const std::string&); - ModulePtr readModuleFile(const std::string&); + using readModuleFileFn = ModulePtr (*)(cc *, const std::string &); + ModulePtr readModuleFile(const std::string &); void setReadModuleFileFn(readModuleFileFn); - typedef ModulePtr (*readModuleFn)(cc*, const std::string&); - ModulePtr readModule(const std::string&); + using readModuleFn = ModulePtr (*)(cc *, const std::string &); + ModulePtr readModule(const std::string &); void setReadModuleFn(readModuleFn); - typedef std::pair (*readExprDefnFn)(cc*, const std::string&); - std::pair readExprDefn(const std::string&); + using readExprDefnFn = std::pair (*)(cc *, const std::string &); + std::pair readExprDefn(const std::string &); void setReadExprDefnFn(readExprDefnFn); - typedef ExprPtr (*readExprFn)(cc*, const std::string&); - ExprPtr readExpr(const std::string&); - MonoTypePtr readMonoType(const std::string&); + using readExprFn = ExprPtr (*)(cc *, const std::string &); + ExprPtr readExpr(const std::string &); + MonoTypePtr readMonoType(const std::string &); void setReadExprFn(readExprFn); + struct UnreachableMatches { + LexicalAnnotation la; + std::string lines; + }; + using gatherUnreachableMatchesFn = void (*)(const UnreachableMatches &); + void gatherUnreachableMatches(const UnreachableMatches &m); + void setGatherUnreachableMatchesFn(gatherUnreachableMatchesFn f); + // search for paths from one type to another // (currently just one-step paths, may be useful to consider multi-step paths) - SearchEntries search(const MonoTypePtr&, const MonoTypePtr&); - SearchEntries search(const ExprPtr&, const MonoTypePtr&); - SearchEntries search(const std::string&, const MonoTypePtr&); - SearchEntries search(const std::string&, const std::string&); + SearchEntries search(const MonoTypePtr &, const MonoTypePtr &); + SearchEntries search(const ExprPtr &, const MonoTypePtr &); + SearchEntries search(const std::string &, const MonoTypePtr &); + SearchEntries search(const std::string &, const std::string &); + private: // parser functions readModuleFileFn readModuleFileF; - readModuleFn readModuleF; - readExprDefnFn readExprDefnF; - readExprFn readExprF; + readModuleFn readModuleF; + readExprDefnFn readExprDefnF; + readExprFn readExprF; + + gatherUnreachableMatchesFn gatherUnreachableMatchesF = + [](const UnreachableMatches &) {}; + public: // type-safe compilation to C++ function pointers - template - typename func::type compileFn(NamesAndExpr ... args) { - static_assert(func::arity == sizeof...(NamesAndExpr)-1, "Formal parameter list and expected function type arity mismatch"); - return rcast::type>( - unsafeCompileFn( - lift::type(*this), - PArgl::names(args...), - PArgl::expr([&](const std::string& x){return this->readExpr(x);}, args...) - ) - ); - } + template + typename func::type compileFn(NamesAndExpr... args) { + static_assert( + func::arity == sizeof...(NamesAndExpr) - 1, + "Formal parameter list and expected function type arity mismatch"); + return rcast::type>(unsafeCompileFn( + lift::type(*this), PArgl::names(args...), + PArgl::expr( + [&](const std::string &x) { return this->readExpr(x); }, args...))); + } + + template + boolSafeFn compileSafeFn(NamesAndExpr &&...args) { + return {this->template compileFn(std::forward(args)...)}; + } // perform type-checking, explicit type annotation, and type class resolution - ExprPtr unsweetenExpression(const TEnvPtr& te, const ExprPtr& e); - ExprPtr unsweetenExpression(const TEnvPtr& te, const std::string& vname, const ExprPtr& e); - ExprPtr unsweetenExpression(const ExprPtr& e); - ExprPtr unsweetenExpression(const std::string& vname, const ExprPtr& e); - ExprPtr normalize(const ExprPtr& e); // unalias + unsweeten + ExprPtr unsweetenExpression(const TEnvPtr &te, const ExprPtr &e); + ExprPtr unsweetenExpression(const TEnvPtr &te, const std::string &vname, + const ExprPtr &e); + ExprPtr unsweetenExpression(const ExprPtr &e); + ExprPtr unsweetenExpression(const std::string &vname, const ExprPtr &e); + ExprPtr normalize(const ExprPtr &e); // unalias + unsweeten // access the LLVM resources - llvm::IRBuilder<>* builder() const; - llvm::Module* module() const; + llvm::IRBuilder<> *builder() const; + llvm::Module *module() const; // dump the contents of the active type environment (useful for debugging) - void dumpTypeEnv(std::function const& = [](std::string const& binding) -> std::string const& { return binding; }) const; - void dumpTypeEnv(str::seq* syms, str::seq* types, std::function const& = [](std::string const& binding) -> std::string const& { return binding; }) const; - std::string showTypeEnv(std::function const& = [](std::string const& binding) -> std::string const& { return binding; }) const; - - const TEnvPtr& typeEnv() const; + void + dumpTypeEnv(std::function const & = + [](std::string const &binding) -> std::string const & { + return binding; + }) const; + void dumpTypeEnv( + str::seq *syms, str::seq *types, + std::function const & = + [](std::string const &binding) -> std::string const & { + return binding; + }) const; + std::string + showTypeEnv(std::function const & = + [](std::string const &binding) -> std::string const & { + return binding; + }) const; + + const TEnvPtr &typeEnv() const; // forward-declare a variable binding - void forwardDeclare(const std::string& vname, const QualTypePtr& qt); + void forwardDeclare(const std::string &vname, const QualTypePtr &qt); // is a variable merely forward-declared, or does it have a definition? - bool hasValueBinding(const std::string& vname); - - // process and define a set of residual definitions produced by type unqualification + bool hasValueBinding(const std::string &vname); + + // process and define a set of residual definitions produced by type + // unqualification bool drainingDefs; LetRec::Bindings drainDefs; - void drainUnqualifyDefs(const Definitions& ds); + void drainUnqualifyDefs(const Definitions &ds); // compile an expression and associate it with a name - void define(const std::string& vname, const ExprPtr& e); - void define(const std::string& vname, const std::string& expr); + void define(const std::string &vname, const ExprPtr &e); + void define(const std::string &vname, const std::string &expr); // shorthand for class instance definitions for classes with 0 or 1 members - void overload(const std::string&, const MonoTypes&); - void overload(const std::string&, const MonoTypes&, const ExprPtr&); - void overload(const std::string&, const MonoTypes&, const std::string&); + void overload(const std::string &, const MonoTypes &); + void overload(const std::string &, const MonoTypes &, const ExprPtr &); + void overload(const std::string &, const MonoTypes &, const std::string &); - // add a type class instance to a known class (wrap up recursive unsweetening/def-draining) - void addInstance(const TClassPtr&, const TCInstancePtr&); + // add a type class instance to a known class (wrap up recursive + // unsweetening/def-draining) + void addInstance(const TClassPtr &, const TCInstancePtr &); // dump the contents of the generated module (useful for debugging) void dumpModule(); // get the x86 machine code for an expression (useful for debugging) - typedef std::vector bytes; - bytes machineCodeForExpr(const std::string& expr); + using bytes = std::vector; + bytes machineCodeForExpr(const std::string &expr); // keep track of C++ classes so that we can perform upcasts where necessary - template - void addObj() { - hlock _; - this->objs->add(); - } + template void addObj() { + hlock _; + this->objs->add(); + } // convenience method for lifting C++ types - template - PolyTypePtr liftType() { - hlock _; - return generalize(lift::type(*this)); - } + template PolyTypePtr liftType() { + hlock _; + return generalize(lift::type(*this)); + } - template - MonoTypePtr liftMonoType() { - return lift::type(*this); - } + template MonoTypePtr liftMonoType() { + return lift::type(*this); + } // bind a C++ value (be sure it stays in scope!) - void bind(const PolyTypePtr& tn, const std::string& vn, void* x); + void bind(const PolyTypePtr &tn, const std::string &vn, void *x); - template - void bind(const std::string& vn, T* x) { - hlock _; - bind(generalize(liftValue::type(*this, x)), vn, rcast(x)); - } + template void bind(const std::string &vn, T *x) { + hlock _; + bind(generalize(liftValue::type(*this, x)), vn, rcast(x)); + } - template - void bindArr(const std::string& vn, T x[N]) { - hlock _; - bind(polytype(qualtype(arrayty(lift::type(*this), N))), vn, rcast(x)); - } + template void bindArr(const std::string &vn, T x[N]) { + hlock _; + bind(polytype(qualtype(arrayty(lift::type(*this), N))), vn, + rcast(x)); + } // simplify binding user functions - template - void bind(const std::string& fn, R (*pfn)(Args...)) { - hlock _; - bindExternFunction(fn, lift::type(*this), rcast(pfn)); - } + template + void bind(const std::string &fn, R (*pfn)(Args...)) { + hlock _; + bindExternFunction(fn, lift::type(*this), rcast(pfn)); + } + private: - typedef std::pair TTyDef; - typedef std::unordered_map TTyDefs; + using TTyDef = std::pair; + using TTyDefs = std::unordered_map; TTyDefs ttyDefs; + public: // allow the definition of transparent type aliases - // ("transparent" in the sense that all other aspects of compilation see the fully expanded type) - void defineTypeAlias(const std::string& name, const str::seq& argNames, const MonoTypePtr& ty); - bool isTypeAliasName(const std::string& name) const; - MonoTypePtr replaceTypeAliases(const MonoTypePtr& ty) const; + // ("transparent" in the sense that all other aspects of compilation see the + // fully expanded type) + void defineTypeAlias(const std::string &name, const str::seq &argNames, + const MonoTypePtr &ty) override; + bool isTypeAliasName(const std::string &name) const override; + MonoTypePtr replaceTypeAliases(const MonoTypePtr &ty) const override; // typedb interface - PolyTypePtr opaquePtrPolyType(const std::type_info& ti, unsigned int sz, bool inStruct); - MonoTypePtr opaquePtrMonoType(const std::type_info& ti, unsigned int sz, bool inStruct); + PolyTypePtr opaquePtrPolyType(const std::type_info &ti, unsigned int sz, + bool inStruct) override; + MonoTypePtr opaquePtrMonoType(const std::type_info &ti, unsigned int sz, + bool inStruct) override; - PolyTypePtr generalize(const MonoTypePtr& mt) const; + PolyTypePtr generalize(const MonoTypePtr &mt) const override; - MonoTypePtr defineNamedType(const std::string& name, const str::seq& argNames, const MonoTypePtr& ty); - bool isTypeName(const std::string&) const; - MonoTypePtr namedTypeRepresentation(const std::string&) const; + MonoTypePtr defineNamedType(const std::string &name, const str::seq &argNames, + const MonoTypePtr &ty) override; + bool isTypeName(const std::string &) const override; + MonoTypePtr namedTypeRepresentation(const std::string &) const override; // an 'unsafe' compilation method - // (the compiled function will conform to the input type description, but this type structure will not be available to C++) - void* unsafeCompileFn(const MonoTypePtr& retTy, const str::seq& names, const MonoTypes& argTys, const ExprPtr& exp); - void* unsafeCompileFn(const MonoTypePtr& fnTy, const str::seq& names, const ExprPtr& exp); - void* unsafeCompileFn(const MonoTypePtr& fnTy, const str::seq& names, const std::string& exp); - void releaseMachineCode(void*); + // (the compiled function will conform to the input type description, but + // this type structure will not be available to C++) + void *unsafeCompileFn(const MonoTypePtr &retTy, const str::seq &names, + const MonoTypes &argTys, const ExprPtr &exp); + void *unsafeCompileFn(const MonoTypePtr &fnTy, const str::seq &names, + const ExprPtr &exp); + void *unsafeCompileFn(const MonoTypePtr &fnTy, const str::seq &names, + const std::string &exp); + void releaseMachineCode(void *); // compile/optimization options void enableModuleInlining(bool f); @@ -250,6 +305,8 @@ public: bool buildInterpretedMatches() const; void requireMatchReachability(bool f); bool requireMatchReachability() const; + void ignoreUnreachableMatches(bool f); + bool ignoreUnreachableMatches() const; void alwaysLowerPrimMatchTables(bool); bool alwaysLowerPrimMatchTables() const; void buildColumnwiseMatches(bool f); @@ -259,29 +316,31 @@ public: void throwOnHugeRegexDFA(bool f); bool throwOnHugeRegexDFA() const; void regexDFAOverNFAMaxRatio(int f); - int regexDFAOverNFAMaxRatio() const; + int regexDFAOverNFAMaxRatio() const; - // allow caller to gather a vector of unreachable rows arising from match compilation UnreachableMatchRowsPtr unreachableMatchRowsPtr; // allow low-level functions to be added - void bindLLFunc(const std::string&, op*); + void bindLLFunc(const std::string &, op *); // bind external functions - void bindExternFunction(const std::string& fname, const MonoTypePtr& fty, void* fn); + void bindExternFunction(const std::string &fname, const MonoTypePtr &fty, + void *fn); // allocate global data - void* memalloc(size_t, size_t); - - template - array* makeArray(size_t n) { - auto* r = reinterpret_cast*>(this->memalloc(sizeof(long) + (sizeof(T) * n), std::max(sizeof(long), alignof(T)))); - r->size = n; - if (r->size > 0) { - new (r->data) T[r->size]; - } - return r; + void *memalloc(size_t, size_t); + + template array *makeArray(size_t n) { + auto *r = reinterpret_cast *>( + this->memalloc(sizeof(long) + (sizeof(T) * n), + std::max(sizeof(long), alignof(T)))); + r->size = n; + if (r->size > 0) { + new (r->data) T[r->size]; } + return r; + } + private: // cache for expression search results SearchCache searchCache; @@ -290,63 +349,64 @@ private: bool runModInlinePass; bool genInterpretedMatch; bool checkMatchReachability; + bool ignoreUnreachablePatternMatchRows = false; bool lowerPrimMatchTables; bool columnwiseMatches; - size_t maxExprDFASize={1000}; - // abort compilation of regexes which translate into huge dfa transition states + size_t maxExprDFASize = {1000}; + // abort compilation of regexes which translate into huge dfa transition + // states bool shouldThrowOnHugeRegexDFA = false; - int dfaOverNfaMaxRatio = 4; + int dfaOverNfaMaxRatio = 4; // the bound root type-def environment - typedef std::map TypeAliasMap; + using TypeAliasMap = std::map; - TEnvPtr tenv; + TEnvPtr tenv; TypeAliasMap typeAliases; - PolyTypePtr lookupVarType(const std::string& vname) const; + PolyTypePtr lookupVarType(const std::string &vname) const; // global variables - void definePolyValue(const std::string& vname, const ExprPtr& unsweetExp); + void definePolyValue(const std::string &vname, const ExprPtr &unsweetExp); // track C++ object relationships ObjsPtr objs; // the JIT engine that compiles our monotyped expressions - jitcc* jit; + jitcc *jit; + public: // compiler-local type structure caches for internal use - std::unordered_map unappTyDefns; -private: - // disable copying - cc(const cc&); - void operator=(const cc&); + std::unordered_map unappTyDefns; + + cc(const cc &) = delete; + void operator=(const cc &) = delete; }; #define LIFTCTY(cc, e) (cc).liftMonoType() -template - struct rccF { - static T compile(cc*, const str::seq&, const std::string&) { - throw std::runtime_error("Internal error, unsupported compilation target type"); - } - }; - -template - struct rccF { - typedef R (*cbF)(Args...); - static cbF compile(cc* c, const str::seq& vns, const std::string& expr) { - return rcast(c->unsafeCompileFn(lift::type(*c), vns, expr)); - } - }; +template struct rccF { + static T compile(cc *, const str::seq &, const std::string &) { + throw std::runtime_error( + "Internal error, unsupported compilation target type"); + } +}; -template - T compileTo(cc* c, const str::seq& vns, const std::string& expr) { - return rccF::compile(c, vns, expr); +template struct rccF { + using cbF = R (*)(Args...); + static cbF compile(cc *c, const str::seq &vns, const std::string &expr) { + return rcast(c->unsafeCompileFn(lift::type(*c), vns, expr)); } +}; +template +T compileTo(cc *c, const str::seq &vns, const std::string &expr) { + return rccF::compile(c, vns, expr); } +} // namespace hobbes + // support binding to C++ class member functions -#define memberfn(e) &hobbes::mfnThunk< decltype(e), decltype(e), e >::fn +#define memberfn(e) &hobbes::mfnThunk::fn #endif diff --git a/include/hobbes/eval/cmodule.H b/include/hobbes/eval/cmodule.H index 3f183d532..b79a024b5 100644 --- a/include/hobbes/eval/cmodule.H +++ b/include/hobbes/eval/cmodule.H @@ -5,6 +5,8 @@ #include #include +#include + namespace hobbes { class cc; @@ -17,10 +19,12 @@ void pushModuleDir(const std::string&); void popModuleDir(); // compile a whole module into a cc context -void compile(cc*, const ModulePtr& m); +// once stopFn() is true, the compilation stops prematurely, +// cc is not valid anymore, all you can do is to destroy it +void compile(cc*, const ModulePtr& m, std::function stopFn=[] { return false; }); // set language options, display language options -typedef std::map OptDescs; +using OptDescs = std::map; OptDescs getAllOptions(); ExprPtr translateExprWithOpts(const ModulePtr&, const ExprPtr&); diff --git a/include/hobbes/eval/func.H b/include/hobbes/eval/func.H index 2d2243001..f0900f54f 100644 --- a/include/hobbes/eval/func.H +++ b/include/hobbes/eval/func.H @@ -16,11 +16,11 @@ inline bool hasPointerRep(const MonoTypePtr& t) { if (const OpaquePtr* op = is(rt)) { return !op->storedContiguously(); } - return is(rt) || is(rt) || is(rt) || is(rt) || is(rt); + return (is(rt) != nullptr) || (is(rt) != nullptr) || (is(rt) != nullptr) || (is(rt) != nullptr) || (is(rt) != nullptr); } inline bool hasPointerRep(const PolyTypePtr& t) { - if (t->typeVariables() > 0 || t->instantiate()->constraints().size() > 0) { + if (t->typeVariables() > 0 || !t->instantiate()->constraints().empty()) { return false; } else { return hasPointerRep(requireMonotype(t)); @@ -33,7 +33,7 @@ inline bool isLargeType(const MonoTypePtr& t) { if (const OpaquePtr* p = is(rt)) { return p->storedContiguously(); } else { - return is(rt) || is(rt) || is(rt); + return (is(rt) != nullptr) || (is(rt) != nullptr) || (is(rt) != nullptr); } } diff --git a/include/hobbes/eval/jitcc.H b/include/hobbes/eval/jitcc.H index c87ae3add..53e5527bf 100644 --- a/include/hobbes/eval/jitcc.H +++ b/include/hobbes/eval/jitcc.H @@ -10,10 +10,17 @@ #include #include +#if LLVM_VERSION_MAJOR >= 11 +#include +#endif #include #include #include +namespace llvm { +class GlobalVariable; +} + namespace hobbes { // an operation, which can emit some specialized assembly code @@ -29,6 +36,13 @@ struct op { virtual llvm::Value* apply(jitcc* ev, const MonoTypes& tys, const MonoTypePtr& rty, const Exprs& es) = 0; }; +#if LLVM_VERSION_MAJOR >= 11 +class ORCJIT; +class Globals; +class VTEnv; +class ConstantList; +#endif + // a JIT compiler for monotyped expressions class jitcc { public: @@ -42,14 +56,16 @@ public: // get the address of a bound symbol void* getSymbolAddress(const std::string&); +#if LLVM_VERSION_MAJOR < 11 // print all module contents void dump() const; +#endif // define a global from a primitive expression void defineGlobal(const std::string& vname, const ExprPtr& unsweetExp); // define a global on some existing memory - void bindGlobal(const std::string& vn, const MonoTypePtr& ty, void* v); + void bindGlobal(const std::string& vn, const MonoTypePtr& ty, void* x); // is there a definition of the named symbol? bool isDefined(const std::string&) const; @@ -103,7 +119,7 @@ public: llvm::Value* internConstString(const std::string&); // get the machine code produced for a given expression - typedef std::vector bytes; + using bytes = std::vector; bytes machineCodeForExpr(const ExprPtr&); // inline all global definitions within an expression @@ -115,46 +131,56 @@ private: TEnvPtr tenv; // produce some machine code for a compiled function - void* getMachineCode(llvm::Function*, llvm::JITEventListener* listener = 0); + void* getMachineCode(llvm::Function*, llvm::JITEventListener* listener = nullptr); +#if LLVM_VERSION_MAJOR >= 11 + std::unique_ptr currentModule; +#else // the current non-finalized module // (new definitions will be accumulated here) // (may be null, to lazily allocate modules) - llvm::Module* currentModule; + llvm::Module* currentModule = nullptr; +#endif +#if LLVM_VERSION_MAJOR < 11 // the set of allocated modules typedef std::vector Modules; Modules modules; +#endif -#if LLVM_VERSION_MINOR == 6 || LLVM_VERSION_MINOR == 7 || LLVM_VERSION_MINOR == 8 || LLVM_VERSION_MAJOR == 4 || LLVM_VERSION_MAJOR <= 11 - llvm::legacy::PassManager* mpm; +#if LLVM_VERSION_MAJOR >= 11 +#else +#if LLVM_VERSION_MINOR == 6 || LLVM_VERSION_MINOR == 7 || LLVM_VERSION_MINOR == 8 || LLVM_VERSION_MAJOR == 4 || LLVM_VERSION_MAJOR <= 12 // the set of allocated execution engines (each will own a finalized module from the set of modules) typedef std::vector ExecutionEngines; ExecutionEngines eengines; #elif LLVM_VERSION_MINOR == 3 - llvm::PassManager* mpm; llvm::ExecutionEngine* eengine; llvm::FunctionPassManager* fpm; #elif LLVM_VERSION_MINOR == 5 - llvm::legacy::PassManager* mpm; llvm::ExecutionEngine* eengine; llvm::legacy::FunctionPassManager* fpm; #else #error "This version of LLVM is not supported" +#endif #endif // support incremental construction of LLVM assembly sequences - llvm::IRBuilder<>* irbuilder; + std::unique_ptr> irbuilder; // the bound root function environment - typedef std::map FuncEnv; + using FuncEnv = std::map; FuncEnv fenv; // keep track of variables and local scopes during compilation +#if LLVM_VERSION_MAJOR >= 11 + std::unique_ptr vtenv; +#else typedef std::map VarBindings; typedef std::vector VarBindingStack; VarBindingStack vtenv; +#endif bool ignoreLocalScope; // compile sets of mutually-recursive functions (as a special case, single-function compilation) @@ -169,10 +195,13 @@ private: inline UCF(const std::string& name, const str::seq& argns, const MonoTypes& argtys, const ExprPtr& exp) : name(name), argns(argns), argtys(argtys), exp(exp) { } }; - typedef std::vector UCFS; + using UCFS = std::vector; void unsafeCompileFunctions(UCFS*); // keep track of global variables +#if LLVM_VERSION_MAJOR >= 11 + std::unique_ptr globals; +#else struct Global { MonoTypePtr type; void* value; @@ -183,6 +212,7 @@ private: }; typedef std::map Globals; Globals globals; +#endif // keep track of global data (in case we need to dynamically allocate global variables of any type) region globalData; @@ -190,6 +220,9 @@ private: void popGlobalRegion(size_t x); // keep track of global constants +#if LLVM_VERSION_MAJOR >= 11 + std::unique_ptr constants; +#else struct Constant { llvm::Constant* value; llvm::Type* type; @@ -198,28 +231,39 @@ private: }; typedef std::map Constants; Constants constants; +#endif llvm::Value* loadConstant(const std::string&); // keep some interned strings, helpful for global constants and debug info - typedef std::unordered_map InternConstVars; + using InternConstVars = std::unordered_map; InternConstVars internConstVars; +#if LLVM_VERSION_MAJOR >= 11 + llvm::GlobalVariable* lookupGlobalVar(const std::string&); +#else // try to load a symbol as a global (may return nullptr if this can't be done) llvm::GlobalVariable* maybeRefGlobal(const std::string&); llvm::GlobalVariable* refGlobal(const std::string&, llvm::GlobalVariable*); +#endif +#if LLVM_VERSION_MAJOR < 11 // pass through a value if it's not a global or if it's a global in the current module // else wrap it in an extern decl llvm::Value* maybeRefGlobalV(llvm::Value*); +#endif // keep track of monotyped definitions as expressions // (in case we want to inline them later) - typedef std::map GlobalExprs; + using GlobalExprs = std::map; GlobalExprs globalExprs; + +#if LLVM_VERSION_MAJOR >= 11 + std::unique_ptr orcjit; +#endif }; // shorthand for compilation over a sequence of expressions -typedef std::vector Values; +using Values = std::vector; Values compile(jitcc*, const Exprs&); Values compileArgs(jitcc*, const Exprs&); diff --git a/include/hobbes/eval/orcjitcc.H b/include/hobbes/eval/orcjitcc.H new file mode 100644 index 000000000..8a5b9b937 --- /dev/null +++ b/include/hobbes/eval/orcjitcc.H @@ -0,0 +1,49 @@ +#ifndef HOBBES_EVAL_ORCJITCC_HPP_INCLUDED +#define HOBBES_EVAL_ORCJITCC_HPP_INCLUDED + +#include + +#if LLVM_VERSION_MAJOR >= 11 +#include +#include +#include +#include + +#include + +namespace llvm { +class Module; +namespace orc { +class LLLazyJIT; +class MaterializationResponsibility; +class MangleAndInterner; +} // namespace orc +} // namespace llvm + +namespace hobbes { + +class ORCJIT { +public: + ORCJIT(); + ORCJIT(const ORCJIT &) = delete; + ORCJIT(ORCJIT &&) = delete; + ORCJIT &operator=(const ORCJIT &) = delete; + ORCJIT &operator=(ORCJIT &&) = delete; + ~ORCJIT(); + + llvm::Error addModule(std::unique_ptr m); + + LLVM_NODISCARD llvm::Expected + lookup(llvm::StringRef name); + + llvm::Error addExternalNonCallableSymbol(llvm::StringRef name, void *ptr); + llvm::Error addExternalCallableSymbol(llvm::StringRef name, void *ptr); + +private: + std::unique_ptr jit; + std::unique_ptr mangle; +}; +} // namespace hobbes + +#endif +#endif diff --git a/include/hobbes/eval/search.H b/include/hobbes/eval/search.H index c73b1f6f5..58d1f7e53 100644 --- a/include/hobbes/eval/search.H +++ b/include/hobbes/eval/search.H @@ -15,7 +15,7 @@ struct SearchEntry { std::string sym; // a symbol matching a user query MonoTypePtr ty; // the exact result type given by this symbol }; -typedef std::vector SearchEntries; +using SearchEntries = std::vector; struct SearchCache { std::map univByType; diff --git a/include/hobbes/events/events.H b/include/hobbes/events/events.H index 36a1f0b52..3a8c0d636 100644 --- a/include/hobbes/events/events.H +++ b/include/hobbes/events/events.H @@ -10,10 +10,10 @@ namespace hobbes { // add a read event handler for a file descriptor -typedef void (*eventhandler)(int fd, void* ud); +using eventhandler = void (*)(int, void *); // return true to automatically repeat after an interval -typedef bool (*timerfunc)(); +using timerfunc = bool (*)(); void addTimer(timerfunc f, int millisecInterval); @@ -23,11 +23,14 @@ void unregisterEventHandler(int fd); void registerInterruptHandler(const std::function& fn); // run a single-step or indefinite event loop -bool stepEventLoop(int timeoutMS = -1); -void runEventLoop(); +bool stepEventLoop(int timeoutMS = -1, const std::function& stopFn = [] { return false; }); +// if stopFn is user defined, a repeatable timer *MUST* be added to trigger the check on stopFn() +// hobbes::addTimer([] { return true; /* repeatable */}, myTimeout); +// hobbes::runEventLoop(myStopFn); +void runEventLoop(const std::function& stopFn = [] { return false; }); // run the event loop for some number of microseconds -void runEventLoop(int microsecondDuration); +void runEventLoop(int microsecondDuration, const std::function& stopFn = [] { return false; }); } diff --git a/include/hobbes/events/httpd.H b/include/hobbes/events/httpd.H index ef4655ea6..f6a4e7d24 100644 --- a/include/hobbes/events/httpd.H +++ b/include/hobbes/events/httpd.H @@ -12,8 +12,8 @@ namespace hobbes { struct HTTPRequest { - typedef std::map Headers; - typedef std::vector Data; + using Headers = std::map; + using Data = std::vector; std::string method; std::string document; @@ -21,9 +21,9 @@ struct HTTPRequest { Data data; }; -typedef void (*HTTPRequestHandler)(const HTTPRequest&, int fd, void* ud); +using HTTPRequestHandler = void (*)(const HTTPRequest &, int, void *); -int installHTTPD(int port, HTTPRequestHandler, void* ud = 0); +int installHTTPD(int port, HTTPRequestHandler, void* ud = nullptr); } diff --git a/include/hobbes/fregion.H b/include/hobbes/fregion.H index 24a4b8988..ceddd78b5 100644 --- a/include/hobbes/fregion.H +++ b/include/hobbes/fregion.H @@ -48,13 +48,13 @@ #include #include -#include -#include -#include +#include +#include #include +#include +#include +#include #include -#include -#include // filesystem waits depend on platform details #include @@ -106,10 +106,10 @@ struct pagedata { void type(pagetype::code x) { this->ptfd = encode(x, availBytes()); } void availBytes(uint16_t x) { this->ptfd = encode(type(), x); } }; -typedef std::vector pagetable; +using pagetable = std::vector; // the index of a page of data in the underlying file -typedef uint64_t file_pageindex_t; +using file_pageindex_t = uint64_t; // convenience for raising errors out of errno inline void raiseSysError [[noreturn]] (const std::string& msg, const std::string& fname) { @@ -118,7 +118,7 @@ inline void raiseSysError [[noreturn]] (const std::string& msg, const std::strin throw std::runtime_error(ss.str()); } -typedef std::vector bytes; +using bytes = std::vector; // a stored name/value binding struct binding { @@ -129,7 +129,7 @@ struct binding { size_t boffset; // where is this binding data stored in the file? }; -typedef std::map bindingset; +using bindingset = std::map; // a mem-mapped file region struct fregion { @@ -140,7 +140,7 @@ struct fregion { }; // account for mappings by absolute page -typedef std::map fmappings; +using fmappings = std::map; // remember which mapped sections correspond to which pages struct falloc { @@ -148,11 +148,11 @@ struct falloc { size_t size; // the number of bytes allocated to this thing }; -typedef std::map fallocs; +using fallocs = std::map; // fast page searches (to avoid linear searches of the entire page table) -typedef std::vector pageseq; -typedef std::map ptyorder; +using pageseq = std::vector; +using ptyorder = std::map; // an image file, opened either for reading or writing struct imagefile { @@ -262,6 +262,9 @@ template } template inline void writes(imagefile* f, TIter begin, TIter end) { + if (begin == end) { + return; + } fdwrite(f, reinterpret_cast(&(*begin)), (end - begin) * sizeof(*begin)); } inline void write(imagefile* f, const std::string& x) { @@ -420,7 +423,7 @@ template // try to find a page with as much free space as requested inline bool findPageWithSpace(imagefile* f, pagetype::code pt, size_t datalen, size_t alignment, file_pageindex_t* idx) { const pageseq& pord = f->freespace[pt]; - if (pord.size() == 0) { + if (pord.empty()) { return false; } @@ -511,7 +514,7 @@ inline void appendTOCData(imagefile* f, const pagetable& newpages) { } // if we added TOC pages while writing the input TOC entries, then TOC entries for those TOC pages need to be added too - if (newtocpages.size() > 0) { + if (!newtocpages.empty()) { appendTOCData(f, newtocpages); } } @@ -526,7 +529,7 @@ inline size_t findSpace(imagefile* f, pagetype::code pt, size_t datalen, size_t if (findPageWithSpace(f, pt, datalen, alignment, &fpage)) { pagedata& pd = f->pages[fpage]; - uint64_t offset = align(f->page_size - pd.availBytes(), alignment); + auto offset = align(f->page_size - pd.availBytes(), alignment); updateTOCData(f, fpage, pagedata(pt, f->page_size - (offset+datalen))); return position(f, fpage, offset); @@ -584,7 +587,7 @@ inline void addBinding(imagefile* f, const std::string& vname, const bytes& type // mmap a region out of this file inline fregion& createFileRegionMap(imagefile* f, file_pageindex_t page, size_t pages) { // leave no gaps in page mappings - if (f->mappings.size() > 0) { + if (!f->mappings.empty()) { fregion& mr = f->mappings.rbegin()->second; size_t pend = mr.base_page + mr.pages; @@ -598,7 +601,7 @@ inline fregion& createFileRegionMap(imagefile* f, file_pageindex_t page, size_t pages = align(pages, f->mmapPageMultiple); // map the specified file region into memory - char* d = reinterpret_cast(mmap(0, pages * f->page_size, PROT_READ | (f->readonly ? 0 : PROT_WRITE), MAP_SHARED, f->fd, page * f->page_size)); + char* d = reinterpret_cast(mmap(nullptr, pages * f->page_size, PROT_READ | (f->readonly ? 0 : PROT_WRITE), MAP_SHARED, f->fd, page * f->page_size)); if (d == MAP_FAILED) { raiseSysError ( @@ -644,7 +647,7 @@ template // find the mapping data for a region, or create it if necessary inline fregion& mappedFileRegion(imagefile* f, file_pageindex_t page, size_t pages) { // try to find the nearest possible mapping for this page - fmappings::iterator fm = gleb(f->mappings, page); + auto fm = gleb(f->mappings, page); // if we couldn't find a mapping, then we have to make one if (fm == f->mappings.end()) { @@ -688,7 +691,7 @@ inline char* mapFileData(imagefile* f, size_t fpos, size_t sz) { // deallocate memory mapped out of this file // (if this means that there are no outstanding references to the mapping, then the mapping itself is released) inline void unmapFileData(imagefile* f, const void* p, size_t sz) { - fallocs::iterator fa = f->allocs.find(const_cast(reinterpret_cast(p))); + auto fa = f->allocs.find(const_cast(reinterpret_cast(p))); if (fa == f->allocs.end()) { return; } @@ -699,7 +702,7 @@ inline void unmapFileData(imagefile* f, const void* p, size_t sz) { // dereference these bytes from the page mapping // if the page mapping has no references, we can remove the page mapping too - fmappings::iterator fm = f->mappings.find(dpage); + auto fm = f->mappings.find(dpage); if (fm == f->mappings.end()) { throw std::runtime_error("Internal error, inconsistent file mapping state"); } @@ -812,7 +815,7 @@ inline size_t readEnvironmentPage(imagefile* f, file_pageindex_t p) { // page is filled up to and including the last byte (otherwise we'd mistakenly // assume that we have to continue reading from the next page) size_t pos = filePosition(f) - 1; - file_pageindex_t tpage = file_pageindex_t(pos / f->page_size); + auto tpage = file_pageindex_t(pos / f->page_size); uint16_t rpos = (pos % f->page_size) + 1; if (rpos == (f->page_size - f->pages[tpage].availBytes())) { @@ -868,7 +871,7 @@ inline void readFile(imagefile* f, uint16_t minVersion, uint16_t maxVersion) { // open a file, or create it if necessary inline imagefile* openFile(const std::string& fname, bool readonly, uint16_t minVersion = HFREGION_CURRENT_FILE_FORMAT_VERSION, uint16_t maxVersion = HFREGION_CURRENT_FILE_FORMAT_VERSION, size_t mmapPageMultiple = 262144 /* 1GB */) { - imagefile* f = new imagefile(); + auto* f = new imagefile(); f->path = fname; f->readonly = readonly; f->mmapPageMultiple = mmapPageMultiple; @@ -915,7 +918,7 @@ inline imagefile* openFile(const std::string& fname, bool readonly, uint16_t min // does this file even represent a structured data file? // we'll say yes if it can be opened, it has the magic number, and its size is a multiple of its page size inline bool isFRegion(const std::string& fname) { - imagefile* f = new imagefile(); + auto* f = new imagefile(); f->path = fname; f->readonly = true; @@ -1221,11 +1224,11 @@ template <> static size_t alignment() { return sizeof(size_t); } static void write(imagefile* f, void* p, const std::string& x) { - if (x.size() > 0) { + if (!x.empty()) { auto bc = sizeof(size_t) + x.size(); size_t dloc = findSpace(f, pagetype::data, bc, sizeof(size_t)); - uint8_t* d = reinterpret_cast(mapFileData(f, dloc, bc)); + auto* d = reinterpret_cast(mapFileData(f, dloc, bc)); *reinterpret_cast(d) = x.size(); memcpy(d+sizeof(size_t), x.data(), x.size()); unmapFileData(f, d, bc); @@ -1237,7 +1240,7 @@ template <> } static void read (imagefile* f, const void* p, std::string* x) { auto dloc = *reinterpret_cast(p); - size_t* c = reinterpret_cast(mapFileData(f, dloc, sizeof(size_t))); + auto* c = reinterpret_cast(mapFileData(f, dloc, sizeof(size_t))); char* s = reinterpret_cast(mapFileData(f, dloc+sizeof(size_t), *c)); x->assign(s, s + *c); @@ -1258,11 +1261,11 @@ template struct store, typename tbool::can_memcpy>::type> : public storeVectorDef { static const bool can_memcpy = false; static void write(imagefile* f, void* p, const std::vector& x) { - if (x.size() > 0) { + if (!x.empty()) { auto bc = sizeof(size_t) + sizeof(T)*x.size(); size_t dloc = findSpace(f, pagetype::data, bc, sizeof(size_t)); - uint8_t* d = reinterpret_cast(mapFileData(f, dloc, bc)); + auto* d = reinterpret_cast(mapFileData(f, dloc, bc)); *reinterpret_cast(d) = x.size(); memcpy(d+sizeof(size_t), &x[0], sizeof(T)*x.size()); unmapFileData(f, d, bc); @@ -1274,8 +1277,8 @@ template } static void read(imagefile* f, const void* p, std::vector* x) { auto dloc = *reinterpret_cast(p); - size_t* c = reinterpret_cast(mapFileData(f, dloc, sizeof(size_t))); - uint8_t* d = reinterpret_cast(mapFileData(f, dloc+sizeof(size_t), *c * sizeof(T))); + auto* c = reinterpret_cast(mapFileData(f, dloc, sizeof(size_t))); + auto* d = reinterpret_cast(mapFileData(f, dloc+sizeof(size_t), *c * sizeof(T))); x->resize(*c); memcpy(reinterpret_cast(&(*x)[0]), d, *c * sizeof(T)); @@ -1288,15 +1291,15 @@ template struct store, typename tbool::can_memcpy>::type> : public storeVectorDef { static const bool can_memcpy = false; static void write(imagefile* f, void* p, const std::vector& x) { - if (x.size() > 0) { + if (!x.empty()) { size_t tsz = store::size(); auto bc = sizeof(size_t) + tsz*x.size(); size_t dloc = findSpace(f, pagetype::data, bc, sizeof(size_t)); - uint8_t* d = reinterpret_cast(mapFileData(f, dloc, bc)); + auto* d = reinterpret_cast(mapFileData(f, dloc, bc)); *reinterpret_cast(d) = x.size(); - auto dc = d + sizeof(size_t); + auto *dc = d + sizeof(size_t); for (const auto& xv : x) { store::write(f, dc, xv); dc += tsz; @@ -1311,8 +1314,8 @@ template static void read(imagefile* f, const void* p, std::vector* x) { size_t tsz = store::size(); auto dloc = *reinterpret_cast(p); - size_t* c = reinterpret_cast(mapFileData(f, dloc, sizeof(size_t))); - uint8_t* d = reinterpret_cast(mapFileData(f, dloc+sizeof(size_t), *c * tsz)); + auto* c = reinterpret_cast(mapFileData(f, dloc, sizeof(size_t))); + auto* d = reinterpret_cast(mapFileData(f, dloc+sizeof(size_t), *c * tsz)); uint8_t* dc = d; x->resize(*c); @@ -1331,14 +1334,14 @@ template <> struct store> : public storeVectorDef { static const bool can_memcpy = false; static void write(imagefile* f, void* p, const std::vector& x) { - if (x.size() > 0) { + if (!x.empty()) { auto bc = sizeof(size_t) + x.size(); size_t dloc = findSpace(f, pagetype::data, bc, sizeof(size_t)); - uint8_t* d = reinterpret_cast(mapFileData(f, dloc, bc)); + auto* d = reinterpret_cast(mapFileData(f, dloc, bc)); *reinterpret_cast(d) = x.size(); - auto dc = d + sizeof(size_t); + auto *dc = d + sizeof(size_t); for (const auto& xv : x) { store::write(f, dc, xv); dc += 1; @@ -1352,8 +1355,8 @@ template <> } static void read(imagefile* f, const void* p, std::vector* x) { auto dloc = *reinterpret_cast(p); - size_t* c = reinterpret_cast(mapFileData(f, dloc, sizeof(size_t))); - uint8_t* d = reinterpret_cast(mapFileData(f, dloc+sizeof(size_t), *c)); + auto* c = reinterpret_cast(mapFileData(f, dloc, sizeof(size_t))); + auto* d = reinterpret_cast(mapFileData(f, dloc+sizeof(size_t), *c)); uint8_t* dc = d; x->resize(*c); @@ -1401,10 +1404,10 @@ template // store tuples template struct storeTupleDef { - typedef typename nth::type H; - typedef tuple TT; - typedef typename TT::offs offs; - typedef storeTupleDef Recurse; + using H = typename nth::type; + using TT = tuple; + using offs = typename TT::offs; + using Recurse = storeTupleDef; static void fieldDefs(size_t offset, ty::Struct::Fields* fs) { offset = align(offset, store::alignment()); @@ -1449,7 +1452,7 @@ template template struct store, typename tbool::value>::type> : public storeTupleDef<0, sizeof...(Ts), Ts...> { static const bool can_memcpy = false; - typedef storeTupleDef<0, sizeof...(Ts), Ts...> Reflect; + using Reflect = storeTupleDef<0, sizeof...(Ts), Ts...>; static void write(imagefile* f, void* p, const tuple& x) { Reflect::incrWrite(f, p, x); @@ -1526,8 +1529,8 @@ struct writeFieldF { template void visit(const char*) { - size_t ooff = align(this->ooffset, store::alignment()); - size_t ioff = align(this->ioffset, alignof(T)); + auto ooff = align(this->ooffset, store::alignment()); + auto ioff = align(this->ioffset, alignof(T)); store::write(this->f, this->o + ooff, *reinterpret_cast(this->i + ioff)); @@ -1545,8 +1548,8 @@ struct readFieldF { template void visit(const char*) { - size_t ioff = align(this->ioffset, store::alignment()); - size_t ooff = align(this->ooffset, alignof(T)); + auto ioff = align(this->ioffset, store::alignment()); + auto ooff = align(this->ooffset, alignof(T)); store::read(this->f, this->i + ioff, reinterpret_cast(this->o + ooff)); @@ -1587,9 +1590,9 @@ template // store variants template struct storeVariantDef { - typedef typename nth::type H; - typedef variant VT; - typedef storeVariantDef Recurse; + using H = typename nth::type; + using VT = variant; + using Recurse = storeVariantDef; static void ctorDefs(ty::Variant::Ctors* cs) { cs->push_back(ty::Variant::Ctor(".f" + hobbes::string::from(i), static_cast(i), store::storeType())); @@ -1636,7 +1639,7 @@ template template struct store, typename tbool::value>::type> : public storeVariantDef<0, sizeof...(Ts), Ts...> { static const bool can_memcpy = false; - typedef storeVariantDef<0, sizeof...(Ts), Ts...> Reflect; + using Reflect = storeVariantDef<0, sizeof...(Ts), Ts...>; static void write(imagefile* f, void* p, const variant& x) { x.template apply(f, p, Reflect::tagOffset()); @@ -1690,7 +1693,7 @@ struct calcVSizeF { template struct store::type> { - typedef typename T::as_variant_type VT; + using VT = typename T::as_variant_type; static const bool can_memcpy = store::can_memcpy; static ty::desc storeType() { @@ -1710,7 +1713,7 @@ template // store opaque type aliases template struct store::type> { - typedef typename T::type RT; + using RT = typename T::type; static ty::desc storeType() { return ty::prim(T::name(), store::storeType()); ; } @@ -1728,7 +1731,7 @@ template ***********************/ struct seriesi { - virtual ~seriesi() { } + virtual ~seriesi() = default; virtual const ty::desc& typeDef() const = 0; }; @@ -1774,10 +1777,9 @@ template } } } - ~wseries() { - } + ~wseries() = default; - const ty::desc& typeDef() const { return this->tdef; } + const ty::desc& typeDef() const override { return this->tdef; } const std::string& name() const { return this->seqname; } imagefile* file() const { return this->f; } @@ -1930,9 +1932,8 @@ template wsseq(imagefile* f, const std::string& n, Wss& ... wss) : log(f, n, 10000, seqVar::storeType(f, wss...)) { seqVar::setWriteCBs(0, [this](uint32_t id, uint64_t p){this->log(std::pair(id,p));}, wss...); } - ~wsseq() { - } - const ty::desc& typeDef() const { return this->log.typeDef(); } + ~wsseq() = default; + const ty::desc& typeDef() const override { return this->log.typeDef(); } private: wseries> log; }; @@ -2038,7 +2039,7 @@ public: size_t dloc = findSpace(this->f, pagetype::data, sizeof(size_t)+len*sizeof(T), std::max(sizeof(size_t), alignof(T))); addBinding(this->f, n, ty::encoding(ty::array(store::storeType())), dloc); - array* result = reinterpret_cast*>(mapFileData(this->f, dloc, sizeof(size_t)+len*sizeof(T))); + auto* result = reinterpret_cast*>(mapFileData(this->f, dloc, sizeof(size_t)+len*sizeof(T))); result->size = len; return result; } else { @@ -2053,7 +2054,7 @@ public: // optimistically map as much as needed for the requested array length // but make sure that the array is stored with the expected length - array* result = reinterpret_cast*>(mapFileData(this->f, b->second.offset, sizeof(size_t)+len*sizeof(T))); + auto* result = reinterpret_cast*>(mapFileData(this->f, b->second.offset, sizeof(size_t)+len*sizeof(T))); if (result->size != len) { unmapFileData(this->f, result, sizeof(size_t)+len*sizeof(T)); @@ -2077,7 +2078,7 @@ public: imagefile* fileData() { return this->f; } const imagefile* fileData() const { return this->f; } private: - typedef std::map wseriess; + using wseriess = std::map; imagefile* f; wseriess ss; }; @@ -2085,7 +2086,7 @@ private: // utility to wait for updates to a file (per platform) inline long fsWaitTickMS() { struct timeval t; - if (gettimeofday(&t, 0) == 0) { + if (gettimeofday(&t, nullptr) == 0) { return (t.tv_sec*1000)+(t.tv_usec/1000); } else { return 0; @@ -2163,7 +2164,7 @@ public: memset(&evt, 0, sizeof(evt)); evt.events = EPOLLIN | EPOLLPRI | EPOLLERR; evt.data.fd = this->ifd; - evt.data.ptr = 0; + evt.data.ptr = nullptr; if (epoll_ctl(this->ep, EPOLL_CTL_ADD, this->ifd, &evt) != 0) { throw std::runtime_error("Failed to add inotify FD to epoll set: " + std::string(strerror(errno))); @@ -2174,7 +2175,7 @@ public: close(this->ifd); } - int wait(int maxWaitMS) { + int wait(int maxWaitMS) const { if (maxWaitMS == 0) { return 0; } else if (maxWaitMS < 0) { @@ -2223,10 +2224,9 @@ template } rseries(imagefile* f, const std::string& seqname) : rseries(f, seqname, store::storeType(), loadBinding(f, seqname)) { } - ~rseries() { - } + ~rseries() = default; - const ty::desc& typeDef() const { return this->tdef; } + const ty::desc& typeDef() const override { return this->tdef; } imagefile* file() const { return this->f; } bool next(T* x, int maxWaitMS = 0 /* <0 : infinite wait, 0 : no wait, >0 : wait up to milliseconds */) { @@ -2247,7 +2247,7 @@ template file_watch fwatch; size_t batchSize; - const uint64_t* headLen; // the mapped array count + const uint64_t* headLen = nullptr; // the mapped array count const uint8_t* head; // pointer into mapped array data (advanced as we read) size_t headIndex; // read index into mapped array @@ -2279,7 +2279,7 @@ template // if we're in the left '()' case, our state is "null" // else our state can be set to load the 'carray T n' batch in this node - if (d[0]) { + if (d[0] != 0u) { this->headLen = reinterpret_cast(mapFileData(this->f, d[1], bsz)); this->head = reinterpret_cast(this->headLen) + sizeof(uint64_t); this->nextNodeRef = d[2]; @@ -2335,7 +2335,7 @@ template } } } - while ((maxWaitMS = fwatch.wait(maxWaitMS))); + while ((maxWaitMS = fwatch.wait(maxWaitMS)) != 0); // we just couldn't get there return false; @@ -2382,8 +2382,8 @@ public: return false; } private: - typedef std::map> VarDef; - typedef std::unordered_map> VarCtorBindings; + using VarDef = std::map>; + using VarCtorBindings = std::unordered_map>; struct LogDef { // the encoded ordering variant type and seq binding ty::desc tdesc; @@ -2515,24 +2515,24 @@ public: ); } else if (b->second.type == ty::encoding(ty::array(store::storeType()))) { // map the array length to determine how much to map for the array - const size_t* lenp = reinterpret_cast(mapFileData(this->f, b->second.offset, sizeof(size_t))); + const auto* lenp = reinterpret_cast(mapFileData(this->f, b->second.offset, sizeof(size_t))); size_t len = *lenp; // now that we know the stored length, we can map the array contents - const array* result = reinterpret_cast*>(mapFileData(this->f, b->second.offset, sizeof(size_t)+len*sizeof(T))); + const auto* result = reinterpret_cast*>(mapFileData(this->f, b->second.offset, sizeof(size_t)+len*sizeof(T))); // and we can get rid of the map segment for the len unmapFileData(this->f, lenp, sizeof(size_t)); return result; } else if (b->second.type == ty::encoding(ty::fileRef(ty::array(store::storeType())))) { - const size_t* offp = reinterpret_cast(mapFileData(this->f, b->second.offset, sizeof(size_t))); + const auto* offp = reinterpret_cast(mapFileData(this->f, b->second.offset, sizeof(size_t))); size_t off = *offp; unmapFileData(this->f, offp, sizeof(size_t)); - const size_t* lenp = reinterpret_cast(mapFileData(this->f, off, sizeof(size_t))); + const auto* lenp = reinterpret_cast(mapFileData(this->f, off, sizeof(size_t))); size_t len = *lenp; - const array* result = reinterpret_cast*>(mapFileData(this->f, off, sizeof(size_t)+len*sizeof(T))); + const auto* result = reinterpret_cast*>(mapFileData(this->f, off, sizeof(size_t)+len*sizeof(T))); unmapFileData(this->f, lenp, sizeof(size_t)); return result; } else { @@ -2548,7 +2548,7 @@ public: imagefile* fileData() { return this->f; } const imagefile* fileData() const { return this->f; } private: - typedef std::map rseriess; + using rseriess = std::map; imagefile* f; rseriess ss; }; diff --git a/include/hobbes/hobbes.H b/include/hobbes/hobbes.H index b42f203b7..28877000a 100644 --- a/include/hobbes/hobbes.H +++ b/include/hobbes/hobbes.H @@ -2,24 +2,29 @@ #ifndef HOBBES_MAIN_HPP_INCLUDED #define HOBBES_MAIN_HPP_INCLUDED -#include #include #include -#include -#include #include #include -#include +#include +#include +#include #include +#include + +#include +#include namespace hobbes { // type aliases for common types DEFINE_TYPE_ALIAS_AS(timespanT, timespan, int64_t); -inline uint64_t microseconds(const timespanT& ts) { return ts.value; } -inline uint64_t milliseconds(const timespanT& ts) { return microseconds(ts) / 1000; } -inline uint64_t seconds (const timespanT& ts) { return milliseconds(ts) / 1000; } +inline uint64_t microseconds(const timespanT &ts) { return ts.value; } +inline uint64_t milliseconds(const timespanT &ts) { + return microseconds(ts) / 1000; +} +inline uint64_t seconds(const timespanT &ts) { return milliseconds(ts) / 1000; } DEFINE_TYPE_ALIAS_AS(timeT, time, int64_t); DEFINE_TYPE_ALIAS_AS(datetimeT, datetime, int64_t); @@ -31,50 +36,50 @@ datetimeT datetimeAt(datetimeT, timeT); timespanT gmtoffset(datetimeT); // allocate some memory in the calling thread's memory pool -char* memalloc(size_t, size_t); +char *memalloc(size_t, size_t); // string representations, I/O -const array* makeString(const std::string& x); -std::string makeStdString(const array* x); +const array *makeString(const std::string &x); +std::string makeStdString(const array *x); -const array* makeString(region& m, const char* s); -const array* makeString(region& m, const std::string& s); -const array* makeString(region& m, const char* s, size_t len); -const array* makeString(const char* s, size_t len); +const array *makeString(region &m, const char *s); +const array *makeString(region &m, const std::string &s); +const array *makeString(region &m, const char *s, size_t len); +const array *makeString(const char *s, size_t len); -inline std::ostream& operator<<(std::ostream& out, const array* x) { +inline std::ostream &operator<<(std::ostream &out, const array *x) { out.write(x->data, x->size); return out; } // allocate an array at some type, with some length -template - array* defInitArray(array* xs) { - if (xs->size > 0) { - new (xs->data) T[xs->size]; - } - return xs; +template array *defInitArray(array *xs) { + if (xs->size > 0) { + new (xs->data) T[xs->size]; } + return xs; +} -template - array* makeArray(region& m, long n) { - array* r = reinterpret_cast*>(m.malloc(sizeof(long) + (sizeof(T) * n), std::max(sizeof(long), alignof(T)))); - r->size = n; - return defInitArray(r); - } +template array *makeArray(region &m, long n) { + array *r = reinterpret_cast *>( + m.malloc(sizeof(long) + (sizeof(T) * n), + std::max(sizeof(long), alignof(T)))); + r->size = n; + return defInitArray(r); +} -template - array* makeArray(long n) { - array* r = reinterpret_cast*>(memalloc(sizeof(long) + (sizeof(T) * n), std::max(sizeof(long), alignof(T)))); - r->size = n; - return defInitArray(r); - } +template array *makeArray(long n) { + array *r = reinterpret_cast *>( + memalloc(sizeof(long) + (sizeof(T) * n), + std::max(sizeof(long), alignof(T)))); + r->size = n; + return defInitArray(r); +} // allocate ... something -template - T* make(const Args& ... args) { - return new (memalloc(sizeof(T), alignof(T))) T(args...); - } +template T *make(const Args &...args) { + return new (memalloc(sizeof(T), alignof(T))) T(args...); +} // resets the thread-local memory pool for expressions // (subsequent allocations will reuse previously-used memory) @@ -90,11 +95,11 @@ public: std::string showMemoryPool(); // control the set of regions used for dynamic allocation -size_t addThreadRegion(const std::string&, region*); -size_t findThreadRegion(const std::string&); +size_t addThreadRegion(const std::string &, region *); +size_t findThreadRegion(const std::string &); void removeThreadRegion(size_t); size_t setThreadRegion(size_t); -} +} // namespace hobbes #endif diff --git a/include/hobbes/ipc/net.H b/include/hobbes/ipc/net.H index 4f8b2a9b6..2402ef9d1 100644 --- a/include/hobbes/ipc/net.H +++ b/include/hobbes/ipc/net.H @@ -16,7 +16,7 @@ namespace hobbes { int lookupPort(const std::string&); // create a socket listening on a port -int allocateServer(int port); +int allocateServer(int port, const std::string& host = ""); int allocateServer(const std::string& port); // connect to a host/port @@ -33,9 +33,9 @@ std::string remoteHostname(int socket); int remotePort(int socket); // run a REPL server at some port, either indirectly or directly with a compiler -typedef std::vector RawData; -typedef uint32_t exprid; -typedef std::function ReWriteExprFn; +using RawData = std::vector; +using exprid = uint32_t; +using ReWriteExprFn = std::function; struct Server { virtual void connect (int conn) = 0; @@ -46,11 +46,13 @@ struct Server { }; int installNetREPL(int port, Server*); +int installNetREPL(const std::string& host, int port, Server*); // install a net repl on a unix domain socket (using file paths) int installNetREPL(const std::string& /*filepath*/, Server*); class cc; int installNetREPL(int port, cc*, ReWriteExprFn const& = [](ExprPtr const& e) -> ExprPtr { return e; }); +int installNetREPL(const std::string& host, int port, cc*, ReWriteExprFn const& = [](ExprPtr const& e) -> ExprPtr { return e; }); // install a net repl on a unix domain socket (using file paths) int installNetREPL(const std::string& /*filepath*/, cc*, ReWriteExprFn const& = [](ExprPtr const& e) -> ExprPtr { return e; }); @@ -79,11 +81,11 @@ private: MonoTypePtr inty; MonoTypePtr outty; }; - typedef std::map ExprDefs; + using ExprDefs = std::map; ExprDefs exprDefs; - typedef std::pair ExprTy; - typedef std::map ExprTyToID; + using ExprTy = std::pair; + using ExprTyToID = std::map; ExprTyToID exprTyToID; public: /* run-time methods */ @@ -91,7 +93,7 @@ public: // append a receive function to the end of the sequence of receive handlers // these functions will be applied in order to read values from the remote process - typedef char* (*ReadFn)(int); + using ReadFn = char *(*)(int); size_t appendReadFn(ReadFn); // read a result (reading and discarding any intermediate results) @@ -101,7 +103,7 @@ public: static size_t unsafeAppendReadFn(size_t, ReadFn); static char* unsafeRead(size_t, size_t); private: - typedef std::queue ReadFns; + using ReadFns = std::queue; ReadFns readFns; size_t rbno; size_t reno; diff --git a/include/hobbes/ipc/prepl.H b/include/hobbes/ipc/prepl.H index b80fb52b2..e01ce834c 100644 --- a/include/hobbes/ipc/prepl.H +++ b/include/hobbes/ipc/prepl.H @@ -5,6 +5,8 @@ #ifndef HOBBES_IPC_REPL_HPP_INCLUDED #define HOBBES_IPC_REPL_HPP_INCLUDED +#include "hobbes/lang/type.H" + #include #include @@ -19,7 +21,8 @@ struct proc { int read_fd; // read from this to get remote proc responses }; -void spawn(const std::string&, proc*); +using FailToKillCallback = std::function; +void spawn(const std::string&, proc*, const FailToKillCallback& fn={}); void procSearch(proc*, const std::string&, const std::string&); void procDefine(proc*, const std::string&, const std::string&); void procEval(proc*, const std::string&); @@ -29,7 +32,7 @@ void procRead(proc*, std::ostream*, uint64_t waitUS = 0); MonoTypePtr refinedType(const proc& p, const std::string& fname, const MonoTypePtr& hasty); int invocationID(const proc& p, const std::string& fname, const MonoTypePtr& hasty); -typedef std::pair PrepProcExpr; +using PrepProcExpr = std::pair; PrepProcExpr procPrepareExpr(const proc&, const ExprPtr&); void runMachineREPL(cc*); diff --git a/include/hobbes/ipc/process.H b/include/hobbes/ipc/process.H index 0fe22a3cc..5201d9b10 100644 --- a/include/hobbes/ipc/process.H +++ b/include/hobbes/ipc/process.H @@ -5,6 +5,7 @@ #include #include #include +#include namespace hobbes { @@ -16,16 +17,16 @@ public: static std::string constraintName(); // unqualifier interface - bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*); - bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs); - ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&,const ExprPtr&,Definitions*) const; - PolyTypePtr lookup (const std::string& vn) const; - SymSet bindings () const; - FunDeps dependencies(const ConstraintPtr&) const; + bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*) override; + bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs) override; + ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&,const ExprPtr&,Definitions*) const override; + PolyTypePtr lookup (const std::string& vn) const override; + SymSet bindings () const override; + FunDeps dependencies(const ConstraintPtr&) const override; private: - ProcManager procman; + std::shared_ptr procman{std::make_shared()}; }; } diff --git a/include/hobbes/ipc/procman.H b/include/hobbes/ipc/procman.H index e5dc57d20..82a58273d 100644 --- a/include/hobbes/ipc/procman.H +++ b/include/hobbes/ipc/procman.H @@ -13,15 +13,15 @@ public: bool isSpawnedPid(const std::string&, long) const; // hf eliminator interface - bool satisfied(const TEnvPtr&, const HasField&, Definitions*) const; - bool satisfiable(const TEnvPtr&, const HasField&, Definitions*) const; - bool refine(const TEnvPtr&, const HasField&, MonoTypeUnifier*, Definitions*); - ExprPtr unqualify(const TEnvPtr&, const ConstraintPtr&, const ExprPtr&, Definitions*) const; - std::string name() const; + bool satisfied(const TEnvPtr&, const HasField&, Definitions*) const override; + bool satisfiable(const TEnvPtr&, const HasField&, Definitions*) const override; + bool refine(const TEnvPtr&, const HasField&, MonoTypeUnifier*, Definitions*) override; + ExprPtr unqualify(const TEnvPtr&, const ConstraintPtr&, const ExprPtr&, Definitions*) const override; + std::string name() const override; private: friend struct ProcManUnqualify; - typedef std::map SpawnedProcs; + using SpawnedProcs = std::map; SpawnedProcs procs; const proc& lp(long) const; diff --git a/include/hobbes/lang/constraints.H b/include/hobbes/lang/constraints.H index 5753d52ba..0b97634f8 100644 --- a/include/hobbes/lang/constraints.H +++ b/include/hobbes/lang/constraints.H @@ -24,7 +24,7 @@ public: void insert(const TEnvPtr&, const ConstraintPtr&, MonoTypeUnifier*); Constraints constraints() const; private: - typedef type_map CSet; + using CSet = type_map; CSet csts; }; diff --git a/include/hobbes/lang/expr.H b/include/hobbes/lang/expr.H index a9d876e70..8303f19c4 100644 --- a/include/hobbes/lang/expr.H +++ b/include/hobbes/lang/expr.H @@ -12,7 +12,7 @@ namespace hobbes { -typedef __int128 int128_t; +using int128_t = __int128; class Expr : public LexicallyAnnotated { public: @@ -42,11 +42,11 @@ private: template class ExprCase : public Expr { public: - typedef ExprCase Base; + using Base = ExprCase; ExprCase(const LexicalAnnotation&); virtual bool operator==(const Case&) const = 0; - bool operator==(const Expr& rhs) const { + bool operator==(const Expr& rhs) const override { if (this == &rhs) { return true; } else if (const Case* trhs = is(&rhs)) { @@ -57,11 +57,11 @@ template } }; -typedef std::shared_ptr ExprPtr; -typedef std::vector Exprs; +using ExprPtr = std::shared_ptr; +using Exprs = std::vector; -typedef std::pair Definition; -typedef std::vector Definitions; +using Definition = std::pair; +using Definitions = std::vector; std::string show(const Expr& e); std::string show(const Expr* e); @@ -78,29 +78,29 @@ std::string showAnnotated(const Definition& d); class Primitive : public Expr { public: - virtual bool operator==(const Expr&) const = 0; + bool operator==(const Expr&) const override = 0; virtual bool operator< (const Primitive&) const = 0; virtual MonoTypePtr primType() const = 0; // for efficient case dispatch Primitive(int cid, const LexicalAnnotation&); }; -typedef std::shared_ptr PrimitivePtr; +using PrimitivePtr = std::shared_ptr; struct PrimPtrLT { bool operator()(const PrimitivePtr&, const PrimitivePtr&) const; }; -typedef std::set PrimitiveSet; +using PrimitiveSet = std::set; template class PrimitiveCase : public Primitive { public: - typedef PrimitiveCase Base; + using Base = PrimitiveCase; PrimitiveCase(const LexicalAnnotation&); virtual bool equiv(const Case&) const = 0; virtual bool lt(const Case&) const = 0; - bool operator<(const Primitive& rhs) const { + bool operator<(const Primitive& rhs) const override { if (const Case* trhs = is(&rhs)) { return lt(*trhs); } else { @@ -108,7 +108,7 @@ template } } - bool operator==(const Expr& rhs) const { + bool operator==(const Expr& rhs) const override { if (const Case* trhs = is(&rhs)) { return this->equiv(*trhs); } else { @@ -120,12 +120,12 @@ template class Unit : public PrimitiveCase { public: Unit(const LexicalAnnotation&); - Expr* clone() const; - void show(std::ostream& out) const; - void showAnnotated(std::ostream& out) const; - bool equiv(const Unit&) const; - bool lt(const Unit&) const; - MonoTypePtr primType() const; + Expr* clone() const override; + void show(std::ostream& out) const override; + void showAnnotated(std::ostream& out) const override; + bool equiv(const Unit&) const override; + bool lt(const Unit&) const override; + MonoTypePtr primType() const override; static const int type_case_id = 0; }; @@ -135,12 +135,12 @@ public: Bool(bool x, const LexicalAnnotation&); bool value() const; void value(bool); - Expr* clone() const; - void show(std::ostream& out) const; - void showAnnotated(std::ostream& out) const; - bool equiv(const Bool&) const; - bool lt(const Bool&) const; - MonoTypePtr primType() const; + Expr* clone() const override; + void show(std::ostream& out) const override; + void showAnnotated(std::ostream& out) const override; + bool equiv(const Bool&) const override; + bool lt(const Bool&) const override; + MonoTypePtr primType() const override; static const int type_case_id = 1; private: @@ -152,12 +152,12 @@ public: Char(char x, const LexicalAnnotation&); char value() const; void value(char); - Expr* clone() const; - void show(std::ostream& out) const; - void showAnnotated(std::ostream& out) const; - bool equiv(const Char&) const; - bool lt(const Char&) const; - MonoTypePtr primType() const; + Expr* clone() const override; + void show(std::ostream& out) const override; + void showAnnotated(std::ostream& out) const override; + bool equiv(const Char&) const override; + bool lt(const Char&) const override; + MonoTypePtr primType() const override; static const int type_case_id = 2; private: @@ -170,12 +170,12 @@ public: Byte(unsigned char x, const LexicalAnnotation&); unsigned char value() const; void value(unsigned char); - Expr* clone() const; - void show(std::ostream& out) const; - void showAnnotated(std::ostream& out) const; - bool equiv(const Byte&) const; - bool lt(const Byte&) const; - MonoTypePtr primType() const; + Expr* clone() const override; + void show(std::ostream& out) const override; + void showAnnotated(std::ostream& out) const override; + bool equiv(const Byte&) const override; + bool lt(const Byte&) const override; + MonoTypePtr primType() const override; static const int type_case_id = 3; private: @@ -188,12 +188,12 @@ public: Short(short x, const LexicalAnnotation&); short value() const; void value(short); - Expr* clone() const; - void show(std::ostream& out) const; - void showAnnotated(std::ostream& out) const; - bool equiv(const Short&) const; - bool lt(const Short&) const; - MonoTypePtr primType() const; + Expr* clone() const override; + void show(std::ostream& out) const override; + void showAnnotated(std::ostream& out) const override; + bool equiv(const Short&) const override; + bool lt(const Short&) const override; + MonoTypePtr primType() const override; static const int type_case_id = 4; private: @@ -206,12 +206,12 @@ public: Int(int x, const LexicalAnnotation&); int value() const; void value(int); - Expr* clone() const; - void show(std::ostream& out) const; - void showAnnotated(std::ostream& out) const; - bool equiv(const Int&) const; - bool lt(const Int&) const; - MonoTypePtr primType() const; + Expr* clone() const override; + void show(std::ostream& out) const override; + void showAnnotated(std::ostream& out) const override; + bool equiv(const Int&) const override; + bool lt(const Int&) const override; + MonoTypePtr primType() const override; static const int type_case_id = 5; private: @@ -224,12 +224,12 @@ public: Long(long x, const LexicalAnnotation&); long value() const; void value(long); - Expr* clone() const; - void show(std::ostream& out) const; - void showAnnotated(std::ostream& out) const; - bool equiv(const Long&) const; - bool lt(const Long&) const; - MonoTypePtr primType() const; + Expr* clone() const override; + void show(std::ostream& out) const override; + void showAnnotated(std::ostream& out) const override; + bool equiv(const Long&) const override; + bool lt(const Long&) const override; + MonoTypePtr primType() const override; static const int type_case_id = 6; private: @@ -242,12 +242,12 @@ public: Float(float x, const LexicalAnnotation&); float value() const; void value(float); - Expr* clone() const; - void show(std::ostream& out) const; - void showAnnotated(std::ostream& out) const; - bool equiv(const Float&) const; - bool lt(const Float&) const; - MonoTypePtr primType() const; + Expr* clone() const override; + void show(std::ostream& out) const override; + void showAnnotated(std::ostream& out) const override; + bool equiv(const Float&) const override; + bool lt(const Float&) const override; + MonoTypePtr primType() const override; static const int type_case_id = 7; private: @@ -260,12 +260,12 @@ public: Double(double x, const LexicalAnnotation&); double value() const; void value(double); - Expr* clone() const; - void show(std::ostream& out) const; - void showAnnotated(std::ostream& out) const; - bool equiv(const Double&) const; - bool lt(const Double&) const; - MonoTypePtr primType() const; + Expr* clone() const override; + void show(std::ostream& out) const override; + void showAnnotated(std::ostream& out) const override; + bool equiv(const Double&) const override; + bool lt(const Double&) const override; + MonoTypePtr primType() const override; static const int type_case_id = 8; private: @@ -284,13 +284,13 @@ template class Var : public ExprCase { public: Var(const std::string& id, const LexicalAnnotation&); - bool operator==(const Var&) const; + bool operator==(const Var&) const override; const std::string& value() const; void value(const std::string&); - Expr* clone() const; - void show(std::ostream& out) const; - void showAnnotated(std::ostream& out) const; + Expr* clone() const override; + void show(std::ostream& out) const override; + void showAnnotated(std::ostream& out) const override; static const int type_case_id = 9; private: @@ -301,7 +301,7 @@ private: class Let : public ExprCase { public: Let(const std::string& id, const ExprPtr& e, const ExprPtr& b, const LexicalAnnotation&); - bool operator==(const Let&) const; + bool operator==(const Let&) const override; const std::string& var() const; const ExprPtr& varExpr() const; @@ -311,9 +311,9 @@ public: void varExpr(const ExprPtr&); void bodyExpr(const ExprPtr&); - Expr* clone() const; - void show(std::ostream& out) const; - void showAnnotated(std::ostream& out) const; + Expr* clone() const override; + void show(std::ostream& out) const override; + void showAnnotated(std::ostream& out) const override; static const int type_case_id = 10; private: @@ -325,11 +325,11 @@ private: // local mutually-recursive function definition class LetRec : public ExprCase { public: - typedef std::pair Binding; - typedef std::vector Bindings; + using Binding = std::pair; + using Bindings = std::vector; LetRec(const Bindings&, const ExprPtr&, const LexicalAnnotation&); - bool operator==(const LetRec&) const; + bool operator==(const LetRec&) const override; const Bindings& bindings() const; const ExprPtr& bodyExpr() const; @@ -338,9 +338,9 @@ public: Bindings& bindings(); void bodyExpr(const ExprPtr&); - Expr* clone() const; - void show(std::ostream&) const; - void showAnnotated(std::ostream&) const; + Expr* clone() const override; + void show(std::ostream&) const override; + void showAnnotated(std::ostream&) const override; static const int type_case_id = 11; private: @@ -351,10 +351,10 @@ private: // \x0...xn -> E (function introduction) class Fn : public ExprCase { public: - typedef std::vector VarNames; + using VarNames = std::vector; Fn(const VarNames& vs, const ExprPtr& e, const LexicalAnnotation&); - bool operator==(const Fn&) const; + bool operator==(const Fn&) const override; const VarNames& varNames() const; const ExprPtr& body() const; @@ -362,9 +362,9 @@ public: VarNames& varNames(); void body(const ExprPtr&); - Expr* clone() const; - void show(std::ostream& out) const; - void showAnnotated(std::ostream& out) const; + Expr* clone() const override; + void show(std::ostream& out) const override; + void showAnnotated(std::ostream& out) const override; static const int type_case_id = 12; private: @@ -376,7 +376,7 @@ private: class App : public ExprCase { public: App(const ExprPtr& fn, const Exprs& args, const LexicalAnnotation&); - bool operator==(const App&) const; + bool operator==(const App&) const override; const ExprPtr& fn() const; const Exprs& args() const; @@ -384,9 +384,9 @@ public: void fn(const ExprPtr&); Exprs& args(); - Expr* clone() const; - void show(std::ostream& out) const; - void showAnnotated(std::ostream& out) const; + Expr* clone() const override; + void show(std::ostream& out) const override; + void showAnnotated(std::ostream& out) const override; static const int type_case_id = 13; private: @@ -398,7 +398,7 @@ private: class Assign : public ExprCase { public: Assign(const ExprPtr& lhs, const ExprPtr& rhs, const LexicalAnnotation&); - bool operator==(const Assign&) const; + bool operator==(const Assign&) const override; const ExprPtr& left() const; const ExprPtr& right() const; @@ -406,9 +406,9 @@ public: void left(const ExprPtr&); void right(const ExprPtr&); - Expr* clone() const; - void show(std::ostream& out) const; - void showAnnotated(std::ostream& out) const; + Expr* clone() const override; + void show(std::ostream& out) const override; + void showAnnotated(std::ostream& out) const override; static const int type_case_id = 14; private: @@ -420,14 +420,14 @@ private: class MkArray : public ExprCase { public: MkArray(const Exprs& es, const LexicalAnnotation&); - bool operator==(const MkArray&) const; + bool operator==(const MkArray&) const override; const Exprs& values() const; Exprs& values(); - Expr* clone() const; - void show(std::ostream& out) const; - void showAnnotated(std::ostream& out) const; + Expr* clone() const override; + void show(std::ostream& out) const override; + void showAnnotated(std::ostream& out) const override; static const int type_case_id = 15; private: @@ -438,7 +438,7 @@ private: class MkVariant : public ExprCase { public: MkVariant(const std::string& lbl, const ExprPtr& e, const LexicalAnnotation&); - bool operator==(const MkVariant&) const; + bool operator==(const MkVariant&) const override; const std::string& label() const; const ExprPtr& value() const; @@ -446,9 +446,9 @@ public: void label(const std::string&); void value(const ExprPtr&); - Expr* clone() const; - void show(std::ostream& out) const; - void showAnnotated(std::ostream& out) const; + Expr* clone() const override; + void show(std::ostream& out) const override; + void showAnnotated(std::ostream& out) const override; static const int type_case_id = 16; private: @@ -459,18 +459,18 @@ private: // {f0=E0,...,fN=EN} (record introduction) class MkRecord : public ExprCase { public: - typedef std::pair FieldDef; - typedef std::vector FieldDefs; + using FieldDef = std::pair; + using FieldDefs = std::vector; MkRecord(const FieldDefs& fs, const LexicalAnnotation&); - bool operator==(const MkRecord&) const; + bool operator==(const MkRecord&) const override; const FieldDefs& fields() const; FieldDefs& fields(); - Expr* clone() const; - void show(std::ostream& out) const; - void showAnnotated(std::ostream& out) const; + Expr* clone() const override; + void show(std::ostream& out) const override; + void showAnnotated(std::ostream& out) const override; static const int type_case_id = 17; private: @@ -487,7 +487,7 @@ private: class AIndex : public ExprCase { public: AIndex(const ExprPtr&, const ExprPtr&, const LexicalAnnotation&); - bool operator==(const AIndex&) const; + bool operator==(const AIndex&) const override; const ExprPtr& array() const; const ExprPtr& index() const; @@ -495,9 +495,9 @@ public: void array(const ExprPtr&); void index(const ExprPtr&); - Expr* clone() const; - void show(std::ostream& out) const; - void showAnnotated(std::ostream& out) const; + Expr* clone() const override; + void show(std::ostream& out) const override; + void showAnnotated(std::ostream& out) const override; static const int type_case_id = 18; private: @@ -509,18 +509,18 @@ private: class Case : public ExprCase { public: struct Binding { - Binding() { } + Binding() = default; Binding(const std::string& selector, const std::string& vname, const ExprPtr& exp) : selector(selector), vname(vname), exp(exp) { } std::string selector; std::string vname; ExprPtr exp; }; - typedef std::vector Bindings; + using Bindings = std::vector; Case(const ExprPtr& v, const Bindings& bs, const LexicalAnnotation&); Case(const ExprPtr& v, const Bindings& bs, const ExprPtr& def, const LexicalAnnotation&); - bool operator==(const Case&) const; + bool operator==(const Case&) const override; const ExprPtr& variant() const; const Bindings& bindings() const; @@ -533,9 +533,9 @@ public: bool hasBinding(const std::string&) const; void addBinding(const std::string& selector, const std::string& vname, const ExprPtr& exp); - Expr* clone() const; - void show(std::ostream& out) const; - void showAnnotated(std::ostream& out) const; + Expr* clone() const override; + void show(std::ostream& out) const override; + void showAnnotated(std::ostream& out) const override; static const int type_case_id = 19; private: @@ -548,17 +548,17 @@ private: class Switch : public ExprCase { public: struct Binding { - Binding() { } + Binding() = default; Binding(const PrimitivePtr& value, const ExprPtr& exp) : value(value), exp(exp) { } PrimitivePtr value; ExprPtr exp; }; - typedef std::vector Bindings; + using Bindings = std::vector; Switch(const ExprPtr& v, const Bindings& bs, const LexicalAnnotation&); Switch(const ExprPtr& v, const Bindings& bs, const ExprPtr& def, const LexicalAnnotation&); - bool operator==(const Switch&) const; + bool operator==(const Switch&) const override; const ExprPtr& expr() const; const Bindings& bindings() const; @@ -568,9 +568,9 @@ public: Bindings& bindings(); void defaultExpr(const ExprPtr&); - Expr* clone() const; - void show(std::ostream&) const; - void showAnnotated(std::ostream& out) const; + Expr* clone() const override; + void show(std::ostream&) const override; + void showAnnotated(std::ostream& out) const override; static const int type_case_id = 20; private: @@ -583,7 +583,7 @@ private: class Proj : public ExprCase { public: Proj(const ExprPtr& r, const std::string& fn, const LexicalAnnotation&); - bool operator==(const Proj&) const; + bool operator==(const Proj&) const override; const ExprPtr& record() const; const std::string& field() const; @@ -591,9 +591,9 @@ public: void record(const ExprPtr&); void field(const std::string&); - Expr* clone() const; - void show(std::ostream& out) const; - void showAnnotated(std::ostream& out) const; + Expr* clone() const override; + void show(std::ostream& out) const override; + void showAnnotated(std::ostream& out) const override; static const int type_case_id = 21; private: @@ -605,7 +605,7 @@ private: class Assump : public ExprCase { public: Assump(const ExprPtr& e, const QualTypePtr& t, const LexicalAnnotation&); - bool operator==(const Assump&) const; + bool operator==(const Assump&) const override; const ExprPtr& expr() const; const QualTypePtr& ty() const; @@ -613,9 +613,9 @@ public: void expr(const ExprPtr&); void ty(const QualTypePtr&); - Expr* clone() const; - void show(std::ostream& out) const; - void showAnnotated(std::ostream& out) const; + Expr* clone() const override; + void show(std::ostream& out) const override; + void showAnnotated(std::ostream& out) const override; static const int type_case_id = 22; private: @@ -627,14 +627,14 @@ private: class Pack : public ExprCase { public: Pack(const ExprPtr& e, const LexicalAnnotation&); - bool operator==(const Pack&) const; + bool operator==(const Pack&) const override; const ExprPtr& expr() const; void expr(const ExprPtr&); - Expr* clone() const; - void show(std::ostream& out) const; - void showAnnotated(std::ostream& out) const; + Expr* clone() const override; + void show(std::ostream& out) const override; + void showAnnotated(std::ostream& out) const override; static const int type_case_id = 23; private: @@ -645,7 +645,7 @@ private: class Unpack : public ExprCase { public: Unpack(const std::string&, const ExprPtr&, const ExprPtr&, const LexicalAnnotation&); - bool operator==(const Unpack&) const; + bool operator==(const Unpack&) const override; const std::string& varName() const; const ExprPtr& package() const; @@ -655,9 +655,9 @@ public: void package(const ExprPtr&); void expr(const ExprPtr&); - Expr* clone() const; - void show(std::ostream& out) const; - void showAnnotated(std::ostream& out) const; + Expr* clone() const override; + void show(std::ostream& out) const override; + void showAnnotated(std::ostream& out) const override; static const int type_case_id = 24; private: @@ -672,12 +672,12 @@ public: Int128(int128_t x, const LexicalAnnotation&); int128_t value() const; void value(int128_t); - Expr* clone() const; - void show(std::ostream& out) const; - void showAnnotated(std::ostream& out) const; - bool equiv(const Int128&) const; - bool lt(const Int128&) const; - MonoTypePtr primType() const; + Expr* clone() const override; + void show(std::ostream& out) const override; + void showAnnotated(std::ostream& out) const override; + bool equiv(const Int128&) const override; + bool lt(const Int128&) const override; + MonoTypePtr primType() const override; static const int type_case_id = 25; private: @@ -778,19 +778,19 @@ inline ExprPtr mktunit(const LexicalAnnotation& la) { } inline ExprPtr mkrecord(const MkRecord::FieldDefs& fds, const LexicalAnnotation& la) { - if (fds.size() == 0) { + if (fds.empty()) { return mktunit(la); } else { ExprPtr result(new MkRecord(fds, la)); Constraints csts; Record::Members ms; - for (MkRecord::FieldDefs::const_iterator fd = fds.begin(); fd != fds.end(); ++fd) { - if (fd->second->type() == QualTypePtr()) { + for (const auto &fd : fds) { + if (fd.second->type() == QualTypePtr()) { return result; } else { - mergeConstraints(fd->second->type()->constraints(), &csts); - ms.push_back(Record::Member(fd->first, fd->second->type()->monoType())); + mergeConstraints(fd.second->type()->constraints(), &csts); + ms.push_back(Record::Member(fd.first, fd.second->type()->monoType())); } } @@ -851,8 +851,8 @@ template inline Constraints liftConstraints(const Exprs& es) { Constraints r; - for (Exprs::const_iterator e = es.begin(); e != es.end(); ++e) { - QualTypePtr qt = (*e)->type(); + for (const auto &e : es) { + QualTypePtr qt = e->type(); if (qt != QualTypePtr()) { append(&r, qt->constraints()); } @@ -889,7 +889,7 @@ inline ExprPtr closcall(const ExprPtr& c, const Exprs& args, const LexicalAnnota } const Exists* ety = is(qt->monoType()); - if (!ety) { + if (ety == nullptr) { throw annotated_error(*c, "Expected existential type in closure application"); } @@ -904,7 +904,7 @@ inline ExprPtr closcall(const ExprPtr& c, const Exprs& args, const LexicalAnnota // op :: (a0..aN) -> r => \(a0..aN).op(a0..aN) inline ExprPtr etaLift(const std::string& opname, const MonoTypePtr& oty, const LexicalAnnotation& la) { Func* fty = is(oty); - if (!fty) { throw annotated_error(la, "Internal compiler error while eta-expanding primitive op: " + opname); } + if (fty == nullptr) { throw annotated_error(la, "Internal compiler error while eta-expanding primitive op: " + opname); } ExprPtr op = var(opname, oty, la); @@ -931,8 +931,8 @@ inline Expr* mkarray(const std::vector& v, const LexicalAnnotatio QualTypePtr aty = qualtype(arrayty(bty)); Exprs cs; - for (size_t b = 0; b < v.size(); ++b) { - ExprPtr be(new Byte(v[b], la)); + for (const unsigned char b : v) { + ExprPtr be(new Byte(b, la)); be->type(ety); cs.push_back(be); } @@ -952,8 +952,8 @@ inline Expr* mkarray(const std::string& v, const LexicalAnnotation& la) { QualTypePtr aty = qualtype(arrayty(cty)); Exprs cs; - for (size_t c = 0; c < v.size(); ++c) { - ExprPtr ce(new Char(v[c], la)); + for (const char c : v) { + ExprPtr ce(new Char(c, la)); ce->type(ety); cs.push_back(ce); } @@ -968,7 +968,7 @@ inline Expr* mkarray(const std::string& v, const LexicalAnnotation& la) { } inline ExprPtr switchE(const ExprPtr& e, const Switch::Bindings& bs, const ExprPtr& def, const LexicalAnnotation& la) { - if (bs.size() == 0) { + if (bs.empty()) { return def; } else { return ExprPtr(new Switch(e, bs, def, la)); @@ -1029,16 +1029,16 @@ inline ExprPtr assign(const ExprPtr& lhs, const ExprPtr& rhs, const LexicalAnnot inline Exprs exprs(const MkRecord::FieldDefs& ms) { Exprs r; - for (MkRecord::FieldDefs::const_iterator m = ms.begin(); m != ms.end(); ++m) { - r.push_back(m->second); + for (const auto &m : ms) { + r.push_back(m.second); } return r; } inline Exprs exprs(const Case::Bindings& bs) { Exprs r; - for (Case::Bindings::const_iterator b = bs.begin(); b != bs.end(); ++b) { - r.push_back(b->exp); + for (const auto &b : bs) { + r.push_back(b.exp); } return r; } @@ -1046,8 +1046,8 @@ inline Exprs exprs(const Case::Bindings& bs) { // replaces instances of a given variable name with the specified expression // (NOTE: this does nothing to prevent variable capture, other than respecting shadowing) // (ie: the free variables of the substituted expression should be disjoint with program variables) -typedef std::map VarMapping; -ExprPtr substitute(const VarMapping& vm, const ExprPtr& e, bool* mapped = 0); +using VarMapping = std::map; +ExprPtr substitute(const VarMapping& vm, const ExprPtr& e, bool* mapped = nullptr); // apply a type substitution across an expression ExprPtr substitute(const MonoTypeSubst& s, const ExprPtr& e); @@ -1133,34 +1133,34 @@ template struct switchExprC : public switchExpr { virtual ~switchExprC() = default; virtual T withConst(const Expr* v) const = 0; - virtual T with (const Var* v) const = 0; - virtual T with (const Let* v) const = 0; - virtual T with (const LetRec* v) const = 0; - virtual T with (const Fn* v) const = 0; - virtual T with (const App* v) const = 0; - virtual T with (const Assign* v) const = 0; - virtual T with (const MkArray* v) const = 0; - virtual T with (const MkVariant* v) const = 0; - virtual T with (const MkRecord* v) const = 0; - virtual T with (const AIndex* v) const = 0; - virtual T with (const Case* v) const = 0; - virtual T with (const Switch* v) const = 0; - virtual T with (const Proj* v) const = 0; - virtual T with (const Assump* v) const = 0; - virtual T with (const Pack* v) const = 0; - virtual T with (const Unpack* v) const = 0; + T with (const Var* v) const override = 0; + T with (const Let* v) const override = 0; + T with (const LetRec* v) const override = 0; + T with (const Fn* v) const override = 0; + T with (const App* v) const override = 0; + T with (const Assign* v) const override = 0; + T with (const MkArray* v) const override = 0; + T with (const MkVariant* v) const override = 0; + T with (const MkRecord* v) const override = 0; + T with (const AIndex* v) const override = 0; + T with (const Case* v) const override = 0; + T with (const Switch* v) const override = 0; + T with (const Proj* v) const override = 0; + T with (const Assump* v) const override = 0; + T with (const Pack* v) const override = 0; + T with (const Unpack* v) const override = 0; // implement just the constant 'with' terms to collapse them - T with(const Unit* v) const { return withConst(v); } - T with(const Bool* v) const { return withConst(v); } - T with(const Char* v) const { return withConst(v); } - T with(const Byte* v) const { return withConst(v); } - T with(const Short* v) const { return withConst(v); } - T with(const Int* v) const { return withConst(v); } - T with(const Long* v) const { return withConst(v); } - T with(const Int128* v) const { return withConst(v); } - T with(const Float* v) const { return withConst(v); } - T with(const Double* v) const { return withConst(v); } + T with(const Unit* v) const override { return withConst(v); } + T with(const Bool* v) const override { return withConst(v); } + T with(const Char* v) const override { return withConst(v); } + T with(const Byte* v) const override { return withConst(v); } + T with(const Short* v) const override { return withConst(v); } + T with(const Int* v) const override { return withConst(v); } + T with(const Long* v) const override { return withConst(v); } + T with(const Int128* v) const override { return withConst(v); } + T with(const Float* v) const override { return withConst(v); } + T with(const Double* v) const override { return withConst(v); } }; bool isConst(const ExprPtr&); @@ -1274,7 +1274,7 @@ template template std::vector switchOf(const Exprs& es, const switchExpr& f) { std::vector result; - for (auto e : es) { + for (const auto& e : es) { result.push_back(switchOf(e, f)); } return result; @@ -1283,7 +1283,7 @@ template template std::vector switchOf(const Exprs& es, const switchExprM& f) { std::vector result; - for (auto e : es) { + for (const auto& e : es) { result.push_back(switchOf(e, const_cast&>(f))); } return result; @@ -1291,10 +1291,10 @@ template template std::vector< std::pair > switchOf(const std::vector< std::pair >& kes, const switchExpr& f) { - typedef std::pair KT; - typedef std::vector KTS; + using KT = std::pair; + using KTS = std::vector; KTS kts; - for (auto ke : kes) { + for (const auto& ke : kes) { kts.push_back(KT(ke.first, switchOf(ke.second, f))); } return kts; @@ -1302,10 +1302,10 @@ template template std::vector< std::pair > switchOf(const std::vector< std::pair >& kes, const switchExprM& f) { - typedef std::pair KT; - typedef std::vector KTS; + using KT = std::pair; + using KTS = std::vector; KTS kts; - for (auto ke : kes) { + for (const auto& ke : kes) { kts.push_back(KT(ke.first, switchOf(ke.second, const_cast&>(f)))); } return kts; @@ -1323,57 +1323,57 @@ struct switchExprTyFn : public switchExprC { virtual ExprPtr wrapWithTy(const QualTypePtr& qty, Expr* e) const; // allocate a fresh expression, updating types as we go - ExprPtr withConst(const Expr* v) const; - ExprPtr with (const Var* v) const; - ExprPtr with (const Let* v) const; - ExprPtr with (const LetRec* v) const; - ExprPtr with (const Fn* v) const; - ExprPtr with (const App* v) const; - ExprPtr with (const Assign* v) const; - ExprPtr with (const MkArray* v) const; - ExprPtr with (const MkVariant* v) const; - ExprPtr with (const MkRecord* v) const; - ExprPtr with (const AIndex* v) const; - ExprPtr with (const Case* v) const; - ExprPtr with (const Switch* v) const; - ExprPtr with (const Proj* v) const; - ExprPtr with (const Assump* v) const; - ExprPtr with (const Pack* v) const; - ExprPtr with (const Unpack* v) const; + ExprPtr withConst(const Expr* v) const override; + ExprPtr with (const Var* v) const override; + ExprPtr with (const Let* v) const override; + ExprPtr with (const LetRec* v) const override; + ExprPtr with (const Fn* v) const override; + ExprPtr with (const App* v) const override; + ExprPtr with (const Assign* v) const override; + ExprPtr with (const MkArray* v) const override; + ExprPtr with (const MkVariant* v) const override; + ExprPtr with (const MkRecord* v) const override; + ExprPtr with (const AIndex* v) const override; + ExprPtr with (const Case* v) const override; + ExprPtr with (const Switch* v) const override; + ExprPtr with (const Proj* v) const override; + ExprPtr with (const Assump* v) const override; + ExprPtr with (const Pack* v) const override; + ExprPtr with (const Unpack* v) const override; }; struct switchExprTyFnM : public switchExprM { // whatever type transform is being done (default is the identity transform) virtual QualTypePtr withTy(const QualTypePtr& qt) const; - UnitV with(Unit* v); - UnitV with(Bool* v); - UnitV with(Char* v); - UnitV with(Byte* v); - UnitV with(Short* v); - UnitV with(Int* v); - UnitV with(Long* v); - UnitV with(Int128* v); - UnitV with(Float* v); - UnitV with(Double* v); - UnitV with(Var* v); - UnitV with(Let* v); - UnitV with(LetRec* v); - UnitV with(Fn* v); - UnitV with(App* v); - UnitV with(Assign* v); - UnitV with(MkArray* v); - UnitV with(MkVariant* v); - UnitV with(MkRecord* v); - UnitV with(AIndex* v); - UnitV with(Case* v); - UnitV with(Switch* v); - UnitV with(Proj* v); - UnitV with(Assump* v); - UnitV with(Pack* v); - UnitV with(Unpack* v); + UnitV with(Unit* v) override; + UnitV with(Bool* v) override; + UnitV with(Char* v) override; + UnitV with(Byte* v) override; + UnitV with(Short* v) override; + UnitV with(Int* v) override; + UnitV with(Long* v) override; + UnitV with(Int128* v) override; + UnitV with(Float* v) override; + UnitV with(Double* v) override; + UnitV with(Var* v) override; + UnitV with(Let* v) override; + UnitV with(LetRec* v) override; + UnitV with(Fn* v) override; + UnitV with(App* v) override; + UnitV with(Assign* v) override; + UnitV with(MkArray* v) override; + UnitV with(MkVariant* v) override; + UnitV with(MkRecord* v) override; + UnitV with(AIndex* v) override; + UnitV with(Case* v) override; + UnitV with(Switch* v) override; + UnitV with(Proj* v) override; + UnitV with(Assump* v) override; + UnitV with(Pack* v) override; + UnitV with(Unpack* v) override; private: - UnitV updateTy(Expr* e); + UnitV updateTy(Expr* e) const; }; Case::Bindings switchOf(const Case::Bindings& bs, const switchExpr& f); @@ -1402,7 +1402,7 @@ ExprPtr stripExplicitAssumptions(const ExprPtr&); const ExprPtr& stripAssumpHead(const ExprPtr&); // find the free variables in a term -typedef std::set VarSet; +using VarSet = std::set; VarSet freeVars(const ExprPtr&); VarSet freeVars(const Expr&); diff --git a/include/hobbes/lang/module.H b/include/hobbes/lang/module.H index 95eff2269..637f98be5 100644 --- a/include/hobbes/lang/module.H +++ b/include/hobbes/lang/module.H @@ -26,12 +26,12 @@ protected: private: int cid; }; -typedef std::shared_ptr ModuleDefPtr; -typedef std::vector ModuleDefs; +using ModuleDefPtr = std::shared_ptr; +using ModuleDefs = std::vector; template struct ModuleDefCase : public ModuleDef { - typedef ModuleDefCase Base; + using Base = ModuleDefCase; ModuleDefCase(const LexicalAnnotation&); }; @@ -42,7 +42,7 @@ public: const std::string& path() const; const std::string& name() const; - void show(std::ostream&) const; + void show(std::ostream&) const override; static const int type_case_id = 0; private: @@ -60,7 +60,7 @@ public: const str::seq& arguments() const; const QualTypePtr& type() const; - void show(std::ostream&) const; + void show(std::ostream&) const override; static const int type_case_id = 1; private: @@ -76,15 +76,15 @@ public: const std::string& varName() const; const QualTypePtr& varType() const; - void show(std::ostream& out) const; + void show(std::ostream& out) const override; static const int type_case_id = 2; private: std::string vname; QualTypePtr qty; }; -typedef std::shared_ptr MVarTypeDefPtr; -typedef std::vector MVarTypeDefs; +using MVarTypeDefPtr = std::shared_ptr; +using MVarTypeDefs = std::vector; class MVarDef : public ModuleDefCase { public: @@ -92,20 +92,20 @@ public: const str::seq& varWithArgs() const; const ExprPtr& varExpr() const; - void show(std::ostream& out) const; + void show(std::ostream& out) const override; static const int type_case_id = 3; private: str::seq vargl; ExprPtr expr; }; -typedef std::shared_ptr MVarDefPtr; -typedef std::vector MVarDefs; +using MVarDefPtr = std::shared_ptr; +using MVarDefs = std::vector; MVarDefs substitute(const MonoTypeSubst&, const MVarDefs&); -typedef std::pair CFunDepDef; -typedef std::vector CFunDepDefs; +using CFunDepDef = std::pair; +using CFunDepDefs = std::vector; class ClassDef : public ModuleDefCase { public: @@ -114,10 +114,10 @@ public: const Constraints& constraints() const; const std::string& name() const; const str::seq& vars() const; - const CFunDepDefs fundeps() const; + CFunDepDefs fundeps() const; const MVarTypeDefs& members() const; - void show(std::ostream& out) const; + void show(std::ostream& out) const override; static const int type_case_id = 4; private: @@ -127,8 +127,8 @@ private: CFunDepDefs fdeps; MVarTypeDefs mvtydefs; }; -typedef std::shared_ptr ClassDefPtr; -typedef std::vector ClassDefs; +using ClassDefPtr = std::shared_ptr; +using ClassDefs = std::vector; class InstanceDef : public ModuleDefCase { public: @@ -139,7 +139,7 @@ public: const MonoTypes& args() const; const MVarDefs& members() const; - void show(std::ostream& out) const; + void show(std::ostream& out) const override; static const int type_case_id = 5; private: @@ -148,13 +148,13 @@ private: MonoTypes targs; MVarDefs mdefs; }; -typedef std::shared_ptr InstanceDefPtr; -typedef std::vector InstanceDefs; +using InstanceDefPtr = std::shared_ptr; +using InstanceDefs = std::vector; class MUnsafePragmaDef : public ModuleDefCase { public: MUnsafePragmaDef(const std::string& symbol, const LexicalAnnotation& la) : Base(la), symbol(symbol) {} - void show(std::ostream& out) const { out << "{-# UNSAFE " << symbol << " #-}"; } ; + void show(std::ostream& out) const override { out << "{-# UNSAFE " << symbol << " #-}"; } ; const std::string& symbolValue() const { return symbol; } static const int type_case_id = 6; @@ -166,7 +166,7 @@ private: class MSafePragmaDef : public ModuleDefCase { public: MSafePragmaDef(const std::string& symbol, const LexicalAnnotation& la) : Base(la), symbol(symbol) {} - void show(std::ostream& out) const { out << "{-# SAFE " << symbol << " #-}"; } ; + void show(std::ostream& out) const override { out << "{-# SAFE " << symbol << " #-}"; } ; const std::string& symbolValue() const { return symbol; } static const int type_case_id = 7; @@ -224,14 +224,14 @@ template struct switchMDefTyFn : switchMDef { virtual QualTypePtr withTy(const QualTypePtr&) const = 0; - ModuleDefPtr with(const MImport*) const; - ModuleDefPtr with(const MTypeDef*) const; - ModuleDefPtr with(const MVarTypeDef*) const; - ModuleDefPtr with(const MVarDef*) const; - ModuleDefPtr with(const ClassDef*) const; - ModuleDefPtr with(const InstanceDef*) const; - ModuleDefPtr with(const MUnsafePragmaDef*) const; - ModuleDefPtr with(const MSafePragmaDef*) const; + ModuleDefPtr with(const MImport*) const override; + ModuleDefPtr with(const MTypeDef*) const override; + ModuleDefPtr with(const MVarTypeDef*) const override; + ModuleDefPtr with(const MVarDef*) const override; + ModuleDefPtr with(const ClassDef*) const override; + ModuleDefPtr with(const InstanceDef*) const override; + ModuleDefPtr with(const MUnsafePragmaDef*) const override; + ModuleDefPtr with(const MSafePragmaDef*) const override; }; @@ -253,8 +253,8 @@ private: std::vector opts; }; -typedef std::shared_ptr ModulePtr; -typedef std::vector Modules; +using ModulePtr = std::shared_ptr; +using Modules = std::vector; // basic utilities std::string show(const Module& m); diff --git a/include/hobbes/lang/pat/dfa.H b/include/hobbes/lang/pat/dfa.H index 460ed47bf..f8e1f529e 100644 --- a/include/hobbes/lang/pat/dfa.H +++ b/include/hobbes/lang/pat/dfa.H @@ -13,16 +13,16 @@ namespace hobbes { -typedef size_t stateidx_t; -typedef std::set stateidxset; +using stateidx_t = size_t; +using stateidxset = std::set; -typedef std::pair PrimFArg; -typedef std::vector PrimFArgs; +using PrimFArg = std::pair; +using PrimFArgs = std::vector; // the various states of pattern matching class MState { public: - virtual ~MState(void) = default; + virtual ~MState() = default; virtual std::string stamp() = 0; // how many times is this state referenced? @@ -51,14 +51,14 @@ template class LoadVars : public MStateCase { public: - typedef std::pair Def; - typedef std::vector Defs; + using Def = std::pair; + using Defs = std::vector; LoadVars(const Defs&, stateidx_t); const Defs& defs() const; stateidx_t nextState() const; - std::string stamp(); + std::string stamp() override; static const int type_case_id = 0; private: @@ -68,15 +68,15 @@ private: class SwitchVal : public MStateCase { public: - typedef std::pair Jump; - typedef std::vector Jumps; + using Jump = std::pair; + using Jumps = std::vector; SwitchVal(const std::string&, const Jumps&, stateidx_t); const std::string& switchVar() const; const Jumps& jumps() const; stateidx_t defaultState() const; - std::string stamp(); + std::string stamp() override; static const int type_case_id = 1; private: @@ -87,15 +87,15 @@ private: class SwitchVariant : public MStateCase { public: - typedef std::pair CtorJump; - typedef std::vector CtorJumps; + using CtorJump = std::pair; + using CtorJumps = std::vector; SwitchVariant(const std::string&, const CtorJumps&, stateidx_t); const std::string& switchVar() const; const CtorJumps& jumps() const; stateidx_t defaultState() const; - std::string stamp(); + std::string stamp() override; static const int type_case_id = 2; private: @@ -110,7 +110,7 @@ public: const ExprPtr& expr() const; - std::string stamp(); + std::string stamp() override; static const int type_case_id = 3; private: @@ -123,13 +123,13 @@ template MStateCase::MStateCase() : MState(Case::type_case_id) { } -typedef std::shared_ptr MStatePtr; -typedef std::vector MStates; +using MStatePtr = std::shared_ptr; +using MStates = std::vector; // destruction-side for high-level pattern representations template struct switchMState { - virtual ~switchMState(void) = default; + virtual ~switchMState() = default; virtual T with(const LoadVars*) const = 0; virtual T with(const SwitchVal*) const = 0; virtual T with(const SwitchVariant*) const = 0; @@ -158,22 +158,22 @@ template } // DFA construction from annotated/normalized pattern match tables -typedef std::unordered_map StatesIdx; +using StatesIdx = std::unordered_map; -typedef std::unordered_map VarNames; // memoize usage of variable names -typedef std::map ArrayElem; -typedef std::unordered_map VarArrayElem; // memoize array 'element' access in match variables -typedef std::unordered_map VarArrayLen; // memoize array 'size' access in match variables -typedef std::unordered_map StructField; -typedef std::unordered_map VarStructField; // memoize struct field access in match variables +using VarNames = std::unordered_map; // memoize usage of variable names +using ArrayElem = std::map; +using VarArrayElem = std::unordered_map; // memoize array 'element' access in match variables +using VarArrayLen = std::unordered_map; // memoize array 'size' access in match variables +using StructField = std::unordered_map; +using VarStructField = std::unordered_map; // memoize struct field access in match variables -typedef std::pair FoldedState; -typedef std::vector FoldedStates; // local functions for states that should be lifted out -typedef std::unordered_map FoldedStateCalls; // call expressions into states that have been folded into local functions +using FoldedState = std::pair; +using FoldedStates = std::vector; // local functions for states that should be lifted out +using FoldedStateCalls = std::unordered_map; // call expressions into states that have been folded into local functions -typedef std::unordered_map> TableCfgStates; // map distinct pattern table configs to their corresponding states (avoid reconstructing the whole state description) +using TableCfgStates = std::unordered_map>; // map distinct pattern table configs to their corresponding states (avoid reconstructing the whole state description) -typedef std::unordered_map ExprIdxs; // map back from result expressions to row IDs +using ExprIdxs = std::unordered_map; // map back from result expressions to row IDs struct MDFA { // the lexical extent of the whole match in the original source program diff --git a/include/hobbes/lang/pat/pattern.H b/include/hobbes/lang/pat/pattern.H index e6bd9c24e..0a6f87244 100644 --- a/include/hobbes/lang/pat/pattern.H +++ b/include/hobbes/lang/pat/pattern.H @@ -14,15 +14,15 @@ namespace hobbes { -typedef std::vector Idxs; +using Idxs = std::vector; // the main signature for this module -- convert a pattern match expression to a primitive compilable expression class Pattern; -typedef std::shared_ptr PatternPtr; -typedef std::vector Patterns; +using PatternPtr = std::shared_ptr; +using Patterns = std::vector; struct PatternRow { - inline PatternRow() { } + inline PatternRow() = default; inline PatternRow(const Patterns& ps, const ExprPtr& r) : patterns(ps), result(r) { } inline PatternRow(const Patterns& ps, const ExprPtr& g, const ExprPtr& r) : patterns(ps), guard(g), result(r) { } @@ -30,8 +30,8 @@ struct PatternRow { ExprPtr guard; // a required condition for a match (may be null if there is no guard) ExprPtr result; // the expression to be evaluated when the given pattern conditions are met }; -typedef std::vector PatternRows; -typedef std::shared_ptr>> UnreachableMatchRowsPtr; +using PatternRows = std::vector; +using UnreachableMatchRowsPtr = std::shared_ptr>>; // support quick hashing of pattern tables bool operator==(const PatternRow&, const PatternRow&); @@ -76,7 +76,7 @@ private: template class PatternCase : public Pattern { public: - typedef PatternCase Base; + using Base = PatternCase; PatternCase(const LexicalAnnotation&); }; @@ -96,15 +96,15 @@ public: const ExprPtr& expression() const; const PrimitivePtr& equivConstant() const; - void show(std::ostream&) const; - bool operator==(const Pattern&) const; + void show(std::ostream&) const override; + bool operator==(const Pattern&) const override; static const int type_case_id = 0; private: PrimitivePtr p; ExprPtr e; - void assignSubNames(const std::string&); + void assignSubNames(const std::string&) override; }; // match any value, maybe bind it to a variable name @@ -114,14 +114,14 @@ public: const std::string& value() const; - void show(std::ostream&) const; - bool operator==(const Pattern&) const; + void show(std::ostream&) const override; + bool operator==(const Pattern&) const override; static const int type_case_id = 1; private: std::string vn; - void assignSubNames(const std::string&); + void assignSubNames(const std::string&) override; }; // match an array of patterns @@ -136,15 +136,15 @@ public: // allow external permutation of array match sequence void indexes(const Idxs&); - void show(std::ostream&) const; - bool operator==(const Pattern&) const; + void show(std::ostream&) const override; + bool operator==(const Pattern&) const override; static const int type_case_id = 2; private: Patterns ps; Idxs idxs; - void assignSubNames(const std::string&); + void assignSubNames(const std::string&) override; }; // match a regular expression @@ -158,20 +158,20 @@ public: static PatternPtr toRegex(const MatchArray&); - void show(std::ostream&) const; - bool operator==(const Pattern&) const; + void show(std::ostream&) const override; + bool operator==(const Pattern&) const override; static const int type_case_id = 3; private: RegexPtr regex; - void assignSubNames(const std::string&); + void assignSubNames(const std::string&) override; }; // match a record of patterns class MatchRecord : public PatternCase { public: - typedef std::pair Field; - typedef std::vector Fields; + using Field = std::pair; + using Fields = std::vector; MatchRecord(const Fields& fs, const LexicalAnnotation&); // default indexes = [0,fs.size()) @@ -182,15 +182,15 @@ public: const Fields& fields() const; void fields(const Fields&); - void show(std::ostream&) const; - bool operator==(const Pattern&) const; + void show(std::ostream&) const override; + bool operator==(const Pattern&) const override; static const int type_case_id = 4; private: Fields fs; Idxs is; - void assignSubNames(const std::string&); + void assignSubNames(const std::string&) override; static void show(std::ostream&, const Field& f); }; @@ -203,15 +203,15 @@ public: const std::string& label() const; const PatternPtr& value() const; - void show(std::ostream&) const; - bool operator==(const Pattern&) const; + void show(std::ostream&) const override; + bool operator==(const Pattern&) const override; static const int type_case_id = 5; private: std::string lbl; PatternPtr p; - void assignSubNames(const std::string&); + void assignSubNames(const std::string&) override; }; template @@ -290,8 +290,8 @@ struct CSelection { ExprPtr seq; Exprs conds; }; -typedef std::shared_ptr CSelectionPtr; -typedef std::vector CSelections; +using CSelectionPtr = std::shared_ptr; +using CSelections = std::vector; Expr* desugarComprehension(cc* c, const ExprPtr& ex, const CSelections& cs, const LexicalAnnotation& la); diff --git a/include/hobbes/lang/pat/regex.H b/include/hobbes/lang/pat/regex.H index dc69e756a..4b5d8f8c7 100644 --- a/include/hobbes/lang/pat/regex.H +++ b/include/hobbes/lang/pat/regex.H @@ -35,19 +35,19 @@ class cc; * rstates : a mapping of F return codes to input regex indexes */ struct Regex { - virtual ~Regex(void) = default; + virtual ~Regex() = default; virtual void show(std::ostream&) const = 0; }; -typedef std::shared_ptr RegexPtr; -typedef std::vector Regexes; +using RegexPtr = std::shared_ptr; +using Regexes = std::vector; RegexPtr parseRegex(const std::string&); str::seq bindingNames(const RegexPtr&); -typedef size_t RegexIdx; -typedef std::set RegexIdxs; -typedef std::map RStates; +using RegexIdx = size_t; +using RegexIdxs = std::set; +using RStates = std::map; -typedef std::map CaptureVarsAt; +using CaptureVarsAt = std::map; struct CRegexes { std::string fname; // the low-level function that evaluates a set of regular expressions against an input @@ -58,8 +58,8 @@ struct CRegexes { CRegexes makeRegexFn(cc*, const Regexes&, const LexicalAnnotation&); -typedef std::pair CVarDef; -typedef std::vector CVarDefs; +using CVarDef = std::pair; +using CVarDefs = std::vector; CVarDefs unpackCaptureVars(const std::string& strVar, const std::string& bufferVar, const CRegexes&, size_t state, const LexicalAnnotation&); diff --git a/include/hobbes/lang/preds/appendsto.H b/include/hobbes/lang/preds/appendsto.H index 88879eb69..923aef381 100644 --- a/include/hobbes/lang/preds/appendsto.H +++ b/include/hobbes/lang/preds/appendsto.H @@ -21,6 +21,8 @@ bool dec(const ConstraintPtr&, AppendsTo*); // an "appendsto eliminator" knows how to resolve an "AppendsTo" constraint at a particular (category of) type struct ATEliminator { + virtual ~ATEliminator() = default; + // is this AT instance eliminable? virtual bool satisfied(const TEnvPtr& tenv, const MonoTypePtr& lhs, const MonoTypePtr& rhs, const MonoTypePtr& result) const = 0; @@ -45,19 +47,19 @@ public: static std::string constraintName(); // extend the set of 'appendsto' eliminators dynamically (dangerous?) - void addEliminator(ATEliminator*); + void addEliminator(const std::shared_ptr&); // unqualifier interface - bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*); - bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs); - ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&, const ExprPtr&, Definitions*) const; - PolyTypePtr lookup (const std::string& vn) const; - SymSet bindings () const; - FunDeps dependencies(const ConstraintPtr&) const; + bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*) override; + bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs) override; + ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&, const ExprPtr&, Definitions*) const override; + PolyTypePtr lookup (const std::string& vn) const override; + SymSet bindings () const override; + FunDeps dependencies(const ConstraintPtr&) const override; private: - typedef std::vector ATEliminators; + using ATEliminators = std::vector>; ATEliminators eliminators; ATEliminator* findEliminator(const TEnvPtr&, const AppendsTo*) const; diff --git a/include/hobbes/lang/preds/appendsto/record.H b/include/hobbes/lang/preds/appendsto/record.H index 8a3604816..262f675ec 100644 --- a/include/hobbes/lang/preds/appendsto/record.H +++ b/include/hobbes/lang/preds/appendsto/record.H @@ -7,12 +7,12 @@ namespace hobbes { struct ATRecordEliminator : public ATEliminator { - bool satisfied(const TEnvPtr& tenv, const MonoTypePtr& rty, const MonoTypePtr& fname, const MonoTypePtr& fty) const; - bool satisfiable(const TEnvPtr& tenv, const MonoTypePtr& rty, const MonoTypePtr& fname, const MonoTypePtr& fty) const; - bool refine(const TEnvPtr& tenv, const MonoTypePtr& rty, const MonoTypePtr& fieldName, const MonoTypePtr& fty, MonoTypeUnifier* s); - PolyTypePtr lookup(const std::string& vn) const; - SymSet bindings() const; - ExprPtr unqualify(const TEnvPtr&, const ConstraintPtr&, const ExprPtr&, Definitions*) const; + bool satisfied(const TEnvPtr& tenv, const MonoTypePtr& rty, const MonoTypePtr& fname, const MonoTypePtr& fty) const override; + bool satisfiable(const TEnvPtr& tenv, const MonoTypePtr& rty, const MonoTypePtr& fname, const MonoTypePtr& fty) const override; + bool refine(const TEnvPtr& tenv, const MonoTypePtr& rty, const MonoTypePtr& fieldName, const MonoTypePtr& fty, MonoTypeUnifier* s) override; + PolyTypePtr lookup(const std::string& vn) const override; + SymSet bindings() const override; + ExprPtr unqualify(const TEnvPtr&, const ConstraintPtr&, const ExprPtr&, Definitions*) const override; }; } diff --git a/include/hobbes/lang/preds/class.H b/include/hobbes/lang/preds/class.H index f12e71023..04ac66f04 100644 --- a/include/hobbes/lang/preds/class.H +++ b/include/hobbes/lang/preds/class.H @@ -18,20 +18,20 @@ FunDeps inferFundeps(const TEnvPtr& tenv, const Constraints& cs); FunDeps mergeFundeps(const FunDeps& lhs, const FunDeps& rhs); // a 'member mapping' is a set of named overloaded definitions -typedef std::map MemberMapping; +using MemberMapping = std::map; // a 'type class' is a scheme for overloading terms class TCInstance; -typedef std::shared_ptr TCInstancePtr; -typedef std::vector TCInstances; +using TCInstancePtr = std::shared_ptr; +using TCInstances = std::vector; class TCInstanceFn; -typedef std::shared_ptr TCInstanceFnPtr; -typedef std::vector TCInstanceFns; +using TCInstanceFnPtr = std::shared_ptr; +using TCInstanceFns = std::vector; class TClass : public Unqualifier, public LexicallyAnnotated { public: - typedef std::map Members; + using Members = std::map; TClass(const Constraints& reqs, const std::string& tcname, size_t tvs, const Members& tcmembers, const LexicalAnnotation&); TClass(const Constraints& reqs, const std::string& tcname, size_t tvs, const Members& tcmembers, const FunDeps& fundeps, const LexicalAnnotation&); @@ -53,14 +53,14 @@ public: TCInstances matches(const TEnvPtr& tenv, const MonoTypes& mts, MonoTypeUnifier*, Definitions* ds) const; // unqualifier interface - bool refine (const TEnvPtr& tenv, const ConstraintPtr& cst, MonoTypeUnifier* s, Definitions* ds); - bool satisfied (const TEnvPtr& tenv, const ConstraintPtr& cst, Definitions* ds) const; - bool satisfiable(const TEnvPtr& tenv, const ConstraintPtr& cst, Definitions* ds) const; - void explain (const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs); - ExprPtr unqualify (const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds) const; - PolyTypePtr lookup (const std::string& vn) const; - SymSet bindings () const; - FunDeps dependencies(const ConstraintPtr&) const; + bool refine (const TEnvPtr& tenv, const ConstraintPtr& cst, MonoTypeUnifier* s, Definitions* ds) override; + bool satisfied (const TEnvPtr& tenv, const ConstraintPtr& cst, Definitions* ds) const override; + bool satisfiable(const TEnvPtr& tenv, const ConstraintPtr& cst, Definitions* ds) const override; + void explain (const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs) override; + ExprPtr unqualify (const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds) const override; + PolyTypePtr lookup (const std::string& vn) const override; + SymSet bindings () const override; + FunDeps dependencies(const ConstraintPtr&) const override; // the member type in the implied context of this class's qua[nt|l]ification // (normally you should use 'lookup' to get fully qualified types) @@ -75,8 +75,8 @@ public: private: friend class TCInstanceFn; - typedef type_map TCMonoInstDB; - typedef type_map TCInstFnDB; + using TCMonoInstDB = type_map; + using TCInstFnDB = type_map; std::string tcname; size_t tvs; @@ -93,18 +93,18 @@ private: bool refine(const TEnvPtr& tenv, const ConstraintPtr& c, const FunDep& fd, MonoTypeUnifier* s, Definitions* ds) const; // to support recursive types, track recursive invocations and assume they're satisfiable - typedef type_map TestedInstances; + using TestedInstances = type_map; mutable TestedInstances testedInstances; // cache satisfiability tests mutable TestedInstances satfInstances; }; -typedef std::shared_ptr TClassPtr; -typedef std::map TClassEnv; +using TClassPtr = std::shared_ptr; +using TClassEnv = std::map; class TCInstance : public LexicallyAnnotated { public: - typedef std::shared_ptr ExprPtr; + using ExprPtr = std::shared_ptr; TCInstance(const std::string& tcname, const MonoTypes& itys, const MemberMapping& mmap, const LexicalAnnotation&); @@ -135,10 +135,10 @@ public: size_t arity() const; // can we immediately exclude this instance generator for this type list? - bool satisfiable(const TEnvPtr&, const MonoTypes&, Definitions*); + bool satisfiable(const TEnvPtr&, const MonoTypes&, Definitions*) const; // assuming we're not satisfiable, what are the constraints that aren't satisfiable? - void explainSatisfiability(const TEnvPtr&, const MonoTypes&, Definitions*, Constraints*, Constraints*); + void explainSatisfiability(const TEnvPtr&, const MonoTypes&, Definitions*, Constraints*, Constraints*) const; // (possibly) produce a type class instance from this generator bool apply(const TEnvPtr& tenv, const MonoTypes& tys, const TClass* c, MonoTypeUnifier*, Definitions* rdefs, TCInstancePtr* out) const; @@ -154,7 +154,7 @@ public: void show(std::ostream&) const; // produce a sequence of type variables and constraints unique to this invocation - typedef std::pair IFnDef; + using IFnDef = std::pair; IFnDef freshDef(MonoTypeSubst* s) const; private: std::string tcname; diff --git a/include/hobbes/lang/preds/consrecord.H b/include/hobbes/lang/preds/consrecord.H index d09c41bac..8e20e03f0 100644 --- a/include/hobbes/lang/preds/consrecord.H +++ b/include/hobbes/lang/preds/consrecord.H @@ -22,14 +22,14 @@ public: static std::string constraintName(); // unqualifier interface - bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*); - bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs); - ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&, const ExprPtr&, Definitions*) const; - PolyTypePtr lookup (const std::string& vn) const; - SymSet bindings () const; - FunDeps dependencies(const ConstraintPtr&) const; + bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*) override; + bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs) override; + ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&, const ExprPtr&, Definitions*) const override; + PolyTypePtr lookup (const std::string& vn) const override; + SymSet bindings () const override; + FunDeps dependencies(const ConstraintPtr&) const override; }; } diff --git a/include/hobbes/lang/preds/consvariant.H b/include/hobbes/lang/preds/consvariant.H index ea80df74e..3faa0ec2e 100644 --- a/include/hobbes/lang/preds/consvariant.H +++ b/include/hobbes/lang/preds/consvariant.H @@ -19,14 +19,14 @@ public: static std::string constraintName(); // unqualifier interface - bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*); - bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs); - ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&, const ExprPtr&, Definitions*) const; - PolyTypePtr lookup (const std::string& vn) const; - SymSet bindings () const; - FunDeps dependencies(const ConstraintPtr&) const; + bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*) override; + bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs) override; + ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&, const ExprPtr&, Definitions*) const override; + PolyTypePtr lookup (const std::string& vn) const override; + SymSet bindings () const override; + FunDeps dependencies(const ConstraintPtr&) const override; }; } diff --git a/include/hobbes/lang/preds/cpptdesc.H b/include/hobbes/lang/preds/cpptdesc.H index a364f2586..4d102e40c 100644 --- a/include/hobbes/lang/preds/cpptdesc.H +++ b/include/hobbes/lang/preds/cpptdesc.H @@ -12,14 +12,14 @@ public: static std::string constraintName(); // unqualifier interface - bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*); - bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs); - ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&,const ExprPtr&,Definitions*) const; - PolyTypePtr lookup (const std::string& vn) const; - SymSet bindings () const; - FunDeps dependencies(const ConstraintPtr&) const; + bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*) override; + bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs) override; + ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&,const ExprPtr&,Definitions*) const override; + PolyTypePtr lookup (const std::string& vn) const override; + SymSet bindings () const override; + FunDeps dependencies(const ConstraintPtr&) const override; }; } diff --git a/include/hobbes/lang/preds/data.H b/include/hobbes/lang/preds/data.H index d48354b79..31e03bda4 100644 --- a/include/hobbes/lang/preds/data.H +++ b/include/hobbes/lang/preds/data.H @@ -15,14 +15,14 @@ public: static std::string constraintName(); // unqualifier interface - bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*); - bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs); - ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&,const ExprPtr&,Definitions*) const; - PolyTypePtr lookup (const std::string& vn) const; - SymSet bindings () const; - FunDeps dependencies(const ConstraintPtr&) const; + bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*) override; + bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs) override; + ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&,const ExprPtr&,Definitions*) const override; + PolyTypePtr lookup (const std::string& vn) const override; + SymSet bindings () const override; + FunDeps dependencies(const ConstraintPtr&) const override; }; } diff --git a/include/hobbes/lang/preds/deconstruct.H b/include/hobbes/lang/preds/deconstruct.H index 6f14b5f32..8c8f60526 100644 --- a/include/hobbes/lang/preds/deconstruct.H +++ b/include/hobbes/lang/preds/deconstruct.H @@ -15,14 +15,14 @@ public: static std::string constraintName(); // unqualifier interface - bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*); - bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs); - ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&,const ExprPtr&,Definitions*) const; - PolyTypePtr lookup (const std::string& vn) const; - SymSet bindings () const; - FunDeps dependencies(const ConstraintPtr&) const; + bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*) override; + bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs) override; + ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&,const ExprPtr&,Definitions*) const override; + PolyTypePtr lookup (const std::string& vn) const override; + SymSet bindings () const override; + FunDeps dependencies(const ConstraintPtr&) const override; }; } diff --git a/include/hobbes/lang/preds/equal.H b/include/hobbes/lang/preds/equal.H index abbf1c946..fed9ee8d5 100644 --- a/include/hobbes/lang/preds/equal.H +++ b/include/hobbes/lang/preds/equal.H @@ -13,14 +13,14 @@ public: static std::string constraintName(); // unqualifier interface - bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*); - bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs); - ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&,const ExprPtr&,Definitions*) const; - PolyTypePtr lookup (const std::string& vn) const; - SymSet bindings () const; - FunDeps dependencies(const ConstraintPtr&) const; + bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*) override; + bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs) override; + ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&,const ExprPtr&,Definitions*) const override; + PolyTypePtr lookup (const std::string& vn) const override; + SymSet bindings () const override; + FunDeps dependencies(const ConstraintPtr&) const override; }; } diff --git a/include/hobbes/lang/preds/hasctor.H b/include/hobbes/lang/preds/hasctor.H index 6b9caf719..d45f21ab8 100644 --- a/include/hobbes/lang/preds/hasctor.H +++ b/include/hobbes/lang/preds/hasctor.H @@ -14,6 +14,8 @@ struct HasCtor { // a "has-ctor eliminator" knows how to resolve a "HasCtor" constraint at a particular (category of) type struct HCEliminator { + virtual ~HCEliminator() = default; + // is this HC instance eliminable? virtual bool satisfied(const TEnvPtr& tenv, const HasCtor&, Definitions*) const = 0; @@ -37,19 +39,19 @@ public: static std::string constraintName(); // extend the set of 'hasctor' eliminators dynamically (dangerous?) - void addEliminator(HCEliminator*); + void addEliminator(const std::shared_ptr&); // unqualifier interface - bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*); - bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs); - ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&, const ExprPtr&, Definitions*) const; - PolyTypePtr lookup (const std::string& vn) const; - SymSet bindings () const; - FunDeps dependencies(const ConstraintPtr&) const; + bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*) override; + bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs) override; + ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&, const ExprPtr&, Definitions*) const override; + PolyTypePtr lookup (const std::string& vn) const override; + SymSet bindings () const override; + FunDeps dependencies(const ConstraintPtr&) const override; private: - typedef std::vector HCEliminators; + using HCEliminators = std::vector>; HCEliminators eliminators; HCEliminator* findEliminator(const TEnvPtr&, const HasCtor&, Definitions*) const; diff --git a/include/hobbes/lang/preds/hasctor/variant.H b/include/hobbes/lang/preds/hasctor/variant.H index 7c4b1d13f..6f4267d64 100644 --- a/include/hobbes/lang/preds/hasctor/variant.H +++ b/include/hobbes/lang/preds/hasctor/variant.H @@ -7,13 +7,15 @@ namespace hobbes { struct HCVariantEliminator : public HCEliminator { - bool satisfied(const TEnvPtr& tenv, const HasCtor&, Definitions*) const; - bool satisfiable(const TEnvPtr& tenv, const HasCtor&, Definitions*) const; - bool refine(const TEnvPtr& tenv, const HasCtor&, MonoTypeUnifier* s, Definitions*); - ExprPtr unqualify(const TEnvPtr&, const ConstraintPtr&, const HasCtor&, const ExprPtr&, Definitions*) const; - std::string name() const; + bool satisfied(const TEnvPtr& tenv, const HasCtor&, Definitions*) const override; + bool satisfiable(const TEnvPtr& tenv, const HasCtor&, Definitions*) const override; + bool refine(const TEnvPtr& tenv, const HasCtor&, MonoTypeUnifier* s, Definitions*) override; + ExprPtr unqualify(const TEnvPtr&, const ConstraintPtr&, const HasCtor&, const ExprPtr&, Definitions*) const override; + std::string name() const override; }; +const Variant* isVariantPEnum(const MonoTypePtr& e); + } #endif diff --git a/include/hobbes/lang/preds/hasfield.H b/include/hobbes/lang/preds/hasfield.H index 5492b366a..4fac67635 100644 --- a/include/hobbes/lang/preds/hasfield.H +++ b/include/hobbes/lang/preds/hasfield.H @@ -3,6 +3,7 @@ #define HOBBES_LANG_TYPEPREDS_HASFIELD_HPP_INCLUDED #include +#include namespace hobbes { @@ -56,19 +57,19 @@ public: static std::string constraintName(); // extend the set of 'hasfield' eliminators dynamically (dangerous?) - void addEliminator(HFEliminator*); + void addEliminator(const std::shared_ptr&); // unqualifier interface - bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*); - bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs); - ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&, const ExprPtr&, Definitions*) const; - PolyTypePtr lookup (const std::string& vn) const; - SymSet bindings () const; - FunDeps dependencies(const ConstraintPtr&) const; + bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*) override; + bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs) override; + ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&, const ExprPtr&, Definitions*) const override; + PolyTypePtr lookup (const std::string& vn) const override; + SymSet bindings () const override; + FunDeps dependencies(const ConstraintPtr&) const override; private: - typedef std::vector HFEliminators; + using HFEliminators = std::vector>; HFEliminators eliminators; }; diff --git a/include/hobbes/lang/preds/hasfield/lookup.H b/include/hobbes/lang/preds/hasfield/lookup.H index 73cdbdb1b..a8a4a7c77 100644 --- a/include/hobbes/lang/preds/hasfield/lookup.H +++ b/include/hobbes/lang/preds/hasfield/lookup.H @@ -8,11 +8,11 @@ namespace hobbes { struct HFLookupEliminator : public HFEliminator { - bool satisfied(const TEnvPtr& tenv, const HasField&, Definitions*) const; - bool satisfiable(const TEnvPtr& tenv, const HasField&, Definitions*) const; - bool refine(const TEnvPtr& tenv, const HasField&, MonoTypeUnifier* s, Definitions*); - ExprPtr unqualify(const TEnvPtr&, const ConstraintPtr&, const ExprPtr&, Definitions*) const; - std::string name() const; + bool satisfied(const TEnvPtr& tenv, const HasField&, Definitions*) const override; + bool satisfiable(const TEnvPtr& tenv, const HasField&, Definitions*) const override; + bool refine(const TEnvPtr& tenv, const HasField&, MonoTypeUnifier* s, Definitions*) override; + ExprPtr unqualify(const TEnvPtr&, const ConstraintPtr&, const ExprPtr&, Definitions*) const override; + std::string name() const override; }; } diff --git a/include/hobbes/lang/preds/hasfield/record.H b/include/hobbes/lang/preds/hasfield/record.H index 6f886e4f5..93d2d7c06 100644 --- a/include/hobbes/lang/preds/hasfield/record.H +++ b/include/hobbes/lang/preds/hasfield/record.H @@ -7,11 +7,11 @@ namespace hobbes { struct HFRecordEliminator : public HFEliminator { - bool satisfied(const TEnvPtr& tenv, const HasField&, Definitions*) const; - bool satisfiable(const TEnvPtr& tenv, const HasField&, Definitions*) const; - bool refine(const TEnvPtr& tenv, const HasField&, MonoTypeUnifier* s, Definitions*); - ExprPtr unqualify(const TEnvPtr&, const ConstraintPtr&, const ExprPtr&, Definitions*) const; - std::string name() const; + bool satisfied(const TEnvPtr& tenv, const HasField&, Definitions*) const override; + bool satisfiable(const TEnvPtr& tenv, const HasField&, Definitions*) const override; + bool refine(const TEnvPtr& tenv, const HasField&, MonoTypeUnifier* s, Definitions*) override; + ExprPtr unqualify(const TEnvPtr&, const ConstraintPtr&, const ExprPtr&, Definitions*) const override; + std::string name() const override; }; } diff --git a/include/hobbes/lang/preds/hasfield/slookup.H b/include/hobbes/lang/preds/hasfield/slookup.H index 47829a77d..43df2f972 100644 --- a/include/hobbes/lang/preds/hasfield/slookup.H +++ b/include/hobbes/lang/preds/hasfield/slookup.H @@ -8,11 +8,11 @@ namespace hobbes { struct HFSLookupEliminator : public HFEliminator { - bool satisfied(const TEnvPtr& tenv, const HasField&, Definitions*) const; - bool satisfiable(const TEnvPtr& tenv, const HasField&, Definitions*) const; - bool refine(const TEnvPtr& tenv, const HasField&, MonoTypeUnifier* s, Definitions*); - ExprPtr unqualify(const TEnvPtr&, const ConstraintPtr&, const ExprPtr&, Definitions*) const; - std::string name() const; + bool satisfied(const TEnvPtr& tenv, const HasField&, Definitions*) const override; + bool satisfiable(const TEnvPtr& tenv, const HasField&, Definitions*) const override; + bool refine(const TEnvPtr& tenv, const HasField&, MonoTypeUnifier* s, Definitions*) override; + ExprPtr unqualify(const TEnvPtr&, const ConstraintPtr&, const ExprPtr&, Definitions*) const override; + std::string name() const override; }; } diff --git a/include/hobbes/lang/preds/hasfield/tenvlookup.H b/include/hobbes/lang/preds/hasfield/tenvlookup.H index a32af5b84..5ecc545f0 100644 --- a/include/hobbes/lang/preds/hasfield/tenvlookup.H +++ b/include/hobbes/lang/preds/hasfield/tenvlookup.H @@ -7,11 +7,11 @@ namespace hobbes { struct HFTEnvLookupEliminator : public HFEliminator { - bool satisfied(const TEnvPtr& tenv, const HasField&, Definitions*) const; - bool satisfiable(const TEnvPtr& tenv, const HasField&, Definitions*) const; - bool refine(const TEnvPtr& tenv, const HasField&, MonoTypeUnifier* s, Definitions*); - ExprPtr unqualify(const TEnvPtr&, const ConstraintPtr&, const ExprPtr&, Definitions*) const; - std::string name() const; + bool satisfied(const TEnvPtr& tenv, const HasField&, Definitions*) const override; + bool satisfiable(const TEnvPtr& tenv, const HasField&, Definitions*) const override; + bool refine(const TEnvPtr& tenv, const HasField&, MonoTypeUnifier* s, Definitions*) override; + ExprPtr unqualify(const TEnvPtr&, const ConstraintPtr&, const ExprPtr&, Definitions*) const override; + std::string name() const override; }; } diff --git a/include/hobbes/lang/preds/loadref.H b/include/hobbes/lang/preds/loadref.H index a0cc4daa5..301a8b922 100644 --- a/include/hobbes/lang/preds/loadref.H +++ b/include/hobbes/lang/preds/loadref.H @@ -13,14 +13,14 @@ public: static std::string constraintName(); // unqualifier interface - bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*); - bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs); - ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&,const ExprPtr&,Definitions*) const; - PolyTypePtr lookup (const std::string& vn) const; - SymSet bindings () const; - FunDeps dependencies(const ConstraintPtr&) const; + bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*) override; + bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs) override; + ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&,const ExprPtr&,Definitions*) const override; + PolyTypePtr lookup (const std::string& vn) const override; + SymSet bindings () const override; + FunDeps dependencies(const ConstraintPtr&) const override; }; } diff --git a/include/hobbes/lang/preds/not.H b/include/hobbes/lang/preds/not.H index ed5917ed0..55fc5c33f 100644 --- a/include/hobbes/lang/preds/not.H +++ b/include/hobbes/lang/preds/not.H @@ -13,14 +13,14 @@ public: static std::string constraintName(); // unqualifier interface - bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*); - bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs); - ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&,const ExprPtr&,Definitions*) const; - PolyTypePtr lookup (const std::string& vn) const; - SymSet bindings () const; - FunDeps dependencies(const ConstraintPtr&) const; + bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*) override; + bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs) override; + ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&,const ExprPtr&,Definitions*) const override; + PolyTypePtr lookup (const std::string& vn) const override; + SymSet bindings () const override; + FunDeps dependencies(const ConstraintPtr&) const override; }; } diff --git a/include/hobbes/lang/preds/packsto.H b/include/hobbes/lang/preds/packsto.H index a36e0bcdf..c0191d41c 100644 --- a/include/hobbes/lang/preds/packsto.H +++ b/include/hobbes/lang/preds/packsto.H @@ -13,14 +13,14 @@ public: static std::string constraintName(); // unqualifier interface - bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*); - bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs); - ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&,const ExprPtr&, Definitions*) const; - PolyTypePtr lookup (const std::string& vn) const; - SymSet bindings () const; - FunDeps dependencies(const ConstraintPtr&) const; + bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*) override; + bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs) override; + ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&,const ExprPtr&, Definitions*) const override; + PolyTypePtr lookup (const std::string& vn) const override; + SymSet bindings () const override; + FunDeps dependencies(const ConstraintPtr&) const override; }; } diff --git a/include/hobbes/lang/preds/recty.H b/include/hobbes/lang/preds/recty.H index c040c17c8..3ec51b1c7 100644 --- a/include/hobbes/lang/preds/recty.H +++ b/include/hobbes/lang/preds/recty.H @@ -13,14 +13,14 @@ public: static std::string constraintName(); // unqualifier interface - bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*); - bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs); - ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&,const ExprPtr&,Definitions*) const; - PolyTypePtr lookup (const std::string& vn) const; - SymSet bindings () const; - FunDeps dependencies(const ConstraintPtr&) const; + bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*) override; + bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs) override; + ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&,const ExprPtr&,Definitions*) const override; + PolyTypePtr lookup (const std::string& vn) const override; + SymSet bindings () const override; + FunDeps dependencies(const ConstraintPtr&) const override; }; } diff --git a/include/hobbes/lang/preds/sizeof.H b/include/hobbes/lang/preds/sizeof.H index 7adfb531e..9fa90a4bf 100644 --- a/include/hobbes/lang/preds/sizeof.H +++ b/include/hobbes/lang/preds/sizeof.H @@ -12,14 +12,14 @@ public: static std::string constraintName(); // unqualifier interface - bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*); - bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs); - ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&,const ExprPtr&,Definitions*) const; - PolyTypePtr lookup (const std::string& vn) const; - SymSet bindings () const; - FunDeps dependencies(const ConstraintPtr&) const; + bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*) override; + bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs) override; + ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&,const ExprPtr&,Definitions*) const override; + PolyTypePtr lookup (const std::string& vn) const override; + SymSet bindings () const override; + FunDeps dependencies(const ConstraintPtr&) const override; }; } diff --git a/include/hobbes/lang/preds/subtype.H b/include/hobbes/lang/preds/subtype.H index 80586f386..f8b3597e5 100644 --- a/include/hobbes/lang/preds/subtype.H +++ b/include/hobbes/lang/preds/subtype.H @@ -15,7 +15,7 @@ bool dec(const ConstraintPtr&, Subtype*); // a "subtype eliminator" knows how to resolve a "Subtype" constraint at a particular (category of) type struct SubtypeEliminator { - virtual ~SubtypeEliminator(void) = default; + virtual ~SubtypeEliminator() = default; // is this instance eliminable? virtual bool satisfied(const TEnvPtr& tenv, const MonoTypePtr& lhs, const MonoTypePtr& rhs) const = 0; @@ -40,19 +40,19 @@ public: static std::string constraintName(); // extend the set of 'subtype' eliminators dynamically (dangerous?) - void addEliminator(SubtypeEliminator*); + void addEliminator(const std::shared_ptr&); // unqualifier interface - bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*); - bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs); - ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&, const ExprPtr&, Definitions*) const; - PolyTypePtr lookup (const std::string& vn) const; - SymSet bindings () const; - FunDeps dependencies(const ConstraintPtr&) const; + bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*) override; + bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs) override; + ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&, const ExprPtr&, Definitions*) const override; + PolyTypePtr lookup (const std::string& vn) const override; + SymSet bindings () const override; + FunDeps dependencies(const ConstraintPtr&) const override; private: - typedef std::vector SubtypeEliminators; + using SubtypeEliminators = std::vector>; SubtypeEliminators eliminators; SubtypeEliminator* findEliminator(const TEnvPtr&, const Subtype&) const; diff --git a/include/hobbes/lang/preds/subtype/obj.H b/include/hobbes/lang/preds/subtype/obj.H index 85cc73d75..8ce48b1dc 100644 --- a/include/hobbes/lang/preds/subtype/obj.H +++ b/include/hobbes/lang/preds/subtype/obj.H @@ -38,7 +38,7 @@ struct PtrAdjustment { } } }; -typedef std::vector PtrAdjustmentPath; // for A <: ... <: Z, all adjustments +using PtrAdjustmentPath = std::vector; // for A <: ... <: Z, all adjustments std::string show(const PtrAdjustmentPath& p); @@ -46,7 +46,7 @@ std::string show(const PtrAdjustmentPath& p); // (this implementation only works with GCC) class Objs : public SubtypeEliminator { public: - virtual ~Objs(void) = default; + virtual ~Objs() = default; #ifndef __clang__ typedef __cxxabiv1::__class_type_info class_type; typedef __cxxabiv1::__si_class_type_info si_class_type; @@ -55,7 +55,7 @@ public: // record class definitions void add(const class_type* ct); #else - typedef int class_type; + using class_type = int; #endif bool add(const std::type_info& ti); bool add(const std::type_info* ti); @@ -77,21 +77,21 @@ public: PolyTypePtr generalize(const MonoTypePtr& mt) const; // subtype eliminator interface - bool refine (const TEnvPtr& tenv, const MonoTypePtr& lhs, const MonoTypePtr& rhs, MonoTypeUnifier* s); - bool satisfied (const TEnvPtr& tenv, const MonoTypePtr& lhs, const MonoTypePtr& rhs) const; - bool satisfiable(const TEnvPtr& tenv, const MonoTypePtr& lhs, const MonoTypePtr& rhs) const; + bool refine (const TEnvPtr& tenv, const MonoTypePtr& lhs, const MonoTypePtr& rhs, MonoTypeUnifier* s) override; + bool satisfied (const TEnvPtr& tenv, const MonoTypePtr& lhs, const MonoTypePtr& rhs) const override; + bool satisfiable(const TEnvPtr& tenv, const MonoTypePtr& lhs, const MonoTypePtr& rhs) const override; - ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&,const ExprPtr&,Definitions*) const; - PolyTypePtr lookup (const std::string& vn) const; - SymSet bindings () const; + ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&,const ExprPtr&,Definitions*) const override; + PolyTypePtr lookup (const std::string& vn) const override; + SymSet bindings () const override; private: - typedef std::map ClassDefs; + using ClassDefs = std::map; ClassDefs classDefs; bool mayBeKnown(const MonoTypePtr& mt) const; bool pathExists(const std::string& from, const std::string& to) const; }; -typedef std::shared_ptr ObjsPtr; +using ObjsPtr = std::shared_ptr; } diff --git a/include/hobbes/lang/preds/typeof.H b/include/hobbes/lang/preds/typeof.H index b49c0752f..27d7f4804 100644 --- a/include/hobbes/lang/preds/typeof.H +++ b/include/hobbes/lang/preds/typeof.H @@ -13,14 +13,14 @@ public: static std::string constraintName(); // unqualifier interface - bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*); - bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs); - ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&,const ExprPtr&,Definitions*) const; - PolyTypePtr lookup (const std::string& vn) const; - SymSet bindings () const; - FunDeps dependencies(const ConstraintPtr&) const; + bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*) override; + bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs) override; + ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&,const ExprPtr&,Definitions*) const override; + PolyTypePtr lookup (const std::string& vn) const override; + SymSet bindings () const override; + FunDeps dependencies(const ConstraintPtr&) const override; }; } diff --git a/include/hobbes/lang/preds/vapp.H b/include/hobbes/lang/preds/vapp.H index 5c512bd1b..91110cc64 100644 --- a/include/hobbes/lang/preds/vapp.H +++ b/include/hobbes/lang/preds/vapp.H @@ -17,14 +17,14 @@ public: static std::string constraintName(); // unqualifier interface - bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*); - bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs); - ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&, const ExprPtr&, Definitions*) const; - PolyTypePtr lookup (const std::string& vn) const; - SymSet bindings () const; - FunDeps dependencies(const ConstraintPtr&) const; + bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*) override; + bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs) override; + ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&, const ExprPtr&, Definitions*) const override; + PolyTypePtr lookup (const std::string& vn) const override; + SymSet bindings () const override; + FunDeps dependencies(const ConstraintPtr&) const override; }; } diff --git a/include/hobbes/lang/preds/vtrunc.H b/include/hobbes/lang/preds/vtrunc.H index e4358385f..73c1975ed 100644 --- a/include/hobbes/lang/preds/vtrunc.H +++ b/include/hobbes/lang/preds/vtrunc.H @@ -17,14 +17,14 @@ public: static std::string constraintName(); // unqualifier interface - bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*); - bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs); - ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&, const ExprPtr&, Definitions*) const; - PolyTypePtr lookup (const std::string& vn) const; - SymSet bindings () const; - FunDeps dependencies(const ConstraintPtr&) const; + bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*) override; + bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + void explain(const TEnvPtr& tenv, const ConstraintPtr& cst, const ExprPtr& e, Definitions* ds, annmsgs* msgs) override; + ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&, const ExprPtr&, Definitions*) const override; + PolyTypePtr lookup (const std::string& vn) const override; + SymSet bindings () const override; + FunDeps dependencies(const ConstraintPtr&) const override; }; } diff --git a/include/hobbes/lang/tylift.H b/include/hobbes/lang/tylift.H index fd2486c8a..9376fce8e 100644 --- a/include/hobbes/lang/tylift.H +++ b/include/hobbes/lang/tylift.H @@ -16,6 +16,8 @@ #include #include +extern hobbes::MonoTypePtr makePVarType(const hobbes::Variant::Members &vms); + namespace hobbes { /********* @@ -41,18 +43,18 @@ struct typedb { }; struct nulltypedb : public typedb { - MonoTypePtr defineNamedType(const std::string& name, const str::seq& argNames, const MonoTypePtr& ty); - bool isTypeName(const std::string&) const; - [[noreturn]] MonoTypePtr namedTypeRepresentation(const std::string&) const; + MonoTypePtr defineNamedType(const std::string& name, const str::seq& argNames, const MonoTypePtr& ty) override; + bool isTypeName(const std::string&) const override; + [[noreturn]] MonoTypePtr namedTypeRepresentation(const std::string&) const override; - [[noreturn]] void defineTypeAlias(const std::string& name, const str::seq& argNames, const MonoTypePtr& ty); - bool isTypeAliasName(const std::string& name) const; - MonoTypePtr replaceTypeAliases(const MonoTypePtr& ty) const; + [[noreturn]] void defineTypeAlias(const std::string& name, const str::seq& argNames, const MonoTypePtr& ty) override; + bool isTypeAliasName(const std::string& name) const override; + MonoTypePtr replaceTypeAliases(const MonoTypePtr& ty) const override; - [[noreturn]] PolyTypePtr opaquePtrPolyType(const std::type_info&, unsigned int sz, bool inStruct); - [[noreturn]] MonoTypePtr opaquePtrMonoType(const std::type_info&, unsigned int sz, bool inStruct); + [[noreturn]] PolyTypePtr opaquePtrPolyType(const std::type_info&, unsigned int sz, bool inStruct) override; + [[noreturn]] MonoTypePtr opaquePtrMonoType(const std::type_info&, unsigned int sz, bool inStruct) override; - PolyTypePtr generalize(const MonoTypePtr& mt) const; + PolyTypePtr generalize(const MonoTypePtr& mt) const override; }; extern nulltypedb nulltdb; @@ -73,8 +75,8 @@ struct recursion { // a linked list is a recursive sum of nested tuples starting at unit template struct seq { - typedef std::pair*> pair_t; - typedef variant rep_t; + using pair_t = std::pair *>; + using rep_t = variant; rep_t data; seq() : data(unit()) { } @@ -167,7 +169,7 @@ template template struct liftPair { static MonoTypePtr type(typedb& tenv) { - typedef std::pair FS; + using FS = std::pair; Record::Members fs; fs.push_back(Record::Member(".f0", lift::type(tenv), offsetof(FS, first))); fs.push_back(Record::Member(".f1", lift::type(tenv), offsetof(FS, second))); @@ -310,7 +312,7 @@ template struct closure { }; template struct closure { - typedef R (*F)(const void*,Args...); + using F = R (*)(const void *, Args...); F f; char data[1]; @@ -340,7 +342,7 @@ template // -- then as with the hobbes::variant layout template struct label { - typedef T type; + using type = T; T value; label() : value() { } label(const T& x) : value(x) { } @@ -348,12 +350,12 @@ template }; template struct liftVarCtor { - typedef T type; + using type = T; static std::string labelText(int idx) { return ".f" + str::from(idx); } }; template struct liftVarCtor< label > { - typedef typename label::type type; + using type = typename label::type; static std::string labelText(int) { return label::name(); } }; template @@ -410,7 +412,8 @@ template if (sizeof(R) == sizeof(uint32_t)) { return Variant::make(vms); } else { - return tapp(primty("penum", tabs(str::strings("r", "v"), tvar("r"))), list(lift::type(tenv), Variant::make(vms))); + return tapp(primty("penum", tabs(str::strings("r", "v"), tvar("r"))), + list(lift::type(tenv), makePVarType(vms))); } } }; diff --git a/include/hobbes/lang/type.H b/include/hobbes/lang/type.H index 8e1dccf36..0db745644 100644 --- a/include/hobbes/lang/type.H +++ b/include/hobbes/lang/type.H @@ -2,17 +2,17 @@ #ifndef HOBBES_LANG_TYPE_HPP_INCLUDED #define HOBBES_LANG_TYPE_HPP_INCLUDED +#include #include +#include #include -#include #include -#include -#include -#include -#include #include #include +#include #include +#include +#include namespace hobbes { @@ -21,24 +21,24 @@ class MonoTypeUnifier; // forall a0..aN : T class PolyType; -typedef std::shared_ptr PolyTypePtr; -typedef std::vector PolyTypes; +using PolyTypePtr = std::shared_ptr; +using PolyTypes = std::vector; // (C0, ..., Cn) => T class QualType; -typedef std::shared_ptr QualTypePtr; -typedef std::vector QualTypes; +using QualTypePtr = std::shared_ptr; +using QualTypes = std::vector; // P(T) class Constraint; -typedef std::shared_ptr ConstraintPtr; -typedef std::vector Constraints; +using ConstraintPtr = std::shared_ptr; +using Constraints = std::vector; // T class MonoType { public: virtual ~MonoType(); - typedef std::shared_ptr ptr; + using ptr = std::shared_ptr; virtual void show(std::ostream&) const = 0; bool operator==(const MonoType& rhs) const; @@ -57,7 +57,7 @@ private: public: // improves performance of identifying type variables and tgens - typedef std::set TypeVarNames; + using TypeVarNames = std::set; TypeVarNames freeTVars; int tgenCount; @@ -68,8 +68,8 @@ public: mutable ptr unaliasedType; }; -typedef MonoType::ptr MonoTypePtr; -typedef std::vector MonoTypes; +using MonoTypePtr = MonoType::ptr; +using MonoTypes = std::vector; inline std::ostream& operator<<(std::ostream& out, const MonoTypePtr& t) { t->show(out); @@ -78,13 +78,13 @@ inline std::ostream& operator<<(std::ostream& out, const MonoTypePtr& t) { // nested environments for types and type predicate resolvers class TEnv; -typedef std::shared_ptr TEnvPtr; +using TEnvPtr = std::shared_ptr; class Unqualifier; -typedef std::shared_ptr UnqualifierPtr; +using UnqualifierPtr = std::shared_ptr; class UnqualifierSet; -typedef std::shared_ptr UnqualifierSetPtr; +using UnqualifierSetPtr = std::shared_ptr; class TEnv { public: @@ -111,12 +111,12 @@ public: TEnv* root(); public: // get access to the internal type environment map (should only be used for debugging) - typedef std::map PolyTypeEnv; + using PolyTypeEnv = std::map; PolyTypeEnv typeEnvTable(std::function const& = [](std::string const& binding) -> std::string const& { return binding; }) const; str::set boundVariables() const; - typedef std::map Unqualifiers; + using Unqualifiers = std::map; const Unqualifiers& unqualifiers() const; private: TEnvPtr parent; @@ -129,7 +129,7 @@ public: MonoTypePtr unalias(const std::string&) const; bool isOpaqueTypeAlias(const std::string&) const; private: - typedef std::map TypeAliases; + using TypeAliases = std::map; TypeAliases typeAliases; public: @@ -145,10 +145,10 @@ TEnvPtr fnFrame(const TEnvPtr&, const str::seq&, const MonoTypes&); TEnvPtr bindFrame(const TEnvPtr&, const std::string&, const MonoTypePtr&); TEnvPtr bindFrame(const TEnvPtr&, const std::string&, const QualTypePtr&); -typedef std::string TVName; -typedef std::vector Names; -typedef std::set NameSet; -typedef std::map MonoTypeSubst; +using TVName = std::string; +using Names = std::vector; +using NameSet = std::set; +using MonoTypeSubst = std::map; inline MonoTypeSubst substitution(const str::seq& ns, const MonoTypes& ts) { MonoTypeSubst s; @@ -267,7 +267,7 @@ template // or may be an alias for a composite type class Prim : public MonoTypeCase { public: - void show(std::ostream& out) const; + void show(std::ostream& out) const override; const std::string& name() const; const MonoTypePtr& representation() const; @@ -286,7 +286,7 @@ private: // an opaque pointer to some C++ type class OpaquePtr : public MonoTypeCase { public: - void show(std::ostream& out) const; + void show(std::ostream& out) const override; const std::string& name() const; unsigned int size() const; @@ -311,7 +311,7 @@ MonoTypePtr normIfOpaquePtr(const MonoTypePtr& ty); class TVar : public MonoTypeCase { public: const std::string& name() const; - void show(std::ostream& out) const; + void show(std::ostream& out) const override; static const int type_case_id = 2; @@ -327,7 +327,7 @@ private: class TGen : public MonoTypeCase { public: int id() const; - void show(std::ostream& out) const; // should never be shown + void show(std::ostream& out) const override; // should never be shown static const int type_case_id = 3; @@ -342,7 +342,7 @@ private: // an array whose length is determined class FixedArray : public MonoTypeCase { public: - void show(std::ostream& out) const; + void show(std::ostream& out) const override; const MonoTypePtr& type() const; const MonoTypePtr& length() const; @@ -363,7 +363,7 @@ private: // an array whose length is not known at compile-time class Array : public MonoTypeCase { public: - void show(std::ostream& out) const; + void show(std::ostream& out) const override; const MonoTypePtr& type() const; @@ -390,9 +390,9 @@ public: MonoTypePtr type; unsigned int id; }; - typedef std::vector Members; + using Members = std::vector; - void show(std::ostream& out) const; + void show(std::ostream& out) const override; // get the first visible member and the type of the 'remainder' of the variant after ignoring the first field // (these are used for structural decomposition in generic functions) @@ -440,9 +440,9 @@ public: MonoTypePtr type; int offset; }; - typedef std::vector Members; + using Members = std::vector; - void show(std::ostream& out) const; + void show(std::ostream& out) const override; const Members& members() const; const MonoTypePtr& member(const std::string& mn) const; @@ -498,7 +498,7 @@ unsigned int alignment(const MonoTypePtr&); // a flat (contextless) function type class Func : public MonoTypeCase { public: - void show(std::ostream& out) const; + void show(std::ostream& out) const override; const MonoTypePtr& argument() const; const MonoTypePtr& result() const; @@ -520,7 +520,7 @@ private: // an abstraction of type structure suitable for unifying otherwise distinct types class Exists : public MonoTypeCase { public: - void show(std::ostream& out) const; + void show(std::ostream& out) const override; const std::string& absTypeName() const; const MonoTypePtr& absType() const; @@ -544,7 +544,7 @@ QualTypePtr unpackedType(const QualTypePtr& qty); // type-level values (the writing is on the wall here -- this is a hack and we are going to need full dependent types) class TString : public MonoTypeCase { public: - void show(std::ostream& out) const; + void show(std::ostream& out) const override; const std::string& value() const; @@ -560,7 +560,7 @@ private: class TLong : public MonoTypeCase { public: - void show(std::ostream& out) const; + void show(std::ostream& out) const override; long value() const; @@ -577,7 +577,7 @@ private: // a type-level abstraction class TAbs : public MonoTypeCase { public: - void show(std::ostream&) const; + void show(std::ostream&) const override; const str::seq& args() const; const MonoTypePtr& body() const; @@ -596,7 +596,7 @@ private: // a type-level application class TApp : public MonoTypeCase { public: - void show(std::ostream&) const; + void show(std::ostream&) const override; const MonoTypePtr& fn() const; const MonoTypes& args() const; @@ -615,7 +615,7 @@ private: // a recursive type class Recursive : public MonoTypeCase { public: - void show(std::ostream&) const; + void show(std::ostream&) const override; const std::string& recTypeName() const; const MonoTypePtr& recType() const; @@ -634,11 +634,11 @@ private: // expressions in types // (eventually we will need to eliminate the distinction between types and expressions) class Expr; -typedef std::shared_ptr ExprPtr; +using ExprPtr = std::shared_ptr; class TExpr : public MonoTypeCase { public: - void show(std::ostream&) const; + void show(std::ostream&) const override; const ExprPtr& expr() const; @@ -712,35 +712,35 @@ template struct CPtr { template struct as { - typedef const T* ty; + using ty = const T *; }; }; struct MPtr { template struct as { - typedef T* ty; + using ty = T *; }; }; template T switchOfF(Ptr ty, F f) { - typedef typename PtrC::template as::ty PrimT; - typedef typename PtrC::template as::ty OpaquePtrT; - typedef typename PtrC::template as::ty TVarT; - typedef typename PtrC::template as::ty TGenT; - typedef typename PtrC::template as::ty TAbsT; - typedef typename PtrC::template as::ty TAppT; - typedef typename PtrC::template as::ty FixedArrayT; - typedef typename PtrC::template as::ty ArrayT; - typedef typename PtrC::template as::ty VariantT; - typedef typename PtrC::template as::ty RecordT; - typedef typename PtrC::template as::ty FuncT; - typedef typename PtrC::template as::ty ExistsT; - typedef typename PtrC::template as::ty RecursiveT; - typedef typename PtrC::template as::ty TStringT; - typedef typename PtrC::template as::ty TLongT; - typedef typename PtrC::template as::ty TExprT; + using PrimT = typename PtrC::template as::ty; + using OpaquePtrT = typename PtrC::template as::ty; + using TVarT = typename PtrC::template as::ty; + using TGenT = typename PtrC::template as::ty; + using TAbsT = typename PtrC::template as::ty; + using TAppT = typename PtrC::template as::ty; + using FixedArrayT = typename PtrC::template as::ty; + using ArrayT = typename PtrC::template as::ty; + using VariantT = typename PtrC::template as::ty; + using RecordT = typename PtrC::template as::ty; + using FuncT = typename PtrC::template as::ty; + using ExistsT = typename PtrC::template as::ty; + using RecursiveT = typename PtrC::template as::ty; + using TStringT = typename PtrC::template as::ty; + using TLongT = typename PtrC::template as::ty; + using TExprT = typename PtrC::template as::ty; switch (ty->case_id()) { case Prim::type_case_id: @@ -793,24 +793,24 @@ template template std::vector switchOf(const MonoTypes& ts, const switchType& f) { std::vector result; - for (MonoTypes::const_iterator t = ts.begin(); t != ts.end(); ++t) { - result.push_back(switchOf(*t, f)); + for (const auto &t : ts) { + result.push_back(switchOf(t, f)); } return result; } template T switchOf(const MonoTypes& ts, T s, T (*appendF)(T,T), const switchType& f) { - for (MonoTypes::const_iterator t = ts.begin(); t != ts.end(); ++t) { - s = appendF(s, switchOf(*t, f)); + for (const auto &t : ts) { + s = appendF(s, switchOf(t, f)); } return s; } template std::vector< std::pair > switchOf(const std::vector< std::pair >& kts, const switchType& f) { - typedef std::pair KT; - typedef std::vector KTS; + using KT = std::pair; + using KTS = std::vector; KTS r; for (typename std::vector< std::pair >::const_iterator kt = kts.begin(); kt != kts.end(); ++kt) { r.push_back(KT(kt->first, switchOf(kt->second, f))); @@ -821,8 +821,8 @@ template template Variant::Members switchOf(const Variant::Members& ms, const switchType& f) { Variant::Members r; - for (Variant::Members::const_iterator m = ms.begin(); m != ms.end(); ++m) { - r.push_back(Variant::Member(m->selector, switchOf(m->type, f), m->id)); + for (const auto &m : ms) { + r.push_back(Variant::Member(m.selector, switchOf(m.type, f), m.id)); } return r; } @@ -830,16 +830,16 @@ template template Record::Members switchOf(const Record::Members& ms, const switchType& f) { Record::Members r; - for (Record::Members::const_iterator m = ms.begin(); m != ms.end(); ++m) { - r.push_back(Record::Member(m->field, switchOf(m->type, f), m->offset)); + for (const auto &m : ms) { + r.push_back(Record::Member(m.field, switchOf(m.type, f), m.offset)); } return r; } inline MonoTypes selectTypes(const Variant::Members& ms) { MonoTypes r; - for (Variant::Members::const_iterator m = ms.begin(); m != ms.end(); ++m) { - r.push_back(m->type); + for (const auto &m : ms) { + r.push_back(m.type); } return r; } @@ -854,8 +854,8 @@ inline str::seq selectNames(const Variant::Members& ms) { inline MonoTypes selectTypes(const Record::Members& ms) { MonoTypes r; - for (Record::Members::const_iterator m = ms.begin(); m != ms.end(); ++m) { - r.push_back(m->type); + for (const auto &m : ms) { + r.push_back(m.type); } return r; } @@ -870,46 +870,46 @@ inline str::seq selectNames(const Record::Members& ms) { // walk a type structure for a side-effect (override any part to do per-constructor walks) struct walkTy : public switchType { - UnitV with(const Prim* v) const; - UnitV with(const OpaquePtr* v) const; - UnitV with(const TVar* v) const; - UnitV with(const TGen* v) const; - UnitV with(const TAbs* v) const; - UnitV with(const TApp* v) const; - UnitV with(const FixedArray* v) const; - UnitV with(const Array* v) const; - UnitV with(const Variant* v) const; - UnitV with(const Record* v) const; - UnitV with(const Func* v) const; - UnitV with(const Exists* v) const; - UnitV with(const Recursive* v) const; - UnitV with(const TString* v) const; - UnitV with(const TLong* v) const; - UnitV with(const TExpr* v) const; + UnitV with(const Prim* v) const override; + UnitV with(const OpaquePtr* v) const override; + UnitV with(const TVar* v) const override; + UnitV with(const TGen* v) const override; + UnitV with(const TAbs* v) const override; + UnitV with(const TApp* v) const override; + UnitV with(const FixedArray* v) const override; + UnitV with(const Array* v) const override; + UnitV with(const Variant* v) const override; + UnitV with(const Record* v) const override; + UnitV with(const Func* v) const override; + UnitV with(const Exists* v) const override; + UnitV with(const Recursive* v) const override; + UnitV with(const TString* v) const override; + UnitV with(const TLong* v) const override; + UnitV with(const TExpr* v) const override; }; // copy a type structure entirely (override any part to do a partial 'Type -> Type' transform) struct switchTyFn : public switchType { - MonoTypePtr with(const Prim* v) const; - MonoTypePtr with(const OpaquePtr* v) const; - MonoTypePtr with(const TVar* v) const; - MonoTypePtr with(const TGen* v) const; - MonoTypePtr with(const TAbs* v) const; - MonoTypePtr with(const TApp* v) const; - MonoTypePtr with(const FixedArray* v) const; - MonoTypePtr with(const Array* v) const; - MonoTypePtr with(const Variant* v) const; - MonoTypePtr with(const Record* v) const; - MonoTypePtr with(const Func* v) const; - MonoTypePtr with(const Exists* v) const; - MonoTypePtr with(const Recursive* v) const; + MonoTypePtr with(const Prim* v) const override; + MonoTypePtr with(const OpaquePtr* v) const override; + MonoTypePtr with(const TVar* v) const override; + MonoTypePtr with(const TGen* v) const override; + MonoTypePtr with(const TAbs* v) const override; + MonoTypePtr with(const TApp* v) const override; + MonoTypePtr with(const FixedArray* v) const override; + MonoTypePtr with(const Array* v) const override; + MonoTypePtr with(const Variant* v) const override; + MonoTypePtr with(const Record* v) const override; + MonoTypePtr with(const Func* v) const override; + MonoTypePtr with(const Exists* v) const override; + MonoTypePtr with(const Recursive* v) const override; // bleh - MonoTypePtr with(const TString* v) const; - MonoTypePtr with(const TLong* v) const; + MonoTypePtr with(const TString* v) const override; + MonoTypePtr with(const TLong* v) const override; // not quite as bleh - MonoTypePtr with(const TExpr*) const; + MonoTypePtr with(const TExpr*) const override; }; MonoTypePtr clone(const MonoTypePtr&); @@ -935,7 +935,7 @@ int tgenSize(const MonoTypes& mts); int tgenSize(const ConstraintPtr& c); [[noreturn]] int tgenSize(const QualTypePtr& qt); -typedef std::set TGenVarSet; +using TGenVarSet = std::set; TGenVarSet tgenVars(const MonoTypePtr&); TVName canonicalName(int v); @@ -1028,7 +1028,7 @@ inline MonoTypePtr primty(const char* x, const MonoTypePtr& aty) { } inline QualTypePtr qualtype(const Constraints& cs, const MonoTypePtr& p) { - return QualTypePtr(new QualType(cs, p)); + return std::make_shared(cs, p); } inline QualTypePtr qualtype(const Constraints& cs, MonoType* mt) { @@ -1036,11 +1036,11 @@ inline QualTypePtr qualtype(const Constraints& cs, MonoType* mt) { } inline QualTypePtr qualtype(const MonoTypePtr& p) { - return QualTypePtr(new QualType(p)); + return std::make_shared(p); } inline QualTypePtr qualtype(MonoType* mt) { - return QualTypePtr(new QualType(MonoTypePtr(mt))); + return std::make_shared(MonoTypePtr(mt)); } inline QualTypePtr qualtype(const char* x) { @@ -1048,11 +1048,11 @@ inline QualTypePtr qualtype(const char* x) { } inline PolyTypePtr polytype(int tvs, const QualTypePtr& qt) { - return PolyTypePtr(new PolyType(tvs, qt)); + return std::make_shared(tvs, qt); } inline PolyTypePtr polytype(const QualTypePtr& qt) { - return PolyTypePtr(new PolyType(qt)); + return std::make_shared(qt); } inline PolyTypePtr polytype(const MonoTypePtr& p) { @@ -1080,7 +1080,7 @@ inline MonoTypePtr tstring(const std::string& x) { } inline MonoTypePtr tuplety(const MonoTypes& mtys = MonoTypes()) { - if (mtys.size() == 0) { + if (mtys.empty()) { return primty("unit"); } else { Record::Members ms; @@ -1125,7 +1125,7 @@ inline MonoTypePtr functy(const MonoTypePtr& aty, const MonoTypePtr& rty) { } inline MonoTypePtr functy(const MonoTypes& atys, const MonoTypePtr& rty) { - if (atys.size() == 0) { + if (atys.empty()) { return Func::make(tuplety(list(tuplety())), rty); } else { return Func::make(tuplety(atys), rty); @@ -1268,7 +1268,7 @@ MonoTypePtr fileRefTy(const MonoTypePtr&); template <> struct genHash { inline size_t operator()(const Record::Member& x) const { - typedef std::tuple RMTup; + using RMTup = std::tuple; static genHash h; return h(RMTup(x.field, x.type, x.offset)); } @@ -1276,7 +1276,7 @@ template <> template <> struct genHash { inline size_t operator()(const Variant::Member& x) const { - typedef std::tuple VMTup; + using VMTup = std::tuple; static genHash h; return h(VMTup(x.selector, x.type, x.id)); } diff --git a/include/hobbes/lang/typeinf.H b/include/hobbes/lang/typeinf.H index e141bb45f..5755e7cb0 100644 --- a/include/hobbes/lang/typeinf.H +++ b/include/hobbes/lang/typeinf.H @@ -65,14 +65,14 @@ private: size_t bcount; // avoid binding to certain type variables - typedef std::map SuppressVarCounts; + using SuppressVarCounts = std::map; SuppressVarCounts suppressVarCounts; bool suppressed(const std::string&) const; bool suppressed(const MonoTypePtr&) const; // equivalences between types - typedef equivalence_mapping M; + using M = equivalence_mapping; M m; }; @@ -121,10 +121,10 @@ void mgu(const MonoTypes& ts0, const MonoTypes& ts1, MonoTypeUnifier* u); void mgu(const ConstraintPtr&, const ConstraintPtr&, MonoTypeUnifier*); // some utilities for dealing with qualified types -typedef std::pair QualLiftedMonoTypes; +using QualLiftedMonoTypes = std::pair; QualLiftedMonoTypes liftQualifiers(const QualTypes& qts); -typedef std::pair QualLiftedMonoType; +using QualLiftedMonoType = std::pair; } diff --git a/include/hobbes/lang/typemap.H b/include/hobbes/lang/typemap.H index 4e0d0a434..493bea321 100644 --- a/include/hobbes/lang/typemap.H +++ b/include/hobbes/lang/typemap.H @@ -16,13 +16,13 @@ struct MonoTypeLT { struct MTyMap { template struct map { - typedef std::map type; + using type = std::map; }; }; // used to do exact matches on types with a wildcard -typedef variant MaybePathPoint; -typedef std::vector MaybePathPoints; +using MaybePathPoint = variant; +using MaybePathPoints = std::vector; // a map from type sequences to some value template @@ -63,11 +63,11 @@ template findMatches(this->d.rootPoint(), path, 0, out); } private: - typedef prefix_tree tmdata; + using tmdata = prefix_tree; tmdata d; bool hasMatch(MonoTypeUnifier& u, typename tmdata::point_t p, const MonoTypes& mts, size_t i) const { - if (p == 0) { + if (p == nullptr) { return false; } @@ -96,7 +96,7 @@ template } void findMatches(MonoTypeUnifier& u, typename tmdata::point_t p, const MonoTypes& mts, size_t i, std::vector* out) const { - if (p == 0) return; + if (p == nullptr) return; if (i == mts.size()) { if (const V* v = this->d.valueAt(p)) { @@ -124,7 +124,7 @@ template } void findBidiMatches(MonoTypeUnifier& u, typename tmdata::point_t p, const MonoTypes& mts, size_t i, std::vector* out) const { - if (p == 0) return; + if (p == nullptr) return; if (i == mts.size()) { if (const V* v = this->d.valueAt(p)) { @@ -148,7 +148,7 @@ template } void findMatches(typename tmdata::point_t p, const MaybePathPoints& path, size_t i, std::vector* out) const { - if (p == 0) return; + if (p == nullptr) return; if (i == path.size()) { if (const V* v = this->d.valueAt(p)) { @@ -156,13 +156,13 @@ template } } else { // do we need an exact match or any point here? - if (const MonoTypePtr* mt = get(path[i])) { + if (const auto* mt = get(path[i])) { findMatches(this->d.moveTo(*mt, p), path, i + 1, out); } else { typename tmdata::KeyPointSeq kps; this->d.keyPointsAt(&kps, p); - for (auto kp : kps) { + for (const auto& kp : kps) { findMatches(kp.second, path, i + 1, out); } } diff --git a/include/hobbes/lang/tyunqualify.H b/include/hobbes/lang/tyunqualify.H index 8dec8294b..ec18d9d9f 100644 --- a/include/hobbes/lang/tyunqualify.H +++ b/include/hobbes/lang/tyunqualify.H @@ -9,17 +9,17 @@ namespace hobbes { -typedef std::set SymSet; +using SymSet = std::set; // how do some parameters of a constraint determine others? -typedef std::vector VarIDs; -typedef std::pair FunDep; -typedef std::vector FunDeps; +using VarIDs = std::vector; +using FunDep = std::pair; +using FunDeps = std::vector; // if E :: T and R.satisfied(T), then R.unqualify(E) class Unqualifier { public: - virtual ~Unqualifier(void) {}; + virtual ~Unqualifier() = default;; // bind any implied type variables in a constraint virtual bool refine(const TEnvPtr& tenv, const ConstraintPtr& cst, MonoTypeUnifier* u, Definitions* ds) = 0; @@ -44,29 +44,29 @@ class Unqualifier { // list functional dependencies between constraint parameters (if any) virtual FunDeps dependencies(const ConstraintPtr&) const = 0; }; -typedef std::shared_ptr UnqualifierPtr; +using UnqualifierPtr = std::shared_ptr; // type predicates are resolved by an assumed disjoint set of unqualifiers class UnqualifierSet : public Unqualifier { public: - typedef std::map Unqualifiers; + using Unqualifiers = std::map; void add(const std::string& name, const UnqualifierPtr& uq); UnqualifierPtr findUnqualifier(const std::string& name); const Unqualifiers& unqualifiers() const; - bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*); - bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const; - void explain(const TEnvPtr&, const ConstraintPtr&, const ExprPtr&, Definitions*, annmsgs*); - ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&, const ExprPtr&, Definitions*) const; - PolyTypePtr lookup(const std::string& vn) const; - SymSet bindings() const; - FunDeps dependencies(const ConstraintPtr&) const; + bool refine(const TEnvPtr&,const ConstraintPtr&,MonoTypeUnifier*,Definitions*) override; + bool satisfied(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + bool satisfiable(const TEnvPtr&,const ConstraintPtr&,Definitions*) const override; + void explain(const TEnvPtr&, const ConstraintPtr&, const ExprPtr&, Definitions*, annmsgs*) override; + ExprPtr unqualify(const TEnvPtr&,const ConstraintPtr&, const ExprPtr&, Definitions*) const override; + PolyTypePtr lookup(const std::string& vn) const override; + SymSet bindings() const override; + FunDeps dependencies(const ConstraintPtr&) const override; private: Unqualifiers uqs; }; -typedef std::shared_ptr UnqualifierSetPtr; +using UnqualifierSetPtr = std::shared_ptr; // utilities to remove discharged type predicates bool hasConstraint(const ConstraintPtr& c, const Constraints& cs); diff --git a/include/hobbes/mc/encode.H b/include/hobbes/mc/encode.H index afd72930f..1d00fe5e0 100644 --- a/include/hobbes/mc/encode.H +++ b/include/hobbes/mc/encode.H @@ -53,10 +53,10 @@ #include #include +#include +#include #include #include -#include -#include namespace hobbes { namespace mc { @@ -124,7 +124,7 @@ public: } uint8_t* base() { return this->mem; } - size_t size() { return this->sz; } + size_t size() const { return this->sz; } // allocate some number of additional bytes at the tail of the buffer // return the address where those bytes can be written (this is how machine code is accumulated) @@ -135,7 +135,7 @@ public: growBuffer(std::max(newsz, this->allocsz * 2)); } - auto r = this->mem + this->sz; + auto *r = this->mem + this->sz; this->sz += segsz; return r; } @@ -143,7 +143,7 @@ public: // add a label reference at the current write position (assuming a 32-bit displacement) void addLabelRef(const std::string& lbl) { this->labelRefs[lbl].push_back(this->sz); - *reinterpret_cast(allocate(sizeof(uint32_t))) = 0; + std::memset(allocate(sizeof(uint32_t)), 0, sizeof(uint32_t)); } // define a label at the current write position @@ -159,8 +159,8 @@ public: // this is useful for deciding an efficient form of call instruction just if we are within 32-bits of the target // but need to degrade to a less efficient (larger code size) call if not # define HMC_MAX_PATCH_LEN 16 - typedef std::array PatchBuffer; - typedef std::function PatchFn; + using PatchBuffer = std::array; + using PatchFn = std::function; void patchWithRIP(const PatchFn& pfn) { // make the initial patch and remember how many bytes it used initially @@ -169,7 +169,7 @@ public: // this is additionally complicated by the fact that this initial allocation // can cause a buffer move itself while (true) { - auto rip = this->mem + this->sz; + auto * rip = this->mem + this->sz; PatchBuffer b; uint32_t n = 0; @@ -190,7 +190,7 @@ public: } // finalize the buffer so that we can execute its code - typedef void (*ThunkF)(); + using ThunkF = void (*)(); ThunkF finalize() { resolveLabelReferences(); @@ -210,8 +210,8 @@ private: uint8_t* mem; // label defs/refs - typedef std::map LabelDefs; - typedef std::map> LabelRefs; + using LabelDefs = std::map; + using LabelRefs = std::map>; LabelDefs labelDefs; LabelRefs labelRefs; @@ -230,14 +230,15 @@ private: if (!canLowerTo(dist)) { throw std::runtime_error("Can't resolve label reference to '" + d->first + "' in program with jump distance greater than 32-bits"); } - *reinterpret_cast(this->mem + pc) = static_cast(dist); + const auto dist32 = static_cast(dist); + std::memcpy(this->mem + pc, &dist32, sizeof(dist32)); } } } // keep track of RIP-dependent patches and re-derive them when we grow our buffer (which should be an infrequent event) - typedef std::pair Patch; - typedef std::map Patches; + using Patch = std::pair; + using Patches = std::map; Patches ripPatches; @@ -304,7 +305,7 @@ private: // apply cumulative adjustments at fixed offsets to source offsets // this allows us to make insertions in exec buffers and "fix up" references to offsets in the original buffer // (e.g. if we had an offset to 5 before, but inserted 2 bytes at 3, then our offset should be adjusted to 7) - typedef std::map CumAdjustments; + using CumAdjustments = std::map; static size_t applyCumAdjustments(const CumAdjustments& cadj, size_t offset) { auto leb = cadj.lower_bound(offset); @@ -336,7 +337,7 @@ private: return align(x, this->pagesz); } static uint8_t* allocateBuffer(size_t sz) { - uint8_t* r = reinterpret_cast(mmap(0, sz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0)); + auto* r = reinterpret_cast(mmap(nullptr, sz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0)); if (r == MAP_FAILED) { throw std::runtime_error("Failed to allocate exec buffer memory with error: " + std::string(strerror(errno))); } @@ -357,7 +358,7 @@ private: * * Where 'sz' means value size in bytes and 'ty' means register class (int or float). */ -typedef uint8_t RegSize; // 1,2,4,8 +using RegSize = uint8_t; // 1,2,4,8 enum RegClass { Int, Float }; template @@ -434,7 +435,7 @@ template class Arg { public: // invalid argument - Arg() : vtag(TReg) { this->variant.vreg = 0; } + Arg() : vtag(TReg) { this->variant.vreg = nullptr; } Arg(const Arg& rhs) { copyFrom(rhs); @@ -464,7 +465,7 @@ public: static Arg ireg(RegisterID name, RegSize rsize) { return reg(name, rsize, Int); } static Arg freg(RegisterID name, RegSize rsize) { return reg(name, rsize, Float); } - const Reg* reg() const { return this->vtag == TReg ? this->variant.vreg : 0; } + const Reg* reg() const { return this->vtag == TReg ? this->variant.vreg : nullptr; } // or it can be an indirect memory reference through a register calculation // these register calculations can look like [B+I*S+D] where B and I are registers, S is a scale factor in {0,1,2,4,8}, and D is up to a 32-bit const displacement @@ -496,7 +497,7 @@ public: static Arg regDeref(RegisterID index, uint8_t scale, int32_t offset, RegSize rsize, RegClass rclass) { return regDeref(RegisterID(), false, index, scale, offset, rsize, rclass); } static Arg regDeref(const Reg& index, uint8_t scale, int32_t offset, RegSize rsize, RegClass rclass) { return regDeref(RegisterID(), false, index.name, scale, offset, rsize, rclass); } - const RegDeref* regDeref() const { return this->vtag == TRegDeref ? this->variant.vregderef : 0; } + const RegDeref* regDeref() const { return this->vtag == TRegDeref ? this->variant.vregderef : nullptr; } // refer to the label 'label' static Arg labelRef(const LabelRef& lbl) { @@ -508,7 +509,7 @@ public: lref.rsize = rsize; return labelRef(lref); } - const LabelRef* labelRef() const { return this->vtag == TLabelRef ? this->variant.vlabelref : 0; } + const LabelRef* labelRef() const { return this->vtag == TLabelRef ? this->variant.vlabelref : nullptr; } // an immediate value static Arg immediate(const Immediate& i) { @@ -530,7 +531,7 @@ public: static Arg i64 (int64_t x) { return immediate(static_cast(x), true, sizeof(x)); } static Arg ui64(uint64_t x) { return immediate(static_cast(x), false, sizeof(x)); } - const Immediate* immediate() const { return this->vtag == TImmediate ? this->variant.vimmediate : 0; } + const Immediate* immediate() const { return this->vtag == TImmediate ? this->variant.vimmediate : nullptr; } // the variant view of this data enum Tag : uint8_t { @@ -606,7 +607,7 @@ private: this->vtag = rhs.vtag; if (!rhs.variant.vreg) { // 0-initialize just for a 0-initialized copy - this->variant.vreg = 0; + this->variant.vreg = nullptr; return; } @@ -634,7 +635,7 @@ enum X86Reg : uint8_t { }; // an instruction argument using x86 machine register IDs is a 'machine arg' -typedef Arg MArg; +using MArg = Arg; // by tradition, there are some special names for some of the registers // we should be consistent with those naming standards when interfacing with humans @@ -693,7 +694,7 @@ inline const Reg* maybeMReg(const std::string& name) { } } auto r = mregs.find(name); - return (r != mregs.end()) ? &r->second : 0; + return (r != mregs.end()) ? &r->second : nullptr; } inline const Reg& mreg(const std::string& name) { if (const auto* p = maybeMReg(name)) { @@ -815,14 +816,14 @@ struct Instruction { return r; } const LabelRef* labelDef() const { - return this->op=="deflbl" && this->argc==1 ? this->args[0].labelRef() : 0; + return this->op=="deflbl" && this->argc==1 ? this->args[0].labelRef() : nullptr; } const LabelRef* jumpTarget() const { // jump instructions start with "j" by convention, should be good enough if (this->op.size() > 0 && this->op[0] == 'j' && this->argc == 1) { return this->args[0].labelRef(); } else { - return 0; + return nullptr; } } bool controlFollows() const { @@ -849,8 +850,8 @@ template using Instructions = std::vector>; // an instruction using x86 machine registers is a 'machine instruction' -typedef Instruction MInst; -typedef std::vector MInsts; +using MInst = Instruction; +using MInsts = std::vector; // print instructions and instruction sequences for human display template @@ -946,10 +947,10 @@ public: } } const Reg* reg() const { - return this->isRegister ? this->variant.vreg : 0; + return this->isRegister ? this->variant.vreg : nullptr; } const RegDeref* regDeref() const { - return !this->isRegister ? this->variant.vregderef : 0; + return !this->isRegister ? this->variant.vregderef : nullptr; } private: bool isRegister; @@ -963,7 +964,7 @@ private: class Output; class MatchFunction { public: - MatchFunction() : pf(0) { } + MatchFunction() : pf(nullptr) { } template MatchFunction(void(*pf)(Output&,const Args&...)) { this->pf = reinterpret_cast(pf); @@ -997,39 +998,39 @@ public: // we use these patterns for instructions that have specializations to work with a specific register (usually r0 aka "rax") static P reg(const std::string& name) { const auto& nreg = mreg(name); - return P(MLitReg, nreg.name, nreg.rsize, nreg.rclass); + return {MLitReg, nreg.name, nreg.rsize, nreg.rclass}; } // partial register mapping // (match size and class, but leave 'name' free) - static P r8 () { return P(MReg, 1, RegClass::Int); } - static P r16() { return P(MReg, 2, RegClass::Int); } - static P r32() { return P(MReg, 4, RegClass::Int); } - static P r64() { return P(MReg, 8, RegClass::Int); } + static P r8 () { return {MReg, 1, RegClass::Int}; } + static P r16() { return {MReg, 2, RegClass::Int}; } + static P r32() { return {MReg, 4, RegClass::Int}; } + static P r64() { return {MReg, 8, RegClass::Int}; } - static P rf32() { return P(MReg, 4, RegClass::Float); } - static P rf64() { return P(MReg, 8, RegClass::Float); } + static P rf32() { return {MReg, 4, RegClass::Float}; } + static P rf64() { return {MReg, 8, RegClass::Float}; } // RM matching (accepting either register or memory arguments) - static P rm8() { return P(MRM, 1, RegClass::Int); } - static P rm16() { return P(MRM, 2, RegClass::Int); } - static P rm32() { return P(MRM, 4, RegClass::Int); } - static P rm64() { return P(MRM, 8, RegClass::Int); } + static P rm8() { return {MRM, 1, RegClass::Int}; } + static P rm16() { return {MRM, 2, RegClass::Int}; } + static P rm32() { return {MRM, 4, RegClass::Int}; } + static P rm64() { return {MRM, 8, RegClass::Int}; } - static P rmf32() { return P(MRM, 4, RegClass::Float); } - static P rmf64() { return P(MRM, 8, RegClass::Float); } + static P rmf32() { return {MRM, 4, RegClass::Float}; } + static P rmf64() { return {MRM, 8, RegClass::Float}; } // label references - static P lbl(RegSize sz = 4) { return P(MLabelRef, sz, RegClass::Int); } + static P lbl(RegSize sz = 4) { return {MLabelRef, sz, RegClass::Int}; } // exact immediate values (some instructions like SHL are specialized for exact value arguments) - static P imm8(int8_t x) { return P(MLitImm, x, 1, RegClass::Int); } + static P imm8(int8_t x) { return {MLitImm, x, 1, RegClass::Int}; } // immediate values matching by size - static P imm8 () { return P(MImm, 1, RegClass::Int); } - static P imm16() { return P(MImm, 2, RegClass::Int); } - static P imm32() { return P(MImm, 4, RegClass::Int); } - static P imm64() { return P(MImm, 8, RegClass::Int); } + static P imm8 () { return {MImm, 1, RegClass::Int}; } + static P imm16() { return {MImm, 2, RegClass::Int}; } + static P imm32() { return {MImm, 4, RegClass::Int}; } + static P imm64() { return {MImm, 8, RegClass::Int}; } // does an argument match this pattern? bool matches(const MArg& arg) const { @@ -1270,8 +1271,8 @@ private: // we should also be able to infer which arguments are in/out/inout here class Match { public: - typedef std::vector RuleSeq; - typedef std::vector VarRefs; + using RuleSeq = std::vector; + using VarRefs = std::vector; Match() { /* invalid */ } Match(const RuleSeq& rules) { @@ -1550,7 +1551,7 @@ inline void emitValue(buffer* b, const MODRMCode& modrm) { if (O == 1) { *b->allocate(1) = static_cast(modrm.disp); } else if (O == 2 || (O == 0 && thd_233(modrm.modrm) == 5) || (O == 0 && hasSIB && thd_233(modrm.sib) == 5)) { - *reinterpret_cast(b->allocate(4)) = modrm.disp; + std::memcpy(b->allocate(4), &modrm.disp, sizeof(modrm.disp)); } } @@ -1612,7 +1613,7 @@ public: int64_t diff = reinterpret_cast(faddr) - reinterpret_cast(rip + 5); if (canLowerTo(diff)) { - int32_t diff32 = static_cast(diff); + auto diff32 = static_cast(diff); // call rel32 = e8 id (5 bytes) (*b)[0] = 0xe8; @@ -1622,7 +1623,7 @@ public: // mov rax, faddr (*b)[0] = REXW().byte; (*b)[1] = 0xb8; - *reinterpret_cast(&(*b)[2]) = faddr; + std::memcpy(&(*b)[2], &faddr, sizeof(faddr)); // call rax Reg rax; @@ -1650,14 +1651,14 @@ private: #ifndef HMC_ENCODE_NO_INLINE_CODETABLES -typedef std::map EncodingTable; +using EncodingTable = std::map; inline void bootEncodingTable(EncodingTable& t) { - typedef Output& O; - typedef const Reg& R; - typedef const RM& RM; - typedef const Immediate& I; - typedef const LabelRef& LR; + using O = Output &; + using R = const Reg &; + using RM = const RM &; + using I = const Immediate &; + using LR = const LabelRef &; t["add"] = Match({ Rule(io(P::reg("al")), P::imm8(), [](O o, I ib){o( ui8(0x04), ui8(ib));}), diff --git a/include/hobbes/mc/liveness.H b/include/hobbes/mc/liveness.H index e348466f2..c7ea5000c 100644 --- a/include/hobbes/mc/liveness.H +++ b/include/hobbes/mc/liveness.H @@ -32,21 +32,21 @@ #ifndef HMC_LIVENESS_H_INCLUDED #define HMC_LIVENESS_H_INCLUDED -#include -#include +#include #include -#include +#include #include -#include +#include +#include namespace hobbes { namespace mc { // a dynamic bitset, used to represent a set of variables (assuming a mapping of variable name to 0-N index) class VarSet { public: - VarSet() : varc(0), bcount(0), bits(0) { + VarSet() : varc(0), bcount(0), bits(nullptr) { } - VarSet(uint64_t vc) : varc(0), bcount(0), bits(0) { + VarSet(uint64_t vc) : varc(0), bcount(0), bits(nullptr) { resize(vc); } VarSet(const VarSet& s) { copyBuffer(s); } @@ -60,15 +60,15 @@ public: } void clear() { - if (this->bits) { + if (this->bits != nullptr) { memset(this->bits, 0, this->bcount * sizeof(uint64_t)); } } void resize(uint64_t sz) { - uint64_t asz = align(sz, 64); + auto asz = align(sz, 64); uint64_t bc = asz / 64; - uint64_t* nbits = new uint64_t[bc]; + auto* nbits = new uint64_t[bc]; if (bc <= this->bcount) { memcpy(nbits, this->bits, bc * sizeof(uint64_t)); @@ -150,7 +150,7 @@ public: uint64_t k = b; // gather members in 4-bit steps - while (v) { + while (v != 0u) { switch (v & 0x0f) { default: case 0: break; // 0000 @@ -242,16 +242,15 @@ inline std::set truncTo(const std::set& us) { // key :: Var -> K (such that K is unique for Var and has < defined) // desc :: K -> string (describe a variable key for an error message) // -typedef uint32_t VarID; +using VarID = uint32_t; template class VarUniverse { public: - typedef typename VarM::Var Var; - typedef decltype(VarM::key(*reinterpret_cast(42))) K; + using Var = typename VarM::Var; + using K = decltype(VarM::key(*reinterpret_cast(42))); - VarUniverse() { - } + VarUniverse() = default; void define(const Var& v) { auto k = VarM::key(v); @@ -310,8 +309,8 @@ private: template class BlockLiveness { public: - typedef typename InstM::Instruction Inst; - typedef typename InstM::Var Var; + using Inst = typename InstM::Instruction; + using Var = typename InstM::Var; BlockLiveness(const std::set& initVars, const std::vector& insts, const InstM& instM) : insts(insts), instM(instM) { // initialize the variable universe out of the instruction sequence @@ -356,7 +355,7 @@ public: pc < insts.size() && // pc is valid instM.follows(insts, pc) && // control follows straight from pc to pc+1 !instM.jumpsTo(insts, pc, &n) && // pc doesn't jump anywhere else - !jumpTargets.count(pc+1) // and the next instruction is only reachable from this one + (jumpTargets.count(pc+1) == 0u) // and the next instruction is only reachable from this one ) { // the next instruction is in the block @@ -550,8 +549,8 @@ public: template class BasicLiveness { public: - typedef typename InstM::Instruction Inst; - typedef typename InstM::Var Var; + using Inst = typename InstM::Instruction; + using Var = typename InstM::Var; BasicLiveness(const std::set& initVars, const std::vector& insts, const InstM& instM) : insts(insts), instM(instM) { // initialize the variable universe out of the instruction sequence diff --git a/include/hobbes/mc/regalloc.H b/include/hobbes/mc/regalloc.H index e168e91e5..f7b5fe7bf 100644 --- a/include/hobbes/mc/regalloc.H +++ b/include/hobbes/mc/regalloc.H @@ -42,11 +42,11 @@ #include "encode.H" #include "liveness.H" +#include +#include #include #include -#include #include -#include namespace hobbes { namespace mc { @@ -56,11 +56,11 @@ namespace hobbes { namespace mc { static const uint32_t MaxRegisters = 16; // instructions subject to register allocation have free register names (as strings) -typedef Instructions RInsts; -typedef Instruction RInst; -typedef Arg RArg; -typedef Reg RReg; -typedef RegDeref RRegDeref; +using RInsts = Instructions; +using RInst = Instruction; +using RArg = Arg; +using RReg = Reg; +using RRegDeref = RegDeref; inline std::string stdRegName(X86Reg r, RegClass rc) { return regName(r, 8, rc); @@ -102,7 +102,7 @@ inline const std::set>& callerSaveRegs() { i.name = static_cast(r); i.rsize = 8; i.rclass = RegClass::Int; - if (r != 4 && !saved.count(i)) { + if (r != 4 && (saved.count(i) == 0u)) { regs.insert(i); } @@ -110,7 +110,7 @@ inline const std::set>& callerSaveRegs() { f.name = static_cast(r); f.rsize = 8; f.rclass = RegClass::Float; - if (!saved.count(f)) { + if (saved.count(f) == 0u) { regs.insert(f); } } @@ -160,7 +160,7 @@ inline std::string rmap(const std::map& m, X86Reg r, RegCla return k->second; } } -inline void rmapInto(const std::map& m, std::set* s, MArg ma) { +inline void rmapInto(const std::map& m, std::set* s, const MArg& ma) { if (const auto* reg = ma.reg()) { s->insert(rmap(m, reg->name, reg->rclass)); } else if (const auto* rd = ma.regDeref()) { @@ -205,7 +205,7 @@ inline std::set regUses(const RInst& ri) { rmapInto(lm, &r, ma); } for (const auto& ma : defs(mi)) { - if (!ma.reg()) { + if (ma.reg() == nullptr) { rmapInto(lm, &r, ma); } } @@ -215,8 +215,8 @@ inline std::set regUses(const RInst& ri) { // a liveness module for instruction sequences with infinite named registers class RInstM { public: - typedef RInst Instruction; - typedef std::string Var; + using Instruction = RInst; + using Var = std::string; RInstM(const RInsts& insts) { for (size_t pc = 0; pc < insts.size(); ++pc) { @@ -427,7 +427,7 @@ public: } } private: - typedef std::map> VarIDSets; + using VarIDSets = std::map>; size_t varc; VarSet vtest; @@ -466,7 +466,7 @@ public: // in the case of a reg move, remember that we can coalesce the two vars involved // add interference edges for all _other_ vars live out here VarID sv = live.id(src->name); - for (auto rd : regDefs(inst)) { + for (const auto& rd : regDefs(inst)) { VarID d = live.id(rd); addMoveEdge(d, sv); @@ -479,7 +479,7 @@ public: } else { // generic instruction, // add interference edges for all vars live out here - for (auto rd : regDefs(inst)) { + for (const auto& rd : regDefs(inst)) { VarID d = live.id(rd); for (auto o : i.liveOut()) { @@ -556,7 +556,7 @@ private: } } } - return 0; + return nullptr; } void addInterfereEdge(VarID v0, VarID v1) { @@ -588,7 +588,7 @@ public: return this->assignSeq; } - typedef std::map VarAliasing; + using VarAliasing = std::map; const VarAliasing& aliasedVars() const { return this->coalescedVars; @@ -607,12 +607,12 @@ private: uint32_t degree (VarID v) const { return this->ig->interferences(v).size(); } // divisions of the interference graph to evaluate - typedef std::set VarList; + using VarList = std::set; VarList removeVar, freezeVar, spillVar; VarSet assignedVars; - typedef std::pair Move; - typedef std::set MoveList; + using Move = std::pair; + using MoveList = std::set; MoveList moves; MoveList delayedMoves; @@ -670,7 +670,7 @@ private: for (VarID mv : this->ig->moves(v)) { Move mvid = moveID(v, mv); - if (this->delayedMoves.erase(mvid)) { + if (this->delayedMoves.erase(mvid) != 0u) { this->moves.insert(mvid); } } @@ -918,7 +918,7 @@ private: // apply : replace var names in instructions, either mapping into the space of fewer var names or into the space // of machine registers // -typedef std::map RMSubst; +using RMSubst = std::map; inline MInst subst(const RMSubst& s, const RInst& i) { return @@ -940,13 +940,13 @@ inline MInst subst(const RMSubst& s, const RInst& i) { ); } -typedef std::map RRSubst; +using RRSubst = std::map; inline RInst subst(const RRSubst& s, const RInst& i) { return i.mapRegs( [&](const std::string& rname, RegSize, RegClass) -> std::string { - if (maybeMReg(rname)) { + if (maybeMReg(rname) != nullptr) { return rname; } else { auto k = s.find(rname); @@ -1045,9 +1045,9 @@ inline RInsts saveCalleeSaveRegs(const RInsts& insts) { if (csaveInsts.empty()) { const auto& csaveRegs = calleeSaveRegs(); - for (auto r = csaveRegs.begin(); r != csaveRegs.end(); ++r) { - std::string n = ".save." + regName(*r); - csaveInsts.push_back(RInst::make("mov", RArg::reg(n, r->rsize, r->rclass), RArg::reg(stdRegName(r->name, r->rclass), r->rsize, r->rclass))); + for (const auto &csaveReg : csaveRegs) { + std::string n = ".save." + regName(csaveReg); + csaveInsts.push_back(RInst::make("mov", RArg::reg(n, csaveReg.rsize, csaveReg.rclass), RArg::reg(stdRegName(csaveReg.name, csaveReg.rclass), csaveReg.rsize, csaveReg.rclass))); } for (auto r = csaveRegs.rbegin(); r != csaveRegs.rend(); ++r) { std::string n = ".save." + regName(*r); @@ -1097,7 +1097,7 @@ size_t firstFit(const ProgramLiveness& live, const Interference& ig, const std:: // spillFrame : calculate the spill frame for a set of variables to spill, packed into as few frame slots as possible // computed offsets will be relative to a given frame size (and the frame size will be updated on exit) -typedef std::map SpillFrame; +using SpillFrame = std::map; inline SpillFrame spillFrame(const ProgramLiveness& live, const Interference& ig, uint32_t* sframe, const std::set& spillVars) { // find a slot for each spilled var (creating as few as necessary) @@ -1166,7 +1166,7 @@ inline RRSubst spillSubst(size_t pc, const std::set& spillVars, const Pro RRSubst r; for (const std::string& v : vs) { VarID vid = live.id(v); - if (spillVars.count(vid)) { + if (spillVars.count(vid) != 0u) { std::ostringstream vns; vns << ".spill." << vid << "." << pc; r[v] = vns.str(); diff --git a/include/hobbes/net.H b/include/hobbes/net.H index 40e6b5bdd..8fff2d104 100644 --- a/include/hobbes/net.H +++ b/include/hobbes/net.H @@ -21,15 +21,15 @@ #include #include +#include +#include +#include +#include +#include +#include #include #include -#include -#include -#include -#include #include -#include -#include // types with static reflection info (for reflective structs, variants, etc) #include "reflect.H" @@ -41,7 +41,7 @@ namespace hobbes { namespace net { #define HNET_CMD_INVOKE static_cast(2) #define HNET_RESULT_FAIL 0 -typedef std::vector bytes; +using bytes = std::vector; // basic socket I/O inline void sendData(int socket, const uint8_t* d, size_t sz) { @@ -127,15 +127,15 @@ struct RPCDef { bytes willPut; // what type will be sent? bytes willGet; // what type will be received? }; -typedef std::vector RPCDefs; +using RPCDefs = std::vector; // initiate a session on a connected socket by sending all of the RPC defs inline int initSession(int s, const RPCDefs& rpcds) { - uint32_t version = HNET_VERSION; + auto version = HNET_VERSION; sendData(s, reinterpret_cast(&version), sizeof(version)); for (const auto& rpcd : rpcds) { - uint8_t defCmd = HNET_CMD_DEFEXPR; + auto defCmd = HNET_CMD_DEFEXPR; sendData(s, &defCmd, sizeof(defCmd)); sendData(s, reinterpret_cast(&rpcd.id), sizeof(rpcd.id)); sendString(s, rpcd.expr); @@ -160,9 +160,16 @@ inline addrinfo* lookupAddrInfo(const std::string& host, const std::string& port memset(&h, 0, sizeof(h)); h.ai_family = AF_UNSPEC; h.ai_socktype = SOCK_STREAM; + const bool isServer = host.empty(); + const char* hostname = isServer ? nullptr : host.c_str(); + const char* service = port.empty() ? nullptr : port.c_str(); + assert(!(hostname == nullptr && service == nullptr)); + if (isServer) { + h.ai_flags = AI_PASSIVE; + } - struct addrinfo* addrs = 0; - switch (getaddrinfo(host.c_str(), port.empty() ? 0 : port.c_str(), &h, &addrs)) { + struct addrinfo* addrs = nullptr; + switch (getaddrinfo(hostname, service, &h, &addrs)) { case 0: return addrs; case EAI_ADDRFAMILY: throw std::runtime_error("Cannot make socket connection to " + host + ":" + port); case EAI_AGAIN: throw std::runtime_error(host + ":" + port + " is temporarily unavailable"); @@ -172,26 +179,26 @@ inline addrinfo* lookupAddrInfo(const std::string& host, const std::string& port case EAI_SERVICE: throw std::runtime_error("Failed to resolve service: " + port); default: throw std::runtime_error("Unknown error while trying to resolve " + host + ":" + port); } - return 0; + return nullptr; } inline int makeConnection(const std::string& localAddr, const std::string& host, const std::string& port) { - struct addrinfo* localAddrs = localAddr.empty() ? 0 : lookupAddrInfo(localAddr, ""); + struct addrinfo* localAddrs = localAddr.empty() ? nullptr : lookupAddrInfo(localAddr, ""); struct addrinfo* addrs = lookupAddrInfo(host, port); - for (auto p = addrs; p != 0; p = p->ai_next) { + for (auto *p = addrs; p != nullptr; p = p->ai_next) { int s = socket(p->ai_family, p->ai_socktype, p->ai_protocol); if (s == -1) continue; - auto la = localAddrs; - for (; la != 0; la = la->ai_next) { + auto *la = localAddrs; + for (; la != nullptr; la = la->ai_next) { if (la->ai_family == p->ai_family && la->ai_socktype == p->ai_socktype && la->ai_protocol == p->ai_protocol) { if (bind(s, la->ai_addr, la->ai_addrlen) != -1) { break; } } } - if (la == 0 && localAddrs != 0) continue; + if (la == nullptr && localAddrs != nullptr) continue; if (connect(s, p->ai_addr, p->ai_addrlen) == -1) { close(s); @@ -222,7 +229,7 @@ inline int makeConnection(const std::string& host, size_t port) { } inline int makeConnection(const std::string& hostport) { - auto p = hostport.find(":"); + auto p = hostport.find(':'); if (p == std::string::npos) { throw std::runtime_error("Failed to determine port: " + hostport); } else { @@ -276,7 +283,7 @@ template <> static void write(int, const unit&) { } static void read (int, unit*) { } - typedef uint8_t async_read_state; + using async_read_state = uint8_t; static void prepare(uint8_t*) {} static bool accum(int, uint8_t*, unit*) { return true; } }; @@ -290,7 +297,7 @@ template static void write(int s, const T& x) { io::write(s, static_cast(x.value)); } static void read(int s, T* x) { io::read(s, reinterpret_cast(&x->value)); } - typedef uint8_t async_read_state; + using async_read_state = uint8_t; static void prepare(uint8_t* o) { *o = 0; } static bool accum(int s, uint8_t* o, T* x) { *o += recvDataPartial(s, reinterpret_cast(x) + *o, sizeof(typename T::rep_t) - *o); return *o == sizeof(typename T::rep_t); } }; @@ -298,8 +305,8 @@ template // support variants template struct descVariantTy { - typedef typename nth::type H; - typedef descVariantTy Recurse; + using H = typename nth::type; + using Recurse = descVariantTy; static void ctorDefs(ty::Variant::Ctors* cs) { std::ostringstream fn; @@ -333,14 +340,14 @@ template }; template struct AsyncStateOf { - typedef typename io::async_read_state type; + using type = typename io::async_read_state; }; template struct variantAsyncInit { static void fn(T* p, void* rs) { new (p) T(); - typedef typename io::async_read_state RSType; + using RSType = typename io::async_read_state; new (rs) RSType(); io::prepare(reinterpret_cast(rs)); } @@ -348,7 +355,7 @@ template template struct variantAsyncAccum { static bool fn(T* p, int s, void* rs) { - typedef typename io::async_read_state RSType; + using RSType = typename io::async_read_state; return io::accum(s, reinterpret_cast(rs), p); } }; @@ -367,9 +374,9 @@ template variantApp, int>::apply(x->unsafeTag(), x->unsafePayload(), s); } - typedef typename io::async_read_state TagState; - typedef typename fmap>::type PayloadSAsTuple; - typedef typename toVariant::type PayloadState; + using TagState = typename io::async_read_state; + using PayloadSAsTuple = typename fmap>::type; + using PayloadState = typename toVariant::type; struct async_read_state { bool readTag; @@ -406,7 +413,7 @@ struct descVariantF { }; template struct io::type> { - typedef typename T::as_variant_type VT; + using VT = typename T::as_variant_type; static const bool can_memcpy = io::can_memcpy; static ty::desc type() { @@ -419,7 +426,7 @@ template static void write(int s, const T& x) { io::write(s, *reinterpret_cast(&x)); } static void read (int s, T* x) { io::read(s, reinterpret_cast(x)); } - typedef typename io::async_read_state async_read_state; + using async_read_state = typename io::async_read_state; static void prepare(async_read_state* o) { io::prepare(o); } static bool accum(int s, async_read_state* o, T* x) { return io::accum(s, o, reinterpret_cast(x)); } }; @@ -442,8 +449,8 @@ template // async reading of pairs struct async_read_state { - typedef typename io::async_read_state Ustate; - typedef typename io::async_read_state Vstate; + using Ustate = typename io::async_read_state; + using Vstate = typename io::async_read_state; bool readFirst; Ustate fstState; @@ -493,7 +500,7 @@ template static bool accum(int s, async_read_state* o, T (*x)[N]) { const auto len = sizeof(T) * N; - uint8_t* buf = reinterpret_cast(&((*x)[0])); + auto* buf = reinterpret_cast(&((*x)[0])); o->bytesRead += recvDataPartial(s, buf + o->bytesRead, len - o->bytesRead); return o->bytesRead == len; } @@ -516,7 +523,7 @@ template } struct async_read_state { - typedef typename io::async_read_state ElemS; + using ElemS = typename io::async_read_state; size_t idx; ElemS elemS; @@ -552,7 +559,7 @@ template // async reading of mem-copyable vectors struct async_read_state { - typedef io::async_read_state LenS; + using LenS = io::async_read_state; bool readLen; LenS lenS; @@ -574,7 +581,7 @@ template o->readLen = false; } } else { - uint8_t* buf = reinterpret_cast(&(*x)[0]); + auto* buf = reinterpret_cast(&(*x)[0]); o->bytesRead += recvDataPartial(s, buf + o->bytesRead, o->byteLen - o->bytesRead); } return !o->readLen && o->bytesRead == o->byteLen; @@ -603,8 +610,8 @@ template // async reading of vectors struct async_read_state { - typedef io::async_read_state LenS; - typedef typename io::async_read_state ElemS; + using LenS = io::async_read_state; + using ElemS = typename io::async_read_state; bool readLen; LenS lenS; @@ -660,9 +667,9 @@ template } } - typedef io::async_read_state LenS; - typedef typename io::async_read_state KS; - typedef typename io::async_read_state TS; + using LenS = io::async_read_state; + using KS = typename io::async_read_state; + using TS = typename io::async_read_state; enum class ReadS : uint8_t { LenS, KS, TS }; struct async_read_state { @@ -721,7 +728,7 @@ template <> // async reading of strings struct async_read_state { - typedef io::async_read_state LenS; + using LenS = io::async_read_state; bool readLen; LenS lenS; @@ -742,7 +749,7 @@ template <> o->readLen = false; } } else { - uint8_t* buf = reinterpret_cast(&(*x)[0]); + auto* buf = reinterpret_cast(&(*x)[0]); o->bytesRead += recvDataPartial(s, buf + o->bytesRead, o->byteLen - o->bytesRead); } return !o->readLen && o->bytesRead == o->byteLen; @@ -752,10 +759,10 @@ template <> // support tuples template struct tupInd { - typedef typename nth::type H; - typedef tuple TT; - typedef typename TT::offs offs; - typedef tupInd Recurse; + using H = typename nth::type; + using TT = tuple; + using offs = typename TT::offs; + using Recurse = tupInd; static void accFields(ty::Struct::Fields* fs) { std::ostringstream ss; @@ -779,7 +786,7 @@ template template struct tupAsyncInit { static void fn(T*, void* rs) { - typedef typename io::async_read_state RSType; + using RSType = typename io::async_read_state; new (rs) RSType(); io::prepare(reinterpret_cast(rs)); } @@ -798,8 +805,8 @@ template static void write(int s, const tuple& x) { tupInd<0, sizeof...(Fs), Fs...>::write(s, x); } static void read (int s, tuple* x) { tupInd<0, sizeof...(Fs), Fs...>::read (s, x); } - typedef typename fmap>::type SAsTuple; - typedef typename toVariant::type async_read_state; + using SAsTuple = typename fmap>::type; + using async_read_state = typename toVariant::type; static void prepare(async_read_state* o) { o->unsafeTag() = 0; @@ -807,10 +814,10 @@ template } static bool accum(int s, async_read_state* o, tuple* x) { if (o->template apply, int, tuple*>(s, x)) { - ++o->unsafeTag(); - if (o->unsafeTag() == sizeof...(Fs)) { + if (o->unsafeTag() == sizeof...(Fs)-1) { return true; } else { + ++o->unsafeTag(); variantApp, void*>::apply(o->unsafeTag(), o->unsafePayload(), o->unsafePayload()); return false; } @@ -835,11 +842,11 @@ template static const bool can_memcpy = false; static ty::desc type() { ty::Struct::Fields fs; defStructF df(&fs); T::meta(df); return ty::record(fs); } - typedef typename T::as_tuple_type TT; + using TT = typename T::as_tuple_type; static void write(int s, const T& x) { io::write(s, *reinterpret_cast(&x)); } static void read (int s, T* x) { io::read (s, reinterpret_cast(x)); } - typedef typename io::async_read_state async_read_state; + using async_read_state = typename io::async_read_state; static void prepare(async_read_state* o) { io::prepare(o); } static bool accum(int s, async_read_state* o, T* x) { return io::accum(s, o, reinterpret_cast(x)); } }; @@ -863,14 +870,14 @@ template // support opaque type aliases template struct io::type> { - typedef typename T::type RT; + using RT = typename T::type; static const bool can_memcpy = io::can_memcpy; static ty::desc type() { return ty::prim(T::name(), io::type()); } static void write(int s, const T& x) { io::write(s, x.value); } static void read (int s, T* x) { io::read (s, &x->value); } - typedef typename io::async_read_state async_read_state; + using async_read_state = typename io::async_read_state; static void prepare(async_read_state* o) { io::prepare(o); } static bool accum(int s, async_read_state* o, T* x) { return io::accum(s, o, &x->value); } }; @@ -985,7 +992,7 @@ template }; template struct AsyncRPCFunc : public AsyncReader { - typedef std::function K; + using K = std::function; AsyncRPCFunc(AsyncScheduler* sched, int* socket, uint32_t exprid) : sched(sched), socket(socket), exprid(exprid) @@ -1008,11 +1015,12 @@ template this->sched->enqueue(this); } - bool readAndFinish() { + bool readAndFinish() override { if (io::accum(*this->socket, &this->pr, &this->r)) { this->ks.front()(this->r); this->ks.pop(); this->r = R(); + this->pr = async_read_state(); io::prepare(&this->pr); return true; } else { @@ -1024,8 +1032,8 @@ template int* socket; uint32_t exprid; - typedef typename io::async_read_state async_read_state; - typedef std::queue KS; + using async_read_state = typename io::async_read_state; + using KS = std::queue; KS ks; R r; diff --git a/include/hobbes/parse/data.H b/include/hobbes/parse/data.H index 8c13066a0..989426c8f 100644 --- a/include/hobbes/parse/data.H +++ b/include/hobbes/parse/data.H @@ -17,8 +17,8 @@ namespace hobbes { -typedef unsigned int nat; -typedef std::vector nats; +using nat = unsigned int; +using nats = std::vector; template std::string show(const T* t) { @@ -31,7 +31,7 @@ template std::string show(const std::vector& ts) { std::ostringstream ss; ss << "["; - if (ts.size() > 0) { + if (!ts.empty()) { ts[0]->show(ss); for (unsigned int i = 1; i < ts.size(); ++i) { ss << ", "; @@ -46,8 +46,8 @@ template // we just watch characters and record newlines class linedb { public: - typedef std::shared_ptr ptr; - typedef std::pair LineCol; + using ptr = std::shared_ptr; + using LineCol = std::pair; linedb(nat stype, const std::string& sdesc); @@ -66,15 +66,14 @@ private: }; // load a set of lines around an implicated set from the specified line database -typedef std::vector strings; -typedef std::pair ldblines; +using strings = std::vector; +using ldblines = std::pair; ldblines load(const linedb::ptr& ldb, const linedb::LineCol& i, const linedb::LineCol& f); template V mapLookup(const std::map& m, const K& k) { - typedef typename std::map::const_iterator CI; - CI i = m.find(k); + auto i = m.find(k); if (i == m.end()) { throw std::runtime_error("Unexpected map index undefined"); } else { diff --git a/include/hobbes/parse/grammar.H b/include/hobbes/parse/grammar.H index 45dad484b..e74e117b1 100644 --- a/include/hobbes/parse/grammar.H +++ b/include/hobbes/parse/grammar.H @@ -17,18 +17,18 @@ namespace hobbes { class GrammarValue : public LexicallyAnnotated { public: + GrammarValue() = delete; + GrammarValue(const LexicallyAnnotated&); virtual ~GrammarValue() = default; virtual void show(std::ostream&) const = 0; -private: - GrammarValue(); }; -typedef std::shared_ptr GrammarValuePtr; +using GrammarValuePtr = std::shared_ptr; class GSymRef : public GrammarValue { public: GSymRef(const std::string&, const LexicalAnnotation&); - void show(std::ostream&) const; + void show(std::ostream&) const override; const std::string& value() const; private: @@ -38,7 +38,7 @@ private: class GStr : public GrammarValue { public: GStr(const std::string&, const LexicalAnnotation&); - void show(std::ostream&) const; + void show(std::ostream&) const override; const std::string& value() const; private: @@ -53,7 +53,7 @@ template template T switchOf(const GrammarValuePtr& p, const switchGrammarValue& f) { - if (const GSymRef* x = dynamic_cast(p.get())) { + if (const auto* x = dynamic_cast(p.get())) { return f.with(x); } else if (const GStr* x = dynamic_cast(p.get())) { return f.with(x); @@ -70,7 +70,7 @@ struct BoundGrammarValue { std::string varname; GrammarValuePtr element; }; -typedef std::vector BoundGrammarValues; +using BoundGrammarValues = std::vector; struct GrammarRule { inline GrammarRule(const BoundGrammarValues& vs, const ExprPtr& e) : values(vs), reduction(e) { } @@ -78,10 +78,10 @@ struct GrammarRule { BoundGrammarValues values; ExprPtr reduction; }; -typedef std::vector GrammarRules; +using GrammarRules = std::vector; -typedef std::pair GrammarSymDef; -typedef std::vector Grammar; +using GrammarSymDef = std::pair; +using Grammar = std::vector; // allow the construction of parsers from grammars class cc; diff --git a/include/hobbes/parse/lalr.H b/include/hobbes/parse/lalr.H index 55cdfa185..f51225546 100644 --- a/include/hobbes/parse/lalr.H +++ b/include/hobbes/parse/lalr.H @@ -14,9 +14,9 @@ namespace hobbes { // a grammar is a mapping from abstract terminals to the set of rules matching those terminals -typedef terminals rule; -typedef std::vector rules; -typedef std::map grammar; +using rule = terminals; +using rules = std::vector; +using grammar = std::map; // an item represents the state of recognizing a rule struct item { @@ -34,23 +34,23 @@ struct item { // an itemset is a partial description of the state of a parser // (with no duplicate items) -typedef std::set itemset; -typedef std::vector itemsets; +using itemset = std::set; +using itemsets = std::vector; // transitions : a set of states to transition to indexed on terminals -typedef std::map state_transitions; +using state_transitions = std::map; // each closed itemset represents a numbered parser state -typedef std::map parser_states; +using parser_states = std::map; // the reverse parser state map -typedef std::map state_definitions; +using state_definitions = std::map; // a set of state transitions map values to target parser states (by index) -typedef std::map state_transitions; +using state_transitions = std::map; // each state has its own set of state transitions -typedef std::map parser_state_transitions; +using parser_state_transitions = std::map; // a parserdef is an ordered sequence of states, along with the transitions defined for each state struct parserdef { @@ -138,8 +138,8 @@ parserdef lr0parser(const grammar& g, terminal* s); nat follow(const parserdef& p, nat q, terminal* t); // a transition of the LR(0) parser can be described by a state and terminal -typedef std::pair transition; -typedef std::set transitionset; +using transition = std::pair; +using transitionset = std::set; transitionset transitions(const parserdef& p); @@ -160,8 +160,8 @@ terminalset directReads(const parserdef& p, const transition& x); template class digraphF { public: - typedef std::set Xs; - typedef std::map F; + using Xs = std::set; + using F = std::map; static F map(const Xs& xs, const Fp& fp, const A& append, const R& r) { return digraphF(xs, fp, append, r).map(); @@ -175,15 +175,15 @@ template digraphF(const Xs& xs, const Fp& fp, const A& append, const R& r) : xs(xs), fp(fp), append(append), r(r) { } - typedef std::stack Xstack; - typedef std::map Xidxs; + using Xstack = std::stack; + using Xidxs = std::map; F map() const { F f; Xstack s; Xidxs n = freshIdxs(this->xs); - for (typename Xs::const_iterator x = this->xs.begin(); x != this->xs.end(); ++x) { + for (auto x = this->xs.begin(); x != this->xs.end(); ++x) { if (n[*x] == 0) { traverse(*x, &s, &n, &f); } @@ -201,7 +201,7 @@ template (*f)[x] = this->fp(x); // and the values of any nodes in the input relation - for (typename Xs::const_iterator y = this->xs.begin(); y != this->xs.end(); ++y) { + for (auto y = this->xs.begin(); y != this->xs.end(); ++y) { if (this->r(x, *y)) { // the node y is in the relation // if it hasn't been visited yet, then recurse into it to determine its value @@ -231,7 +231,7 @@ template static Xidxs freshIdxs(const Xs& xs) { Xidxs r; - for (typename Xs::const_iterator x = xs.begin(); x != xs.end(); ++x) { + for (auto x = xs.begin(); x != xs.end(); ++x) { r[*x] = 0; } return r; @@ -241,7 +241,7 @@ template }; // the across/up sets of LALR(1) determination -typedef std::map transition_lookahead; +using transition_lookahead = std::map; transition_lookahead Reads(const parserdef& p, const transitionset& ts); transition_lookahead Follow(const parserdef& p, const transitionset& ts); @@ -252,7 +252,7 @@ parserdef lalr1parser(const grammar& g, terminal* s); // an ambiguity conflict on a particular terminal class ambiguity_conflict : public std::runtime_error { public: - ambiguity_conflict(const std::string& ex, terminal* t) throw(); + ambiguity_conflict(const std::string& ex, terminal* t) noexcept; terminal* failedTerminal() const; private: @@ -262,7 +262,7 @@ private: // a failure to compile a grammar to an LALR table, with cause class compile_table_failure : public std::runtime_error { public: - compile_table_failure(const std::string& msg, const grammar& g, const itemset& faileditems, terminal* t) throw(); + compile_table_failure(const std::string& msg, const grammar& g, const itemset& faileditems, terminal* t) noexcept; const grammar& failedGrammar() const; const itemset& failedItems() const; @@ -331,10 +331,10 @@ private: std::ostream& operator<<(std::ostream& out, const action& act); // a parser state maps a set of terminals to actions -typedef std::map lrstate; +using lrstate = std::map; // an ordered sequence of states describes the whole behavior of an LR parser -typedef std::vector lrtable; +using lrtable = std::vector; // determine the LR table, derived from the LALR(1) parser lrtable lalrTable(const parserdef& pd, const precedence& p = precedence()); diff --git a/include/hobbes/parse/parser.H b/include/hobbes/parse/parser.H index 6c8c10f57..f46ba3f24 100644 --- a/include/hobbes/parse/parser.H +++ b/include/hobbes/parse/parser.H @@ -23,8 +23,8 @@ namespace hobbes { // such that: // the type of R matches the type of R for all other definitions of S struct ParseRule { - typedef std::pair Binding; - typedef std::vector Bindings; + using Binding = std::pair; + using Bindings = std::vector; inline ParseRule(terminal* s, const Bindings& bs, const ExprPtr& r) : symbol(s), bindings(bs), reducer(r) { } @@ -34,7 +34,7 @@ struct ParseRule { }; // and a parser is a set of such rules -typedef std::vector Parser; +using Parser = std::vector; // consume a grammar to produce a parser for that grammar class cc; diff --git a/include/hobbes/parse/terminal.H b/include/hobbes/parse/terminal.H index 0775dbd32..b8bd7e8db 100644 --- a/include/hobbes/parse/terminal.H +++ b/include/hobbes/parse/terminal.H @@ -25,8 +25,8 @@ struct terminal { virtual PatternPtr matchPattern() const = 0; virtual ExprPtr matchRefExpr() const = 0; }; -typedef std::vector terminals; -typedef std::set terminalset; +using terminals = std::vector; +using terminalset = std::set; // characters can be terminals class character : public terminal { @@ -34,10 +34,10 @@ public: character(char x = 0); char value() const; void value(char); - void show(std::ostream&) const; + void show(std::ostream&) const override; - PatternPtr matchPattern() const; - ExprPtr matchRefExpr() const; + PatternPtr matchPattern() const override; + ExprPtr matchRefExpr() const override; private: char x; }; @@ -47,10 +47,10 @@ class symbol : public terminal { public: symbol(const std::string& sname); const std::string& name() const; - void show(std::ostream& out) const; + void show(std::ostream& out) const override; - [[noreturn]] PatternPtr matchPattern() const; - [[noreturn]] ExprPtr matchRefExpr() const; + [[noreturn]] PatternPtr matchPattern() const override; + [[noreturn]] ExprPtr matchRefExpr() const override; private: std::string sname; }; @@ -59,11 +59,11 @@ private: class endOfFile : public terminal { public: endOfFile(); - void show(std::ostream&) const; + void show(std::ostream&) const override; static terminal* value(); - [[noreturn]] PatternPtr matchPattern() const; - [[noreturn]] ExprPtr matchRefExpr() const; + [[noreturn]] PatternPtr matchPattern() const override; + [[noreturn]] ExprPtr matchRefExpr() const override; }; // allow terminals to be ordered by basic precedence / associativity definitions @@ -79,7 +79,7 @@ struct prec { assoc::pref asc; }; -typedef std::map precedence; +using precedence = std::map; } diff --git a/include/hobbes/read/parser.H b/include/hobbes/read/parser.H index 1cbcdf40f..3d6602edb 100644 --- a/include/hobbes/read/parser.H +++ b/include/hobbes/read/parser.H @@ -18,7 +18,7 @@ ModulePtr defReadModuleFile(cc*, const std::string&); ModulePtr defReadModule(cc*, const char*); ModulePtr defReadModule(cc*, const std::string&); -typedef std::pair ExprDefn; +using ExprDefn = std::pair; ExprDefn defReadExprDefn(cc*, const std::string&); ExprPtr defReadExpr(cc*, const std::string&); @@ -28,10 +28,10 @@ ExprPtr defReadExpr(cc*, const std::string&); Expr* defVarCtor(const std::string&, const LexicalAnnotation&); Pattern* defPatVarCtor(const std::string&, const LexicalAnnotation&); -typedef Expr* (*VarCtorFn)(const std::string&, const LexicalAnnotation&); +using VarCtorFn = Expr *(*)(const std::string &, const LexicalAnnotation &); void overrideVarCtor(VarCtorFn); -typedef Pattern* (*PatVarCtorFn)(const std::string&, const LexicalAnnotation&); +using PatVarCtorFn = Pattern *(*)(const std::string &, const LexicalAnnotation &); void overridePatVarCtor(PatVarCtorFn); } diff --git a/include/hobbes/read/pgen/hexpr.parse.H b/include/hobbes/read/pgen/hexpr.parse.H index f5e8e6e79..10ed00dd9 100644 --- a/include/hobbes/read/pgen/hexpr.parse.H +++ b/include/hobbes/read/pgen/hexpr.parse.H @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 3.7.4. */ +/* A Bison parser, made by GNU Bison 3.8.2. */ /* Bison interface for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify @@ -16,7 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program. If not, see . */ + along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -156,7 +156,7 @@ extern int yydebug; #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { -#line 262 "hexpr.y" +#line 295 "hexpr.y" hobbes::Module* module; hobbes::ModuleDefs* mdefs; @@ -197,6 +197,7 @@ union YYSTYPE hobbes::MonoTypes* mtypes; hobbes::Record::Members* mreclist; hobbes::Variant::Members* mvarlist; + hobbes::Variant::Member* mpvar; std::string* string; bool boolv; @@ -216,7 +217,7 @@ union YYSTYPE hobbes::BoundGrammarValue* pbelem; hobbes::GrammarValue* pvalue; -#line 220 "hexpr.parse.H" +#line 221 "hexpr.parse.H" }; typedef union YYSTYPE YYSTYPE; @@ -241,6 +242,8 @@ struct YYLTYPE extern YYSTYPE yylval; extern YYLTYPE yylloc; + int yyparse (void); + #endif /* !YY_YY_HEXPR_PARSE_H_INCLUDED */ diff --git a/include/hobbes/reflect.H b/include/hobbes/reflect.H index 2a150be62..3de3a275a 100644 --- a/include/hobbes/reflect.H +++ b/include/hobbes/reflect.H @@ -12,17 +12,17 @@ #ifndef HOBBES_REFLECT_H_INCLUDED #define HOBBES_REFLECT_H_INCLUDED -#include -#include -#include -#include +#include +#include +#include #include +#include +#include #include -#include -#include #include +#include #include -#include +#include #if defined(__APPLE__) && defined(__MACH__) #include @@ -50,7 +50,7 @@ namespace string { inline std::string demangle() { if (const char* tn = typeid(T).name()) { int s = 0; - if (char* dmn = abi::__cxa_demangle(tn, 0, 0, &s)) { + if (char* dmn = abi::__cxa_demangle(tn, nullptr, nullptr, &s)) { std::string r(dmn); free(dmn); return r; @@ -63,9 +63,9 @@ namespace string { } // tokenize strings - typedef std::vector seq; + using seq = std::vector; inline seq csplit(const std::string& str, const std::string& pivot) { - typedef std::string::size_type size_type; + using size_type = std::string::size_type; seq ret; size_type mp = 0; @@ -85,7 +85,7 @@ namespace string { return ret; } - typedef std::pair pair; + using pair = std::pair; inline pair rsplit(const std::string& s, const std::string& ss) { size_t p = s.rfind(ss); if (p == std::string::npos) { @@ -96,7 +96,7 @@ namespace string { } inline std::string cdelim(const seq& ss, const std::string& d) { - if (ss.size() > 0) { + if (!ss.empty()) { std::ostringstream x; x << ss[0]; for (size_t i = 1; i < ss.size(); ++i) { @@ -109,7 +109,7 @@ namespace string { } } -typedef __int128 int128_t; +using int128_t = __int128; // very basic macro metaprogramming #define PRIV_HPPF_FIRST(a, ...) a @@ -188,7 +188,7 @@ template // value-level bool -> type-level bool template struct tbool { }; -template <> struct tbool { typedef void type; }; +template <> struct tbool { using type = void; }; // test to see if a type(s) can be printed template () << std::declval())> @@ -230,7 +230,7 @@ template struct offsetInfo { static const size_t offset = alignTo(base, alignof(Field)); - typedef offsetInfo tail; + using tail = offsetInfo; static const size_t maxAlignment = szmax(alignof(Field), tail::maxAlignment); static const size_t size = (offset-base) + sizeof(Field) + tail::size; @@ -265,13 +265,13 @@ template template struct nth { }; template - struct nth<0, Field, Fields...> { typedef Field type; }; + struct nth<0, Field, Fields...> { using type = Field; }; template struct nth : nth { }; template struct tuple { - typedef offsetInfo<0, 0, Fields...> offs; + using offs = offsetInfo<0, 0, Fields...>; static const size_t alignment = offs::maxAlignment; static const size_t size = alignTo(offs::size, offs::maxAlignment); static const bool packed = (size == offs::size) && offs::packed; @@ -316,11 +316,11 @@ template <> static const size_t alignment = 1; static const size_t size = 0; - tuple() { } - tuple(const tuple<>&) { } - ~tuple() { } + tuple() = default; + tuple(const tuple<>&) = default; + ~tuple() = default; - tuple<>& operator=(const tuple<>&) { return *this; } + tuple<>& operator=(const tuple<>&) = default; }; template @@ -331,33 +331,33 @@ template template struct tupType { }; template - struct tupType> { typedef typename nth::type type; }; + struct tupType> { using type = typename nth::type; }; // map a function over a tuple's types (useful for structurally-derived types) template struct concatT { }; template struct concatT, tuple, Rest...> { - typedef typename concatT, Rest...>::type type; + using type = typename concatT, Rest...>::type; }; template struct concatT> { - typedef tuple type; + using type = tuple; }; template
" << vty.first << "" << showType(*this->c, vty.second->instantiate()) << "