diff --git a/.gitmodules b/.gitmodules index 94faa0800..fce3abd86 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,21 @@ [submodule "compiler+runtime/third-party/bpptree"] path = compiler+runtime/third-party/bpptree url = https://github.com/jank-lang/BppTree.git +[submodule "compiler+runtime/third-party/bdwgc"] + path = compiler+runtime/third-party/bdwgc + url = https://github.com/jank-lang/bdwgc.git +[submodule "compiler+runtime/third-party/fmt"] + path = compiler+runtime/third-party/fmt + url = https://github.com/jank-lang/fmt.git +[submodule "compiler+runtime/third-party/immer"] + path = compiler+runtime/third-party/immer + url = https://github.com/jank-lang/immer.git +[submodule "compiler+runtime/third-party/magic_enum"] + path = compiler+runtime/third-party/magic_enum + url = https://github.com/jank-lang/magic_enum.git +[submodule "compiler+runtime/third-party/cli11"] + path = compiler+runtime/third-party/cli11 + url = https://github.com/jank-lang/CLI11.git +[submodule "compiler+runtime/third-party/libzippp"] + path = compiler+runtime/third-party/libzippp + url = https://github.com/jank-lang/libzippp.git diff --git a/compiler+runtime/CMakeLists.txt b/compiler+runtime/CMakeLists.txt index dba972950..d03b87c0b 100644 --- a/compiler+runtime/CMakeLists.txt +++ b/compiler+runtime/CMakeLists.txt @@ -13,18 +13,15 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules" - ) +) # LTO is explicitly not used, since it leads to runtime symbol lookup issues with the JIT. set(CMAKE_INTERPROCEDURAL_OPTIMIZATION FALSE) -set(VCPKG_OVERLAY_TRIPLETS "${CMAKE_SOURCE_DIR}/vcpkg-triplet") -set(VCPKG_TARGET_TRIPLET "x64-clang-static") - project( jank VERSION 0.1 - DESCRIPTION "A native Clojure dialect built on LLVM." + DESCRIPTION "The native Clojure dialect on LLVM." HOMEPAGE_URL "https://jank-lang.org/" # C is needed here, due to a clang issue: # https://stackoverflow.com/questions/71740678/cmake-error-in-findterminfo-with-clang-15-on-macos @@ -203,17 +200,22 @@ add_library( ) target_include_directories( - jank_lib - PUBLIC - "$" + jank_lib + PUBLIC + "$" ) target_include_directories( - jank_lib - SYSTEM - PUBLIC - "$" - "$" - "$" + jank_lib + SYSTEM + PUBLIC + "$" + "$" + "$" + "$" + "$" + "$" + "$" + "$" ) target_precompile_headers( jank_lib @@ -225,29 +227,23 @@ set_property(TARGET jank_lib PROPERTY OUTPUT_NAME jank) target_compile_features(jank_lib PUBLIC ${jank_cxx_standard}) target_compile_options(jank_lib PUBLIC ${jank_common_compiler_flags} ${jank_aot_compiler_flags}) -find_package(Immer CONFIG REQUIRED) -find_package(magic_enum CONFIG REQUIRED) -find_package(fmt CONFIG REQUIRED) -find_package(Boost REQUIRED COMPONENTS filesystem preprocessor) -find_package(BDWgc CONFIG REQUIRED) -find_package(libzippp CONFIG REQUIRED) -find_package(CLI11 CONFIG REQUIRED) -find_package(OpenSSL CONFIG REQUIRED) -#find_package(libassert CONFIG REQUIRED) +include(FetchContent) +include(cmake/dependency/bdwgc.cmake) +include(cmake/dependency/fmt.cmake) +include(cmake/dependency/libzippp.cmake) -target_include_directories(jank_lib SYSTEM PRIVATE ${Boost_INCLUDE_DIRS}) +find_package(OpenSSL REQUIRED COMPONENTS Crypto) +find_package(Boost REQUIRED COMPONENTS filesystem) target_link_libraries( jank_lib PRIVATE - immer fmt::fmt - BDWgc::gc BDWgc::cord BDWgc::gccpp BDWgc::gctba + fmt::fmt + bdwgc::gc bdwgc::gccpp libzippp::libzippp - CLI11::CLI11 - #libassert::assert readline clangInterpreter - Boost::boost - $<$:crypto> + Boost::filesystem + OpenSSL::Crypto ) jank_hook_llvm(jank_lib) @@ -330,7 +326,7 @@ set_target_properties(nanobench_lib PROPERTIES ENABLE_EXPORTS 1) # ---- libfolly.a ---- # Folly is well and truly a pain in the ass to build through its -# own build system (via vcpkg). It regularly fails to build for me +# own build system. It regularly fails to build for me # on all sorts of standard systems (both Linux and macOS) and jank # has been running with custom patches for several months now. After # running into compilation issues with it yet again, I've decided to @@ -366,7 +362,6 @@ target_include_directories( SYSTEM PUBLIC "$" - ${BOOST_INCLUDE_DIRS} ) set_property(TARGET folly_lib PROPERTY OUTPUT_NAME folly) @@ -382,7 +377,7 @@ set_target_properties(folly_lib PROPERTIES ENABLE_EXPORTS 1) target_link_libraries( folly_lib PUBLIC - Boost::preprocessor + fmt::fmt ) # ---- libfolly.a ---- @@ -402,15 +397,13 @@ target_compile_features(jank_exe PRIVATE ${jank_cxx_standard}) target_compile_options(jank_exe PUBLIC ${jank_common_compiler_flags} ${jank_aot_compiler_flags}) target_link_options(jank_exe PRIVATE ${jank_linker_flags}) -target_include_directories(jank_exe SYSTEM PRIVATE ${BOOST_INCLUDE_DIRS}) - target_link_libraries( jank_exe PUBLIC ${jank_link_whole_start} jank_lib ${jank_link_whole_end} ${jank_link_whole_start} nanobench_lib ${jank_link_whole_end} folly_lib fmt::fmt - Boost::boost Boost::filesystem Boost::system + Boost::filesystem ) jank_hook_llvm(jank_exe) @@ -440,8 +433,6 @@ if(jank_tests) target_compile_options(jank_test_exe PRIVATE -DDOCTEST_CONFIG_SUPER_FAST_ASSERTS) target_link_options(jank_test_exe PRIVATE ${jank_linker_flags}) - target_include_directories(jank_test_exe SYSTEM PRIVATE ${BOOST_INCLUDE_DIRS}) - find_package(doctest REQUIRED) target_link_libraries( jank_test_exe PUBLIC @@ -449,7 +440,7 @@ if(jank_tests) ${jank_link_whole_start} nanobench_lib ${jank_link_whole_end} folly_lib doctest::doctest - Boost::boost Boost::filesystem + Boost::filesystem ) jank_hook_llvm(jank_test_exe) diff --git a/compiler+runtime/cmake/dependency/bdwgc.cmake b/compiler+runtime/cmake/dependency/bdwgc.cmake new file mode 100644 index 000000000..193e50090 --- /dev/null +++ b/compiler+runtime/cmake/dependency/bdwgc.cmake @@ -0,0 +1,19 @@ +set(CMAKE_C_FLAGS_OLD "${CMAKE_C_FLAGS}") +set(CMAKE_CXX_FLAGS_OLD "${CMAKE_CXX_FLAGS}") +set(BUILD_SHARED_LIBS_OLD ${BUILD_SHARED_LIBS}) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w") + set(BUILD_SHARED_LIBS OFF) + set(enable_cplusplus ON CACHE BOOL "Enable C++") + set(build_cord OFF CACHE BOOL "Build cord") + set(enable_docs OFF CACHE BOOL "Enable docs") + set(enable_throw_bad_alloc_library OFF CACHE BOOL "Enable C++ gctba library build") + + add_subdirectory(third-party/bdwgc) + + unset(enable_cplusplus) + unset(build_cord) + unset(enable_docs) +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS_OLD}") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_OLD}") +set(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS_OLD}) diff --git a/compiler+runtime/cmake/dependency/fmt.cmake b/compiler+runtime/cmake/dependency/fmt.cmake new file mode 100644 index 000000000..1baa1e744 --- /dev/null +++ b/compiler+runtime/cmake/dependency/fmt.cmake @@ -0,0 +1,7 @@ +set(FMT_DOC OFF CACHE BOOL "Generate docs") +set(FMT_INSTALL OFF CACHE BOOL "Generate the install target.") + +add_subdirectory(third-party/fmt) + +unset(FMT_DOC) +unset(FMT_INSTALL) diff --git a/compiler+runtime/cmake/dependency/libzippp.cmake b/compiler+runtime/cmake/dependency/libzippp.cmake new file mode 100644 index 000000000..9fee4b74c --- /dev/null +++ b/compiler+runtime/cmake/dependency/libzippp.cmake @@ -0,0 +1,8 @@ +set(CMAKE_C_FLAGS_OLD "${CMAKE_C_FLAGS}") +set(CMAKE_CXX_FLAGS_OLD "${CMAKE_CXX_FLAGS}") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w") + + add_subdirectory(third-party/libzippp) +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS_OLD}") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_OLD}") diff --git a/compiler+runtime/default.nix b/compiler+runtime/default.nix index d31c17155..6fa22745b 100644 --- a/compiler+runtime/default.nix +++ b/compiler+runtime/default.nix @@ -10,8 +10,6 @@ let # Deps boost = pkgs.callPackage ./nix/boost.nix { }; - boehmgc = pkgs.callPackage ./nix/boehmgc.nix { }; - libzippp = pkgs.callPackage ./nix/libzippp.nix { }; openssl = pkgs.callPackage ./nix/openssl.nix { }; in @@ -28,17 +26,11 @@ pkgs.llvmPackages_19.stdenv.mkDerivation { buildInputs = [ boost - boehmgc - libzippp openssl pkgs.doctest pkgs.double-conversion pkgs.readline pkgs.libzip - pkgs.immer - pkgs.cli11 - pkgs.magic-enum - pkgs.fmt pkgs.llvmPackages_19.clang-unwrapped pkgs.llvmPackages_19.llvm ]; diff --git a/compiler+runtime/doc/build.md b/compiler+runtime/doc/build.md index d01e1950c..dad390d22 100644 --- a/compiler+runtime/doc/build.md +++ b/compiler+runtime/doc/build.md @@ -3,19 +3,19 @@ For Debian-based distros, this should be all you need: ```bash -sudo apt-get install -y curl git git-lfs zip build-essential entr libssl-dev libdouble-conversion-dev pkg-config ninja-build python3-pip cmake debhelper devscripts gnupg zlib1g-dev entr libffi-dev clang libjemalloc-dev libreadline-dev +sudo apt-get install -y curl git git-lfs zip build-essential entr libssl-dev libdouble-conversion-dev pkg-config ninja-build python3-pip cmake debhelper devscripts gnupg zlib1g-dev entr libffi-dev clang libreadline-dev libzip-dev libbz2-dev doctest-dev libboost-all-dev ``` For Arch: ```bash -sudo pacman -S git git-lfs clang pkg-config cmake ninja make python3 libffi jemalloc entr +sudo pacman -S git git-lfs clang pkg-config cmake ninja make python3 libffi entr doctest boost libzip lbzip2 ``` For macOS, try this: ```bash -brew install curl git git-lfs zip entr openssl double-conversion pkg-config ninja python cmake gnupg zlib jemalloc +brew install curl git git-lfs zip entr openssl double-conversion pkg-config ninja python cmake gnupg zlib doctest boost libzip lbzip2 ``` Clone the repo as follows: @@ -27,8 +27,8 @@ git clone --recurse-submodules https://github.com/jank-lang/jank.git git submodule update --recursive --init ``` -## Compiling Cling -Note that you must compile Cling/Clang/LLVM. This can take an hour or two, +## Compiling Clang +Note that you must compile Clang/LLVM. This can take an hour or two, depending on your machine. Building jank itself should take a minute or two. ``` diff --git a/compiler+runtime/include/cpp/jank/prelude.hpp b/compiler+runtime/include/cpp/jank/prelude.hpp index 565a4966e..b900c1f3b 100644 --- a/compiler+runtime/include/cpp/jank/prelude.hpp +++ b/compiler+runtime/include/cpp/jank/prelude.hpp @@ -14,8 +14,6 @@ #include -//#include - #include #include diff --git a/compiler+runtime/include/cpp/jank/read/parse.hpp b/compiler+runtime/include/cpp/jank/read/parse.hpp index 7e1db7aaa..7e61bfad0 100644 --- a/compiler+runtime/include/cpp/jank/read/parse.hpp +++ b/compiler+runtime/include/cpp/jank/read/parse.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include #include #include @@ -12,39 +14,16 @@ namespace jank::runtime /* TODO: Rename file to processor. */ namespace jank::read::parse { - static option get_char_from_literal(native_persistent_string const &sv) + + struct char_parse_error { - if(sv.size() == 2) - { - return sv[1]; - } - else if(sv == R"(\newline)") - { - return '\n'; - } - else if(sv == R"(\space)") - { - return ' '; - } - else if(sv == R"(\tab)") - { - return '\t'; - } - else if(sv == R"(\backspace)") - { - return '\b'; - } - else if(sv == R"(\formfeed)") - { - return '\f'; - } - else if(sv == R"(\return)") - { - return '\r'; - } + native_persistent_string error; + }; + + result + parse_character_in_base(native_persistent_string const &char_literal, int const base); - return none; - } + option get_char_from_literal(native_persistent_string const &s); struct processor { diff --git a/compiler+runtime/include/cpp/jank/util/escape.hpp b/compiler+runtime/include/cpp/jank/util/escape.hpp index 42525fe82..e9a58c22f 100644 --- a/compiler+runtime/include/cpp/jank/util/escape.hpp +++ b/compiler+runtime/include/cpp/jank/util/escape.hpp @@ -78,7 +78,7 @@ struct fmt::formatter> } template - auto format(jank::util::escape_view const &s, C &ctx) + auto format(jank::util::escape_view const &s, C &ctx) const { return s.copy(ctx.out()); } diff --git a/compiler+runtime/nix/boehmgc.nix b/compiler+runtime/nix/boehmgc.nix deleted file mode 100644 index 577da1afc..000000000 --- a/compiler+runtime/nix/boehmgc.nix +++ /dev/null @@ -1,31 +0,0 @@ -{ - pkgs ? import (builtins.fetchTarball { - url = "https://github.com/NixOS/nixpkgs/archive/75b209227dff3cbfac19f510a62f9446c92beac4.tar.gz"; - sha256 = "166varzdamn2kkw5zslarzl6026q87wjnss1hlhdsq89hwvfgd2d"; - }) { }, -}: - -let - stdenv = pkgs.llvmPackages_19.stdenv; - cc = stdenv.cc.cc; -in - -stdenv.mkDerivation rec { - pname = "boehm-gc"; - version = "8.2.8"; - - src = pkgs.fetchFromGitHub { - owner = "ivmai"; - repo = "bdwgc"; - rev = "v${version}"; - hash = "sha256-UQSLK/05uPal6/m+HMz0QwXVII1leonlmtSZsXjJ+/c="; - }; - - nativeBuildInputs = [ - pkgs.cmake - ]; - - cmakeFlags = [ - "-Denable_cplusplus=ON" - ]; -} diff --git a/compiler+runtime/nix/boost.nix b/compiler+runtime/nix/boost.nix index d63485f05..3b296c54d 100644 --- a/compiler+runtime/nix/boost.nix +++ b/compiler+runtime/nix/boost.nix @@ -1,16 +1,8 @@ { - pkgs ? import (builtins.fetchTarball { - url = "https://github.com/NixOS/nixpkgs/archive/75b209227dff3cbfac19f510a62f9446c92beac4.tar.gz"; - sha256 = "166varzdamn2kkw5zslarzl6026q87wjnss1hlhdsq89hwvfgd2d"; - }) { }, + pkgs, }: -let - stdenv = pkgs.llvmPackages_19.stdenv; - cc = stdenv.cc.cc; -in - -stdenv.mkDerivation rec { +pkgs.stdenv.mkDerivation rec { pname = "boost"; version = "1.86.0"; diff --git a/compiler+runtime/nix/libzippp.nix b/compiler+runtime/nix/libzippp.nix deleted file mode 100644 index 0e72e10e8..000000000 --- a/compiler+runtime/nix/libzippp.nix +++ /dev/null @@ -1,32 +0,0 @@ -{ - pkgs ? import (builtins.fetchTarball { - url = "https://github.com/NixOS/nixpkgs/archive/75b209227dff3cbfac19f510a62f9446c92beac4.tar.gz"; - sha256 = "166varzdamn2kkw5zslarzl6026q87wjnss1hlhdsq89hwvfgd2d"; - }) { }, -}: - -let - stdenv = pkgs.llvmPackages_19.stdenv; - cc = stdenv.cc.cc; -in - -stdenv.mkDerivation rec { - pname = "libzippp"; - version = "7.1-1.10.1"; - - src = pkgs.fetchFromGitHub { - owner = "ctabin"; - repo = pname; - rev = "${pname}-v${version}"; - hash = "sha256-ffX4UuDKMgSYwIecmJnj+XLnjsMwUbK6rraOk0z4Ma8="; - }; - - nativeBuildInputs = [ - pkgs.cmake - ]; - - buildInputs = [ - pkgs.zlib - pkgs.libzip - ]; -} diff --git a/compiler+runtime/nix/openssl.nix b/compiler+runtime/nix/openssl.nix index 40208d3fc..8bc6f6ab5 100644 --- a/compiler+runtime/nix/openssl.nix +++ b/compiler+runtime/nix/openssl.nix @@ -1,16 +1,8 @@ { - pkgs ? import (builtins.fetchTarball { - url = "https://github.com/NixOS/nixpkgs/archive/75b209227dff3cbfac19f510a62f9446c92beac4.tar.gz"; - sha256 = "166varzdamn2kkw5zslarzl6026q87wjnss1hlhdsq89hwvfgd2d"; - }) { }, + pkgs, }: -let - stdenv = pkgs.llvmPackages_19.stdenv; - cc = stdenv.cc.cc; -in - -stdenv.mkDerivation rec { +pkgs.stdenv.mkDerivation rec { pname = "openssl"; version = "3.3.2"; diff --git a/compiler+runtime/nix/readline.nix b/compiler+runtime/nix/readline.nix new file mode 100644 index 000000000..29355afa0 --- /dev/null +++ b/compiler+runtime/nix/readline.nix @@ -0,0 +1,5 @@ +{ + pkgs, +}: + +pkgs.readline diff --git a/compiler+runtime/src/cpp/jank/read/parse.cpp b/compiler+runtime/src/cpp/jank/read/parse.cpp index 396bd2348..ed965884c 100644 --- a/compiler+runtime/src/cpp/jank/read/parse.cpp +++ b/compiler+runtime/src/cpp/jank/read/parse.cpp @@ -15,6 +15,81 @@ namespace jank::read::parse { using namespace jank::runtime; + result + parse_character_in_base(native_persistent_string const &char_literal, int const base) + { + try + { + size_t chars_processed{}; + auto const codepoint(std::stol(char_literal, &chars_processed, base)); + + /* `std::stol` will ignore any character that lies outside of + * the `base` digits range. + * + * For base `8`, valid digits are {0, 1, 2, 3, 4, 5, 6, 7}. + * For base `16`, valid digits are {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, A, B, C, D, E, F} + * + * If `std::stol` doesn't process all the + * characters in `char_literal`, we'll consider it as invalid. + * + * Refer: https://en.cppreference.com/w/cpp/string/basic_string/stol + */ + if(chars_processed != char_literal.size()) + { + return err("Invalid unicode digit"); + } + + std::wstring_convert, char32_t> converter; + + native_persistent_string const converted(converter.to_bytes(codepoint)); + + if(converter.converted() != 1) + { + return err("Out of range"); + } + + return ok(converted); + } + catch(std::exception const &e) + { + return err(e.what()); + } + } + + option get_char_from_literal(native_persistent_string const &s) + { + if(s.size() == 2) + { + return s[1]; + } + else if(s == R"(\newline)") + { + return '\n'; + } + else if(s == R"(\space)") + { + return ' '; + } + else if(s == R"(\tab)") + { + return '\t'; + } + else if(s == R"(\backspace)") + { + return '\b'; + } + else if(s == R"(\formfeed)") + { + return '\f'; + } + else if(s == R"(\return)") + { + return '\r'; + } + + return none; + } + native_bool processor::object_source_info::operator==(processor::object_source_info const &rhs) const { @@ -350,6 +425,26 @@ namespace jank::read::parse if(character.is_none()) { + /* Hexadecimal unicode */ + if(sv[0] == '\\' && (sv[1] == 'u' || sv[1] == 'o')) + { + auto const base{ (sv[1] == 'u' ? 16 : 8) }; + auto const char_bytes(parse_character_in_base(sv.substr(2), base)); + + if(char_bytes.is_ok()) + { + return object_source_info{ make_box(char_bytes.expect_ok()), + token, + token }; + } + else + { + return err( + error{ token.pos, + fmt::format("Error reading character `{}`: {}", sv, char_bytes.expect_err().error) }); + } + } + return err(error{ token.pos, fmt::format("invalid character literal `{}`", sv) }); } diff --git a/compiler+runtime/src/cpp/jank/runtime/obj/character.cpp b/compiler+runtime/src/cpp/jank/runtime/obj/character.cpp index 7e92ddff6..5aa513c5e 100644 --- a/compiler+runtime/src/cpp/jank/runtime/obj/character.cpp +++ b/compiler+runtime/src/cpp/jank/runtime/obj/character.cpp @@ -3,24 +3,31 @@ namespace jank::runtime { - static native_persistent_string get_literal_from_char(char const ch) + static native_persistent_string get_literal_from_char_bytes(native_persistent_string const &bytes) { - switch(ch) + if(bytes.size() == 1) { - case '\n': - return R"(\newline)"; - case ' ': - return R"(\space)"; - case '\t': - return R"(\tab)"; - case '\b': - return R"(\backspace)"; - case '\f': - return R"(\formfeed)"; - case '\r': - return R"(\return)"; - default: - return fmt::format(R"(\{})", ch); + switch(bytes[0]) + { + case '\n': + return R"(\newline)"; + case ' ': + return R"(\space)"; + case '\t': + return R"(\tab)"; + case '\b': + return R"(\backspace)"; + case '\f': + return R"(\formfeed)"; + case '\r': + return R"(\return)"; + default: + return fmt::format(R"(\{})", bytes[0]); + } + } + else + { + return fmt::format(R"(\{})", bytes); } } @@ -57,7 +64,7 @@ namespace jank::runtime native_persistent_string obj::character::to_code_string() const { - return get_literal_from_char(data[0]); + return get_literal_from_char_bytes(data); } native_hash obj::character::to_hash() const diff --git a/compiler+runtime/test/cpp/jank/read/parse.cpp b/compiler+runtime/test/cpp/jank/read/parse.cpp index 2ff1bfcea..ac7d675ef 100644 --- a/compiler+runtime/test/cpp/jank/read/parse.cpp +++ b/compiler+runtime/test/cpp/jank/read/parse.cpp @@ -193,6 +193,107 @@ namespace jank::read::parse CHECK(r.expect_ok().unwrap().start == lex::token{ 9, 10, lex::token_kind::character, "\\backspace" }); } + + SUBCASE("Hex unicode") + { + SUBCASE("Valid") + { + lex::processor lp{ R"(\u1234 \u5678 \u90ab \ucdef \uABCD \uEFa0)" }; + processor p{ lp.begin(), lp.end() }; + + size_t offset{}; + for(native_persistent_string const &ch : + { "\\u1234", "\\u5678", "\\u90ab", "\\ucdef", "\\uABCD", "\\uEFa0" }) + { + auto const r(p.next()); + CHECK(equal(r.expect_ok().unwrap().ptr, + make_box( + parse_character_in_base(ch.substr(2), 16).expect_ok()))); + + auto const len(ch.size()); + CHECK(r.expect_ok().unwrap().start + == lex::token{ offset, len, lex::token_kind::character, ch }); + CHECK(r.expect_ok().unwrap().end == r.expect_ok().unwrap().start); + + /* +1 for space */ + offset += len + 1; + } + } + + SUBCASE("Invalid length") + { + lex::processor lp{ R"(\u123456 \uabcdef \u12abf5)" }; + processor p{ lp.begin(), lp.end() }; + + for(size_t i{}; i < 3; ++i) + { + auto const r(p.next()); + CHECK(r.is_err()); + } + } + + SUBCASE("Invalid unicode characters") + { + lex::processor lp{ R"(\uabcg \u120x \uza19 \u1Gab)" }; + processor p{ lp.begin(), lp.end() }; + + for(size_t i{}; i < 4; ++i) + { + auto const r(p.next()); + CHECK(r.is_err()); + } + } + } + + SUBCASE("Octal unicode") + { + SUBCASE("Valid") + { + lex::processor lp{ R"(\o012 \o345 \o670)" }; + processor p{ lp.begin(), lp.end() }; + + size_t offset{}; + for(native_persistent_string const &ch : { "\\o012", "\\o345", "\\o670" }) + { + auto const r(p.next()); + CHECK(equal(r.expect_ok().unwrap().ptr, + make_box( + parse_character_in_base(ch.substr(2), 8).expect_ok()))); + + auto const len(ch.size()); + CHECK(r.expect_ok().unwrap().start + == lex::token{ offset, len, lex::token_kind::character, ch }); + CHECK(r.expect_ok().unwrap().end == r.expect_ok().unwrap().start); + + /* +1 for space */ + offset += len + 1; + } + } + + SUBCASE("Invalid length") + { + lex::processor lp{ R"(\o12345677 \o23007673323)" }; + processor p{ lp.begin(), lp.end() }; + + for(size_t i{}; i < 2; ++i) + { + auto const r(p.next()); + CHECK(r.is_err()); + } + } + + SUBCASE("Invalid ocatal character") + { + lex::processor lp{ R"(\o128 \o962 \oAaa \oxf0)" }; + processor p{ lp.begin(), lp.end() }; + + for(size_t i{}; i < 4; ++i) + { + auto const r(p.next()); + CHECK(r.is_err()); + } + } + } } TEST_CASE("String") diff --git a/compiler+runtime/third-party/bdwgc b/compiler+runtime/third-party/bdwgc new file mode 160000 index 000000000..bc13560d3 --- /dev/null +++ b/compiler+runtime/third-party/bdwgc @@ -0,0 +1 @@ +Subproject commit bc13560d331f23906afb6a2a89194ba41460a099 diff --git a/compiler+runtime/third-party/cli11 b/compiler+runtime/third-party/cli11 new file mode 160000 index 000000000..5a03ee583 --- /dev/null +++ b/compiler+runtime/third-party/cli11 @@ -0,0 +1 @@ +Subproject commit 5a03ee58384ce18b6b3de5a2256e18f5ef103633 diff --git a/compiler+runtime/third-party/fmt b/compiler+runtime/third-party/fmt new file mode 160000 index 000000000..4b8e2838f --- /dev/null +++ b/compiler+runtime/third-party/fmt @@ -0,0 +1 @@ +Subproject commit 4b8e2838f0767793e060135f4824c4114e285678 diff --git a/compiler+runtime/third-party/immer b/compiler+runtime/third-party/immer new file mode 160000 index 000000000..df6ef46d9 --- /dev/null +++ b/compiler+runtime/third-party/immer @@ -0,0 +1 @@ +Subproject commit df6ef46d97e1fe81f397015b9aeb32505cef653b diff --git a/compiler+runtime/third-party/libzippp b/compiler+runtime/third-party/libzippp new file mode 160000 index 000000000..28c853872 --- /dev/null +++ b/compiler+runtime/third-party/libzippp @@ -0,0 +1 @@ +Subproject commit 28c8538720030cea0a60622a2b9efe47fa9251ce diff --git a/compiler+runtime/third-party/magic_enum b/compiler+runtime/third-party/magic_enum new file mode 160000 index 000000000..a72a0536c --- /dev/null +++ b/compiler+runtime/third-party/magic_enum @@ -0,0 +1 @@ +Subproject commit a72a0536c716fdef4f029fb43e1fd7e7b3d9ac9b diff --git a/compiler+runtime/vcpkg-triplet/x64-clang-static.cmake b/compiler+runtime/vcpkg-triplet/x64-clang-static.cmake deleted file mode 100644 index 4406f229b..000000000 --- a/compiler+runtime/vcpkg-triplet/x64-clang-static.cmake +++ /dev/null @@ -1,9 +0,0 @@ -set(VCPKG_TARGET_ARCHITECTURE x64) -set(VCPKG_CRT_LINKAGE dynamic) -set(VCPKG_LIBRARY_LINKAGE static) -set(VCPKG_BUILD_TYPE release) - -set(VCPKG_CMAKE_SYSTEM_NAME ${CMAKE_HOST_SYSTEM_NAME}) -#set(VCPKG_CXX_FLAGS "${VCPKG_CXX_FLAGS} -stdlib=libc++") -set(VCPKG_CXX_FLAGS "${VCPKG_CXX_FLAGS}") -set(VCPKG_C_FLAGS "${VCPKG_C_FLAGS}") diff --git a/compiler+runtime/vcpkg.json b/compiler+runtime/vcpkg.json deleted file mode 100644 index 584d0609c..000000000 --- a/compiler+runtime/vcpkg.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "jank", - "version-semver": "0.1.0", - "dependencies": [ - "bdwgc", - "boost-algorithm", - "boost-filesystem", - "boost-smart-ptr", - "boost-variant", - "boost-preprocessor", - "cli11", - "fmt", - "immer", - "libassert", - "libzippp", - "magic-enum", - "readline" - ], - "default-features": [], - "features": { - "tests": { - "description": "Dependencies for testing", - "dependencies": [ - "doctest" - ] - } - } -}