diff --git a/.gitignore b/.gitignore index 7e8ea38a87c731336f4c99a9052fd38adba02cbe..68ec47295083dab2e361efe792ce6d6e857bdb0d 100644 --- a/.gitignore +++ b/.gitignore @@ -19,7 +19,6 @@ build.clang/* # Local configurations .vim/* .vscode/* - -# CCLS styff +.idea/ .ccls*/ .ccls diff --git a/CMakeLists.txt b/CMakeLists.txt index 08e07772c361dad38867ddc85996bf2d591190e9..e9493eb8aa2a25c9baa81a04137228e37fdfbf95 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,45 +11,46 @@ endif() message(STATUS "The installation prefix is ${CMAKE_INSTALL_PREFIX}") message(STATUS "The build type is ${CMAKE_BUILD_TYPE}") -# Don't forget for specific things -if(WIN32) - message(STATUS "You are building on windows, pay attenion to the dependencies") -endif() -if(MSVC OR MSYS OR MINGW) - message(STATUS "You are building with a windows compiler") -elseif(APPLE) - message(STATUS "You are building on MacOS X") -elseif(UNIX AND NOT APPLE) - message(STATUS "You are building on Linux, FreeBSD or any other toaster OS") -else() - message(FATAL_ERROR "The OS is not recognized") -endif() - set(CMAKE_POSITION_INDEPENDENT_CODE ON) # Pass -fPIC set(CMAKE_COLOR_MAKEFILE ON) set(CMAKE_COLOR_DIAGNOSTICS ON) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # Always to that... set(THREADS_PREFER_PTHREAD_FLAG ON) # Pthread ftw +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +# Do the thing with UPX to try to reduce the size of large executables +option(USE_UPX "Use upx to reduce executable size [OFF,ON,AUTO]" AUTO) +find_program(UPX upx DOC "Use upx to compress executables, optional") +if(UPX STREQUAL "UPX-NOTFOUND") + if(USE_UPX STREQUAL "ON") + message(ERROR "The upx executable was not found (USE_UPX=ON)") + else() + message(STATUS "The upx executable was not found, don't compress executable (USE_UPX=${USE_UPX})") + macro(upx_pack TARGET EXEC) + endmacro() + endif() +elseif((USE_UPX STREQUAL "ON") OR (USE_UPX STREQUAL "AUTO")) + message(STATUS "The ${UPX} program will be used to compress the built binaries (USE_UPX=${USE_UPX})") + macro(upx_pack TARGET EXEC) + add_custom_command(TARGET "${TARGET}" POST_BUILD USES_TERMINAL + COMMAND ${UPX} -qt "${EXEC}" || ${UPX} --best --lzma "${EXEC}" + ) + endmacro() +else() + message(STATUS "The upx executable was found, but we won't use it (USE_UPX=OFF)") + macro(upx_pack TARGET EXEC) + endmacro() +endif() -# For Qt -set(CMAKE_AUTOUIC ON) -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) - -# Find Qt dependencies -find_package(Qt6 REQUIRED COMPONENTS - Widgets - OpenGL - OpenGLWidgets -) - -# Find others dependencies -find_library(AVCODEC_LIBRARY avcodec 4.0 REQUIRED) -find_library(AVUTIL_LIBRARY avutil 4.0 REQUIRED) -find_library(SWRESAMPLE_LIBRARY swresample REQUIRED) -find_library(AVFORMAT_LIBRARY avformat REQUIRED) -find_library(MPV_LIBRARY mpv REQUIRED) -find_package( OpenMP REQUIRED) +# Dependencies +find_package(Qt6 COMPONENTS Widgets OpenGL OpenGLWidgets REQUIRED) +find_library(AVCODEC_LIBRARY avcodec 4.0 REQUIRED) +find_library(AVUTIL_LIBRARY avutil 4.0 REQUIRED) +find_library(SWRESAMPLE_LIBRARY swresample REQUIRED) +find_library(AVFORMAT_LIBRARY avformat REQUIRED) +find_library(MPV_LIBRARY mpv REQUIRED) # Grab all files file(GLOB_RECURSE Vivy_SRC CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cc") @@ -59,6 +60,18 @@ if(APPLE) endif() set(PROJECT_SOURCES ${Vivy_SRC} ${Vivy_INC} ${Vivy_APPLE_SRC}) +# The Rust lib +add_custom_target(libvivy + COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/utils/scripts/build-libvivy.bash" + "${CMAKE_CURRENT_BINARY_DIR}" ${CARGO_RELEASE_BUILD} + BYPRODUCTS vvcc libvivy.a + COMMENT "Rust library to embed into Vivy" + USES_TERMINAL +) +upx_pack(libvivy "${CMAKE_CURRENT_BINARY_DIR}/vvcc") +set_property(TARGET libvivy PROPERTY ADDITIONAL_CLEAN_FILES "vvcc;libvivy.a") +install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/vvcc" DESTINATION bin) + # Add the Vivy executable qt_add_executable(Vivy MANUAL_FINALIZATION @@ -66,6 +79,9 @@ qt_add_executable(Vivy rsc/VivyRessources.qrc ) qt_set_finalizer_mode(Vivy ENABLE MODES static_plugins) +add_dependencies(Vivy libvivy) +upx_pack(Vivy "${CMAKE_CURRENT_BINARY_DIR}/Vivy") +install(TARGETS Vivy RUNTIME DESTINATION bin) set(Vivy_PRECOMPILED_INC PRIVATE src/PreCompiledHeaders.hh) @@ -83,7 +99,7 @@ target_link_libraries(Vivy PRIVATE ${AVUTIL_LIBRARY}) target_link_libraries(Vivy PRIVATE ${SWRESAMPLE_LIBRARY}) target_link_libraries(Vivy PRIVATE ${AVFORMAT_LIBRARY}) target_link_libraries(Vivy PRIVATE ${MPV_LIBRARY}) -target_link_libraries(Vivy PRIVATE OpenMP::OpenMP_CXX) +target_link_libraries(Vivy PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/libvivy.a) # Headers related things target_include_directories(Vivy PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) @@ -145,10 +161,12 @@ if (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") -Wno-c++98-compat-pedantic -Wno-c++98-c++11-c++14-c++17-compat-pedantic -Wno-c++20-compat + -Wno-unsafe-buffer-usage # Different versions of MPV... -Wno-switch-enum + -Wno-unknown-warning-option -Wno-reserved-identifier -Wno-extra-semi-stmt -Wno-redundant-parens diff --git a/README.md b/README.md index 4e99f86760827e6f64af02a89c57357f1996eaf1..ac7fa9edb6cb8133b4870cb8db227297f2696b45 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,14 @@ ## Prerequisites -- [rust](https://www.rust-lang.org) compiler with version >= 1.70 +- [rust](https://www.rust-lang.org) compiler with version >= 1.77 - [cmake](https://cmake.org/) at least the version 3.18 - C++ compiler with [C++17 support](https://en.cppreference.com/w/cpp/17) - [mpv](https://mpv.io/) development library - [Qt6](https://www.qt.io/) development library: QtCore, QtWidgets, QtOpenGL, QtOpenGLWidgets. -- The AV libraries: libavutil libavcodec libavformat +- The AV libraries in e recent version: libavutil libavcodec libavformat - [cbindgen](https://github.com/mozilla/cbindgen): `cargo install --force cbindgen` +- [cargo-insta](https://insta.rs/docs/cli/): `cargo install --force cargo-insta` - Some unix utils, the `jq` binary, the `bash` shell. ## Build @@ -16,22 +17,41 @@ Simply use cmake to build in another folder of the source folder: ```bash +# Prepare, compile and install cmake -Bbuild -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_INSTALL_PREFIX=$HOME/.local -GNinja ninja -Cbuild ninja -Cbuild install ``` -To do a debug build, use the debug switch with cmake: `-DCMAKE_BUILD_TYPE=Debug`. Note that the last -option is here to generate the `compile_commands.json`, you should copy it at the root of the -project. +To do a debug build, use the debug switch with cmake: `-DCMAKE_BUILD_TYPE=Debug`. -## Licence +To only build and use vvcc, you may use the following commands: + +```bash +cd src/Rust + +# Build and install, if vvcc is too big, you can use upx +cargo install --path vvs_cli -The C++ part of this software is licenced under the LGPL v3.0 or latter. The Rust part is under the -MIT license. +# Man pages +mkdir -p $HOME/.local/share/man/man1/ +vvcc --manpage > $HOME/.local/share/man/man1/vvcc.1 ---- +# Shell completion scripts +mkdir -p $HOME/.local/share/completion/ +vvcc --shell bash > $HOME/.local/share/bash-completion/completions/vvcc +vvcc --shell zsh > $HOME/.local/share/zsh/site-functions/_vvcc + +# View the dependencies +cargo install cargo-depgraph +cargo depgraph --build-deps --dedup-transitive-deps | dot -Tpdf | zathura - +``` + +## Licence -# TODO! +- The C++ part of this software is licenced under [the LGPL v3.0 or latter](/LICENSE) +- The Rust part (Vivy Script) is under the [MIT license](/src/Rust/LICENSE.txt) +- The NotoSans fonts are distributed using the [OFL licence](/rsc/licence/OFL-1.1) +- Some parts of the Rust folder (vvs_parser, vvs_parser_derive) are under the + [MPL-2.0](/src/Rust/full_moon/LICENSE.txt) -- Use the rust things for the ASS instead of the C++ thing. diff --git a/TOFIX.md b/TOFIX.md index b98321dd639ed0b461da4269617be0fc1fc1e942..dd353838043c7c88b4247f349335d0a529fe9ab9 100644 --- a/TOFIX.md +++ b/TOFIX.md @@ -1,6 +1,14 @@ +# MISC + - [ ] Save file: do not error on save = name - [ ] Load Ass: do not fail on Default style not defined - [ ] Save file: add .vivy extension by default -- [ ] Save/Load file: use the rust thing, also find a way to populate the properties with that thing - [ ] Problems with the mouse with video/ass/audio sub-documents - [ ] Some videos won't embed with the OpenGL thing... + +# Script Specific + +- [ ] We can't have recursive types for containers, for example we can't have a table that contains + tables, or a sequence that contains sequences. We must enforce that +- [ ] Enforce variant declaration correctness (ints or floats, maybe only one string that is always + that last thing) diff --git a/rsc/VivyRessources.qrc b/rsc/VivyRessources.qrc index 8f32cedb7cdd095af365c96baba55e470eeacaeb..53700b1d440c6e383b871431f710d3a6e44e6579 100644 --- a/rsc/VivyRessources.qrc +++ b/rsc/VivyRessources.qrc @@ -9,10 +9,7 @@ <!-- Fonts, FiraCode is OFL-1.1, NotoSans is APACHE-2.0 --> <file>fonts/FiraCode-Regular.ttf</file> <file>fonts/FiraCode-Bold.ttf</file> - <file>fonts/NotoSans-Bold.ttf</file> - <file>fonts/NotoSans-Italic.ttf</file> <file>fonts/NotoSans-Regular.ttf</file> - <file>fonts/NotoSans-BoldItalic.ttf</file> <!-- Licences --> <file>licence/LGPL-V2.0</file> diff --git a/rsc/fonts/NotoSans-Bold.ttf b/rsc/fonts/NotoSans-Bold.ttf deleted file mode 100644 index 54ad879b41b5db8b21dca1aa00a2d474697e7bf0..0000000000000000000000000000000000000000 Binary files a/rsc/fonts/NotoSans-Bold.ttf and /dev/null differ diff --git a/rsc/fonts/NotoSans-BoldItalic.ttf b/rsc/fonts/NotoSans-BoldItalic.ttf deleted file mode 100644 index 530a82835d3b0b07d4b56cfae9ebfa5e02a9129e..0000000000000000000000000000000000000000 Binary files a/rsc/fonts/NotoSans-BoldItalic.ttf and /dev/null differ diff --git a/rsc/fonts/NotoSans-Italic.ttf b/rsc/fonts/NotoSans-Italic.ttf deleted file mode 100644 index 27ff1ed60a9afc0e6a4d7604abf6d9ad307ef7fd..0000000000000000000000000000000000000000 Binary files a/rsc/fonts/NotoSans-Italic.ttf and /dev/null differ diff --git a/src/Rust/Cargo.lock b/src/Rust/Cargo.lock index 438b9cce5e2c3acb9b7aecd42b68361435637657..724c516d66202c5a162160f278bac90c7d2ebc7d 100644 --- a/src/Rust/Cargo.lock +++ b/src/Rust/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "ab_glyph" -version = "0.2.22" +version = "0.2.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1061f3ff92c2f65800df1f12fc7b4ff44ee14783104187dd04dfee6f11b0fd2" +checksum = "79faae4620f45232f599d9bc7b290f88247a0834162c4495ab2f02d60004adfb" dependencies = [ "ab_glyph_rasterizer", "owned_ttf_parser", @@ -20,9 +20,9 @@ checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" [[package]] name = "ahash" -version = "0.8.6" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "once_cell", @@ -32,42 +32,118 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "allocator-api2" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.4.1" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "bstr" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytecount" -version = "0.6.7" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" + +[[package]] +name = "cast" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + +[[package]] +name = "cbindgen" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da6bc11b07529f16944307272d5bd9b22530bc7d05751717c9d416586cedab49" +dependencies = [ + "clap 3.2.25", + "heck 0.4.1", + "indexmap 1.9.3", + "log", + "proc-macro2", + "quote", + "serde", + "serde_json", + "syn 1.0.109", + "tempfile", + "toml 0.5.11", +] + +[[package]] +name = "cc" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "504bdec147f2cc13c8b57ed9401fd8a147cc66b67ad5cb241394244f2c947549" [[package]] name = "cfg-if" @@ -75,11 +151,53 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + +[[package]] +name = "clap" +version = "3.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" +dependencies = [ + "atty", + "bitflags 1.3.2", + "clap_lex 0.2.4", + "indexmap 1.9.3", + "strsim 0.10.0", + "termcolor", + "textwrap", +] + [[package]] name = "clap" -version = "4.4.7" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b" +checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc" dependencies = [ "clap_builder", "clap_derive", @@ -87,53 +205,203 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.7" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663" +checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99" dependencies = [ "anstyle", - "clap_lex", - "strsim", + "clap_lex 0.7.2", + "strsim 0.11.1", "terminal_size", ] [[package]] name = "clap_complete" -version = "4.4.4" +version = "4.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bffe91f06a11b4b9420f62103854e90867812cd5d01557f853c5ee8e791b12ae" +checksum = "a8670053e87c316345e384ca1f3eba3006fc6355ed8b8a1140d104e109e3df34" dependencies = [ - "clap", + "clap 4.5.13", ] [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", - "syn", + "syn 2.0.72", ] [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "clap_lex" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "clap_mangen" -version = "0.2.15" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3be86020147691e1d2ef58f75346a3d4d94807bfc473e377d52f09f0f7d77f7" +checksum = "f17415fd4dfbea46e3274fcd8d368284519b358654772afb700dc2e8d2b24eeb" dependencies = [ - "clap", + "clap 4.5.13", "roff", ] +[[package]] +name = "codespan" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3362992a0d9f1dd7c3d0e89e0ab2bb540b7a95fea8cd798090e758fda2899b5e" +dependencies = [ + "codespan-reporting", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "console" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "criterion" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" +dependencies = [ + "anes", + "cast", + "ciborium", + "clap 4.5.13", + "criterion-plot", + "is-terminal", + "itertools", + "num-traits", + "once_cell", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +dependencies = [ + "cast", + "itertools", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "derive_more" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "syn 2.0.72", + "unicode-xid", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + [[package]] name = "equivalent" version = "1.0.1" @@ -142,19 +410,54 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.5" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + +[[package]] +name = "globset" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", ] [[package]] name = "hashbrown" -version = "0.14.2" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash", "allocator-api2", @@ -166,105 +469,260 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + [[package]] name = "indexmap" -version = "2.0.2" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.14.5", ] +[[package]] +name = "insta" +version = "1.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "810ae6042d48e2c9e9215043563a58a80b877bc863228a74cf10c49d4620a6f5" +dependencies = [ + "console", + "globset", + "lazy_static", + "linked-hash-map", + "serde", + "similar", + "walkdir", +] + +[[package]] +name = "is-terminal" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +dependencies = [ + "hermit-abi 0.3.9", + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "libc" -version = "0.2.149" +version = "0.2.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[package]] +name = "linked-hash-map" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.4.10" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "llvm-sys" +version = "181.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d255b36907416971229095a8465c0b69f5f1c6fb8421b6dcdbb64eb47e1be90" +dependencies = [ + "anyhow", + "cc", + "lazy_static", + "libc", + "regex-lite", + "semver", +] [[package]] name = "log" -version = "0.4.20" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "memchr" -version = "2.6.4" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] -name = "minimal-lexical" -version = "0.2.1" +name = "oorandom" +version = "11.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" [[package]] -name = "nom" -version = "7.1.3" +name = "os_str_bytes" +version = "6.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" + +[[package]] +name = "owned_ttf_parser" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490d3a563d3122bf7c911a59b0add9389e5ec0f5f0c3ac6b91ff235a0e6a7f90" dependencies = [ - "memchr", - "minimal-lexical", + "ttf-parser", ] [[package]] -name = "nom_locate" -version = "4.2.0" +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "plotters" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e3c83c053b0713da60c5b8de47fe8e494fe3ece5267b2f23090a07a053ba8f3" +checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" dependencies = [ - "bytecount", - "memchr", - "nom", + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", ] [[package]] -name = "once_cell" -version = "1.18.0" +name = "plotters-backend" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" [[package]] -name = "owned_ttf_parser" -version = "0.19.0" +name = "plotters-svg" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "706de7e2214113d63a8238d1910463cfce781129a6f263d13fdb09ff64355ba4" +checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" dependencies = [ - "ttf-parser", + "plotters-backend", ] [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "regex" -version = "1.10.2" +version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" dependencies = [ "aho-corasick", "memchr", @@ -274,65 +732,120 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", "regex-syntax", ] +[[package]] +name = "regex-lite" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" + [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "roff" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316" +checksum = "88f8660c1ff60292143c98d08fc6e2f654d722db50410e3f3797d40baaf9d8f3" [[package]] name = "rustix" -version = "0.38.21" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", ] +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + [[package]] name = "serde" -version = "1.0.190" +version = "1.0.205" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" +checksum = "e33aedb1a7135da52b7c21791455563facbbcc43d0f0f66165b42c21b3dfb150" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.190" +version = "1.0.205" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" +checksum = "692d6f5ac90220161d6774db30c662202721e64aed9058d2c394f451261420c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.72", +] + +[[package]] +name = "serde_json" +version = "1.0.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da" +dependencies = [ + "indexmap 2.3.0", + "itoa", + "memchr", + "ryu", + "serde", ] [[package]] name = "serde_spanned" -version = "0.6.4" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" +dependencies = [ + "serde", +] + +[[package]] +name = "similar" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e" + +[[package]] +name = "smol_str" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80" +checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" dependencies = [ "serde", ] @@ -343,17 +856,56 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" -version = "2.0.38" +version = "2.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "tempfile" +version = "3.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" +dependencies = [ + "cfg-if", + "fastrand", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + [[package]] name = "terminal_size" version = "0.3.0" @@ -361,34 +913,59 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" dependencies = [ "rustix", - "windows-sys", + "windows-sys 0.48.0", ] +[[package]] +name = "textwrap" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" + [[package]] name = "thiserror" -version = "1.0.50" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.50" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.72", +] + +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", ] [[package]] name = "toml" -version = "0.8.5" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "toml" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3efaf127c78d5339cc547cce4e4d973bd5e4f56e949a06d091c082ebeef2f800" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", "serde_spanned", @@ -398,20 +975,20 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.20.5" +version = "0.22.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "782bf6c2ddf761c1e7855405e8975472acf76f7f36d0d4328bd3b7a2fae12a85" +checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" dependencies = [ - "indexmap", + "indexmap 2.3.0", "serde", "serde_spanned", "toml_datetime", @@ -420,9 +997,9 @@ dependencies = [ [[package]] name = "ttf-parser" -version = "0.19.2" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49d64318d8311fc2668e48b63969f4343e0a85c4a109aa8460d6672e364b8bd1" +checksum = "5be21190ff5d38e8b4a2d3b6a3ae57f612cc39c96e83cedeaf7abc338a8bac4a" [[package]] name = "unicode-ident" @@ -432,15 +1009,27 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-segmentation" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + +[[package]] +name = "unicode-width" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "vvs_ass" @@ -461,14 +1050,34 @@ name = "vvs_cli" version = "0.5.0" dependencies = [ "anyhow", - "clap", + "clap 4.5.13", "clap_complete", "clap_mangen", "log", "serde", "thiserror", - "toml", + "toml 0.8.19", + "vvs_ass", + "vvs_codegen", "vvs_font", + "vvs_llvm", + "vvs_parser", + "vvs_runtime", + "vvs_utils", +] + +[[package]] +name = "vvs_codegen" +version = "0.5.0" +dependencies = [ + "anyhow", + "hashbrown 0.14.5", + "log", + "serde", + "serde_json", + "vvs_lang", + "vvs_llvm", + "vvs_runtime_types", "vvs_utils", ] @@ -487,41 +1096,250 @@ name = "vvs_lang" version = "0.5.0" dependencies = [ "anyhow", - "hashbrown", + "derive_more", + "hashbrown 0.14.5", "log", - "nom", - "nom_locate", + "paste", "regex", "serde", "thiserror", + "toml 0.8.19", + "vvs_parser", "vvs_utils", ] +[[package]] +name = "vvs_lib" +version = "0.5.0" +dependencies = [ + "cbindgen", + "hashbrown 0.14.5", + "log", + "serde", + "serde_json", + "vvs_ass", +] + +[[package]] +name = "vvs_llvm" +version = "0.5.0" +dependencies = [ + "anyhow", + "llvm-sys", + "log", +] + +[[package]] +name = "vvs_parser" +version = "0.5.0" +dependencies = [ + "anyhow", + "bytecount", + "cfg-if", + "codespan", + "codespan-reporting", + "criterion", + "derive_more", + "hashbrown 0.14.5", + "insta", + "log", + "paste", + "serde", + "smol_str", + "termcolor", + "vvs_parser_derive", +] + +[[package]] +name = "vvs_parser_derive" +version = "0.5.0" +dependencies = [ + "indexmap 2.3.0", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "vvs_procmacro" version = "0.5.0" dependencies = [ + "anyhow", "proc-macro2", "quote", - "syn", + "syn 2.0.72", +] + +[[package]] +name = "vvs_runtime" +version = "0.5.0" +dependencies = [ + "anyhow", + "log", + "serde", + "serde_json", + "vvs_llvm", + "vvs_runtime_types", + "vvs_utils", +] + +[[package]] +name = "vvs_runtime_types" +version = "0.5.0" +dependencies = [ + "anyhow", + "hashbrown 0.14.5", + "log", + "serde", + "serde_json", + "unicode-segmentation", + "vvs_ass", + "vvs_lang", + "vvs_llvm", + "vvs_procmacro", + "vvs_utils", ] [[package]] name = "vvs_utils" version = "0.5.0" dependencies = [ + "anyhow", "log", "serde", "thiserror", ] +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.72", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.72", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-sys" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -530,13 +1348,29 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -545,67 +1379,115 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + [[package]] name = "winnow" -version = "0.5.17" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3b801d0e0a6726477cc207f60162da452f3a95adb368399bef20a946e06f65c" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" dependencies = [ "memchr", ] [[package]] name = "zerocopy" -version = "0.7.15" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81ba595b9f2772fbee2312de30eeb80ec773b4cb2f1e8098db024afadda6c06f" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.15" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "772666c41fb6dceaf520b564b962d738a8e1a83b41bd48945f50837aed78bb1d" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.72", ] diff --git a/src/Rust/Cargo.toml b/src/Rust/Cargo.toml index aeba7e5ad0f4da0a66977cef64410c516894ec9d..840c7a05919cca5327972a63b104b142afae2e09 100644 --- a/src/Rust/Cargo.toml +++ b/src/Rust/Cargo.toml @@ -1,54 +1,105 @@ [workspace] resolver = "2" -members = [ - "vvs_cli", - "vvs_ass", - "vvs_font", - "vvs_lang", - "vvs_utils", - "vvs_procmacro", -] +members = ["vvs_*"] + [workspace.package] version = "0.5.0" -authors = ["Maël MARTIN"] -description = "The V5 of the Vivy Script utility to manipulate in an easy way ASS files" -edition = "2021" -license = "MIT" +authors = [ + "Maëlle Martin <maelle.martin@proton.me>", + "Kampfkarren <kampfkarren@gmail.com>", +] +description = "The V5 of the Vivy Script utility to manipulate in an easy way ASS files" +edition = "2021" +license = "MIT" +rust-version = "1.76" + + +[profile.release] +debug = false +opt-level = 3 +panic = "abort" +strip = true +codegen-units = 1 +lto = true + + +[profile.dev] +debug = true +opt-level = "s" + [workspace.dependencies] +# Local dependencies +vvs_parser_derive = { path = "vvs_parser_derive" } +vvs_parser = { path = "vvs_parser" } +vvs_procmacro = { path = "vvs_procmacro" } +vvs_utils = { path = "vvs_utils" } +vvs_font = { path = "vvs_font" } +vvs_ass = { path = "vvs_ass" } +vvs_lang = { path = "vvs_lang" } +vvs_runtime = { path = "vvs_runtime" } +vvs_codegen = { path = "vvs_codegen" } +vvs_llvm = { path = "vvs_llvm" } +vvs_runtime_types = { path = "vvs_runtime_types" } + # Utils -thiserror = "1" -anyhow = "1" -paste = "1" -log = "0.4" -bitflags = { version = "2", default-features = false } -unicode-segmentation = "1" -hashbrown = "0.14" +bytecount = "*" +cfg-if = "*" +paste = "*" +indexmap = "*" +thiserror = "*" +anyhow = "*" +log = "*" +hashbrown = "*" +cbindgen = "*" +termcolor = "*" +derive_more = { version = "*", features = ["full"] } +smol_str = { version = "*", features = ["serde"] } +bitflags = { version = "*", default-features = false } # Parsing -regex = { version = "1", default-features = false, features = ["std"] } -nom = { version = "7", default-features = false, features = ["std"] } -nom_locate = { version = "4", default-features = false, features = ["std"] } +unicode-segmentation = "*" +regex = { version = "*", default-features = false, features = ["std"] } # SerDe -toml = { version = "0.8", default-features = false, features = [ +serde_json = { version = "*", default-features = false, features = [ + "std", + "preserve_order", +] } +serde = { version = "*", default-features = false, features = [ + "std", + "rc", + "derive", +] } +toml = { version = "*", default-features = false, features = [ "parse", "display", ] } -serde = { version = "1", default-features = false, features = [ + +# ProcMacros +quote = "*" +proc-macro2 = "*" + +# FONTS +ttf-parser = { version = "*" } +ab_glyph = { version = "*" } + +# CLI +clap_mangen = "*" # Could be replace by something crafter by hand… +clap_complete = "*" +clap = { version = "*", default-features = false, features = [ + "usage", + "help", "std", + "suggestions", + "error-context", "derive", + "wrap_help", ] } -[profile.release] -strip = true -debug = false -lto = true -opt-level = "z" -codegen-units = 1 -panic = "abort" - -[profile.dev] -debug = true -opt-level = "s" +# FOR FULL-MOON TESTS +codespan = "*" +codespan-reporting = "*" +criterion = "*" +insta = { version = "*", features = ["glob", "yaml"] } diff --git a/src/Rust/README.md b/src/Rust/README.md deleted file mode 100644 index 3337f0bd3339cfea7d9f35318bf790457238cdd6..0000000000000000000000000000000000000000 --- a/src/Rust/README.md +++ /dev/null @@ -1,57 +0,0 @@ -# Vivy Script -The V4 of the Vivy Script utility to manipulate in an easy way ASS files. - -# How to build and install -Like any rust project, simply run: - - cargo build --release - cargo install --path vvs_cli - vvcc --help - -If you want to test it, from the root of the project you may replace any call -to `vvcc` by `cargo run --bin vvcc --`. - -# Misc -## Manpage -To get the `vvcc` manpage, just run: - - vvcc --manpage | man -l - - -To install it, you may run the following commands: - - mkdir -p $HOME/.local/share/man/man1/ - vvcc --manpage > $HOME/.local/share/man/man1/vvcc.1 - man vvcc - -## Shell completion -To get the completion scripts to source you can use the following commands. You -can then source those files to get the completion working with your shell. - - mkdir -p $HOME/.local/share/completion/ - vvcc --shell bash > $HOME/.local/share/bash-completion/completions/vvcc - vvcc --shell zsh > $HOME/.local/share/zsh/site-functions/_vvcc - -To get the completion working with the system, you can use the following commands: - - vvcc --shell bash > /usr/local/share/bash-completion/completions/vvcc - vvcc --shell zsh > /usr/local/share/zsh/site-functions/_vvcc - -To visualize the dependency graph of VivyScript, use the command: - - cargo install cargo-depgraph - cargo depgraph --build-deps --dedup-transitive-deps | dot -Tpdf | zathura - - -## To test the project -The unit-tests can be ran on the project by running `cargo test`. The -integration tests and the unit-tests can be run together by using pcvs in the -[tests](tests) folder: - - pip install pcvs -- Install PCVS - (cd tests && pcvs run) -- Run in the correct folder - -You can also install PCVS by cloning the project and running `pip install .` -from its root. - -# Licence -- The VVS project is under the MIT licence -- The NotoSans fonts are distributed using the [OFL licence](vvs_font/fonts/NotoSans-LICENCE-OFL.txt) diff --git a/src/Rust/VVLib.h b/src/Rust/VVLib.h new file mode 100644 index 0000000000000000000000000000000000000000..7dcc900cb3ab67f9bb9d1ea35716c60692000f9a --- /dev/null +++ b/src/Rust/VVLib.h @@ -0,0 +1,187 @@ +/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */ + +#pragma once + +/* Generated with cbindgen:0.26.0 */ + +#include <inttypes.h> + +#ifdef __cplusplus +namespace VVLib { +namespace C { +#endif // __cplusplus + +/** + * Wraps the container that holds all the content of the ASS file / Vivy file. + */ +typedef struct ASSContainer ASSContainer; + +/** + * Wraps a line in an ASS file. + */ +typedef struct ASSLine ASSLine; + +/** + * Type used to describe an ASS style. + */ +typedef struct ASSStyle ASSStyle; + +/** + * Wraps syllabes, contained in lines in ASS files. + */ +typedef struct ASSSyllabe ASSSyllabe; + +/** + * Represents a string slice, the user may not modify this slice, never! Note that the string is + * not null terminated and may contains null bytes in it, use the len attribute to get the length + * of this string and convert it to your linking. + * + * # Safety + * Note that you must always put unicode inside a string slice! + */ +typedef struct StringSlice +{ + uintptr_t len; + const char *str; +} StringSlice; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * Get the number of lines in the container. + */ +int32_t ASSContainerGetLinesCount(const struct ASSContainer *this_); + +/** + * Get the number of syllabes in the line. + */ +int32_t ASSLineGetSyllabesCount(const struct ASSLine *this_); + +/** + * Get a line by its number in the container. + */ +struct ASSLine *ASSContainerGetLineAt(struct ASSContainer *this_, int32_t idx); + +/** + * Get a syllabe in a line by its index. + */ +struct ASSSyllabe *ASSLineGetSyllabeAt(struct ASSLine *this_, int32_t idx); + +/** + * Tells whever a line is commented or not. + */ +bool ASSLineIsCommented(const struct ASSLine *this_); + +/** + * Gets the style of the line, or 'Default' if it was not found/specified. + */ +struct StringSlice ASSLineGetStyle(const struct ASSLine *this_); + +/** + * Get the content of a syllabe. + */ +struct StringSlice ASSSyllabeGetContent(const struct ASSSyllabe *this_); + +/** + * Get the duration of a syllabe. + */ +int32_t ASSSyllabeGetDuration(const struct ASSSyllabe *this_); + +/** + * Get the start of a syllabe. + */ +int32_t ASSSyllabeGetStartTime(const struct ASSSyllabe *this_); + +/** + * Get the end time of a syllabe. + */ +int32_t ASSSyllabeGetFiniTime(const struct ASSSyllabe *this_); + +/** + * Set the duration of a syllabe. + */ +void ASSSyllabeSetDuration(struct ASSSyllabe *this_, int32_t duration); + +/** + * Set the start of a syllabe. + */ +void ASSSyllabeSetStartTime(struct ASSSyllabe *this_, int32_t time); + +/** + * Set the end of a syllabe. + */ +void ASSSyllabeSetFiniTime(struct ASSSyllabe *this_, int32_t time); + +/** + * Load the ASS from a file, returns nullptr if an error was encountred. + */ +struct ASSContainer *ASSContainerFromFile(char *path); + +/** + * Get a style out of the container by its name. + */ +struct ASSStyle *ASSContainerGetStyleByName(struct ASSContainer *this_, struct StringSlice name); + +/** + * Get the name of a style by its position. + */ +struct StringSlice ASSContainerGetStyleNameAt(const struct ASSContainer *this_, int32_t idx); + +/** + * Get the number of styles in the container. + */ +int32_t ASSContainerGetStylesCount(const struct ASSContainer *this_); + +/** + * Set the start time of the line. + */ +void ASSLineSetStartTime(struct ASSLine *this_, int32_t time); + +/** + * Set the end time of a line. + */ +void ASSLineSetFiniTime(struct ASSLine *this_, int32_t time); + +/** + * Get the duration of a line. + */ +int32_t ASSLineGetDuration(const struct ASSLine *this_); + +/** + * Set the duration of a line. + */ +void ASSLineSetDuration(struct ASSLine *this_, int32_t duration); + +/** + * Get the start time of a line. + */ +int32_t ASSLineGetStartTime(const struct ASSLine *this_); + +/** + * Get the end time of a line. + */ +int32_t ASSLineGetFiniTime(const struct ASSLine *this_); + +/** + * Drop the container. It is file to pass a null pointer to this function. + */ +void ASSContainerDrop(struct ASSContainer *this_); + +/** + * Get the name of the style. + * + * # Safety + * It is up to the user to ensure that the style is not dropped before the returned pointer. + */ +struct StringSlice ASSStyleGetName(const struct ASSStyle *this_); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +#ifdef __cplusplus +} // namespace C +} // namespace VVLib +#endif // __cplusplus diff --git a/src/Rust/VVLib.hh b/src/Rust/VVLib.hh new file mode 100644 index 0000000000000000000000000000000000000000..93ab3c44189bfa2856d0060bdcd998d6dff73177 --- /dev/null +++ b/src/Rust/VVLib.hh @@ -0,0 +1,123 @@ +/// This file was hand-written to wrap the generated C ABI into a C++ wrapper. + +#include "VVLib.h" + +#include <algorithm> +#include <string> +#include <string_view> + +namespace VVLib +{ +class ASSContainer; +class ASSLine; +class ASSSyllabe; + +/// ASSSyllabe modelize each syllabe of each line in the ASS file. +class ASSSyllabe { + C::ASSSyllabe *const self; + friend ASSLine; + + ASSSyllabe(C::ASSSyllabe *const zelf) noexcept + : self(zelf) + { + } + +public: + const std::string_view content() const noexcept + { + const C::StringSlice slice = C::ASSSyllabeGetContent(self); + return std::string_view(slice.str, slice.len); + } + char operator[](int i) noexcept { return content()[static_cast<size_t>(i)]; } + char operator[](int i) const noexcept { return content()[static_cast<size_t>(i)]; } + + void set_duration(int dur) noexcept { C::ASSSyllabeSetDuration(self, dur); } + void set_start(int start) noexcept { C::ASSSyllabeSetStartTime(self, start); } + void set_fini(int fini) noexcept { C::ASSSyllabeSetFiniTime(self, fini); } + int duration() const noexcept { return C::ASSSyllabeGetDuration(self); } + int start() const noexcept { return C::ASSSyllabeGetStartTime(self); } + int fini() const noexcept { return C::ASSSyllabeGetFiniTime(self); } +}; + +/// ASSLine modelize each line of an ASS file. +class ASSLine { + C::ASSLine *const self; + friend ASSContainer; + + ASSLine(C::ASSLine *const zelf) noexcept + : self(zelf) + { + } + +public: + int syllabes_count() const noexcept { return C::ASSLineGetSyllabesCount(self); } + ASSSyllabe operator[](int i) noexcept { return syllabe_at(i); } + const ASSSyllabe operator[](int i) const noexcept { return syllabe_at(i); } + const ASSSyllabe syllabe_at(int i) const noexcept + { + return const_cast<ASSLine *>(this)->syllabe_at(i); + } + ASSSyllabe syllabe_at(int i) noexcept + { + return ASSSyllabe(C::ASSLineGetSyllabeAt(self, std::clamp(i, 0, this->syllabes_count()))); + } + + bool is_commented() const noexcept { return C::ASSLineIsCommented(self); } + const std::string_view style() const + { + const C::StringSlice slice = C::ASSLineGetStyle(self); + return std::string_view(slice.str, slice.len); + } + + void set_start(int start) noexcept { C::ASSLineSetStartTime(self, start); } + void set_fini(int fini) noexcept { C::ASSLineSetFiniTime(self, fini); } + void set_duration(int dur) noexcept { C::ASSLineSetDuration(self, dur); } + int start() const noexcept { return C::ASSLineGetStartTime(self); } + int fini() const noexcept { return C::ASSLineGetFiniTime(self); } + int duration() const noexcept { return C::ASSLineGetDuration(self); } +}; + +/// The container wraps everything around an ASS file. +class ASSContainer { + C::ASSContainer *const self; + + ASSContainer(const char *path) noexcept + : self(C::ASSContainerFromFile(const_cast<char *>(path))) + { + } + +public: + ~ASSContainer() noexcept { C::ASSContainerDrop(self); } + + static ASSContainer from_file(const char *path) noexcept { return ASSContainer(path); } + static ASSContainer from_file(std::string path) noexcept { return from_file(path.c_str()); } + static ASSContainer from_file(std::string_view path) noexcept + { + return from_file(std::string(path)); + } + + int styles_count() const noexcept { return C::ASSContainerGetStylesCount(self); } + C::ASSStyle *style(std::string_view name) const noexcept + { + C::StringSlice style{ .len = name.length(), .str = name.data() }; + return C::ASSContainerGetStyleByName(self, style); + } + std::string_view style(int idx) const noexcept + { + const C::StringSlice slice = C::ASSContainerGetStyleNameAt(self, idx); + return std::string_view(slice.str, slice.len); + } + + int lines_count() const noexcept { return C::ASSContainerGetLinesCount(self); } + ASSLine operator[](int i) noexcept { return line_at(i); } + const ASSLine operator[](int i) const noexcept { return line_at(i); } + const ASSLine line_at(int i) const noexcept + { + return const_cast<ASSContainer *>(this)->line_at(i); + } + ASSLine line_at(int i) noexcept + { + return ASSLine(C::ASSContainerGetLineAt(self, std::clamp(i, 0, this->lines_count()))); + } +}; +} diff --git a/src/Rust/benches/date.lua b/src/Rust/benches/date.lua new file mode 100644 index 0000000000000000000000000000000000000000..f8f6bcecd8e8fbd9b97579db348d72fb209db035 --- /dev/null +++ b/src/Rust/benches/date.lua @@ -0,0 +1,730 @@ +--------------------------------------------------------------------------------------- +-- Module for date and time calculations +-- +-- Version 2.1.1 +-- Copyright (C) 2006, by Jas Latrix (jastejada@yahoo.com) +-- Copyright (C) 2013-2014, by Thijs Schreijer +-- Licensed under MIT, http://opensource.org/licenses/MIT + +--[[ CONSTANTS ]]-- +local HOURPERDAY = 24 +local MINPERHOUR = 60 +local MINPERDAY = 1440 -- 24*60 +local SECPERMIN = 60 +local SECPERHOUR = 3600 -- 60*60 +local SECPERDAY = 86400 -- 24*60*60 +local TICKSPERSEC = 1000000 +local TICKSPERDAY = 86400000000 +local TICKSPERHOUR = 3600000000 +local TICKSPERMIN = 60000000 +local DAYNUM_MAX = 365242500 -- Sat Jan 01 1000000 00:00:00 +local DAYNUM_MIN = -365242500 -- Mon Jan 01 1000000 BCE 00:00:00 +local DAYNUM_DEF = 0 -- Mon Jan 01 0001 00:00:00 +local _; +--[[ LOCAL ARE FASTER ]]-- +local type = type +local pairs = pairs +local error = error +local assert = assert +local tonumber = tonumber +local tostring = tostring +local string = string +local math = math +local os = os +local unpack = unpack or table.unpack +local setmetatable = setmetatable +local getmetatable = getmetatable +--[[ EXTRA FUNCTIONS ]]-- +local fmt = string.format +local lwr = string.lower +local rep = string.rep +local len = string.len -- luacheck: ignore +local sub = string.sub +local gsub = string.gsub +local gmatch = string.gmatch or string.gfind +local find = string.find +local ostime = os.time +local osdate = os.date +local floor = math.floor +local ceil = math.ceil +local abs = math.abs +-- removes the decimal part of a number +local function fix(n) n = tonumber(n) return n and ((n > 0 and floor or ceil)(n)) end +-- returns the modulo n % d; +local function mod(n,d) return n - d*floor(n/d) end +-- is `str` in string list `tbl`, `ml` is the minimun len +local function inlist(str, tbl, ml, tn) + local sl = len(str) + if sl < (ml or 0) then return nil end + str = lwr(str) + for k, v in pairs(tbl) do + if str == lwr(sub(v, 1, sl)) then + if tn then tn[0] = k end + return k + end + end +end +local function fnil() end +--[[ DATE FUNCTIONS ]]-- +local DATE_EPOCH -- to be set later +local sl_weekdays = { + [0]="Sunday",[1]="Monday",[2]="Tuesday",[3]="Wednesday",[4]="Thursday",[5]="Friday",[6]="Saturday", + [7]="Sun",[8]="Mon",[9]="Tue",[10]="Wed",[11]="Thu",[12]="Fri",[13]="Sat", +} +local sl_meridian = {[-1]="AM", [1]="PM"} +local sl_months = { + [00]="January", [01]="February", [02]="March", + [03]="April", [04]="May", [05]="June", + [06]="July", [07]="August", [08]="September", + [09]="October", [10]="November", [11]="December", + [12]="Jan", [13]="Feb", [14]="Mar", + [15]="Apr", [16]="May", [17]="Jun", + [18]="Jul", [19]="Aug", [20]="Sep", + [21]="Oct", [22]="Nov", [23]="Dec", +} +-- added the '.2' to avoid collision, use `fix` to remove +local sl_timezone = { + [000]="utc", [0.2]="gmt", + [300]="est", [240]="edt", + [360]="cst", [300.2]="cdt", + [420]="mst", [360.2]="mdt", + [480]="pst", [420.2]="pdt", +} +-- set the day fraction resolution +local function setticks(t) + TICKSPERSEC = t; + TICKSPERDAY = SECPERDAY*TICKSPERSEC + TICKSPERHOUR= SECPERHOUR*TICKSPERSEC + TICKSPERMIN = SECPERMIN*TICKSPERSEC +end +-- is year y leap year? +local function isleapyear(y) -- y must be int! + return (mod(y, 4) == 0 and (mod(y, 100) ~= 0 or mod(y, 400) == 0)) +end +-- day since year 0 +local function dayfromyear(y) -- y must be int! + return 365*y + floor(y/4) - floor(y/100) + floor(y/400) +end +-- day number from date, month is zero base +local function makedaynum(y, m, d) + local mm = mod(mod(m,12) + 10, 12) + return dayfromyear(y + floor(m/12) - floor(mm/10)) + floor((mm*306 + 5)/10) + d - 307 + --local yy = y + floor(m/12) - floor(mm/10) + --return dayfromyear(yy) + floor((mm*306 + 5)/10) + (d - 1) +end +-- date from day number, month is zero base +local function breakdaynum(g) + local g = g + 306 + local y = floor((10000*g + 14780)/3652425) + local d = g - dayfromyear(y) + if d < 0 then y = y - 1; d = g - dayfromyear(y) end + local mi = floor((100*d + 52)/3060) + return (floor((mi + 2)/12) + y), mod(mi + 2,12), (d - floor((mi*306 + 5)/10) + 1) +end +--[[ for floats or int32 Lua Number data type +local function breakdaynum2(g) + local g, n = g + 306; + local n400 = floor(g/DI400Y);n = mod(g,DI400Y); + local n100 = floor(n/DI100Y);n = mod(n,DI100Y); + local n004 = floor(n/DI4Y); n = mod(n,DI4Y); + local n001 = floor(n/365); n = mod(n,365); + local y = (n400*400) + (n100*100) + (n004*4) + n001 - ((n001 == 4 or n100 == 4) and 1 or 0) + local d = g - dayfromyear(y) + local mi = floor((100*d + 52)/3060) + return (floor((mi + 2)/12) + y), mod(mi + 2,12), (d - floor((mi*306 + 5)/10) + 1) +end +]] +-- day fraction from time +local function makedayfrc(h,r,s,t) + return ((h*60 + r)*60 + s)*TICKSPERSEC + t +end +-- time from day fraction +local function breakdayfrc(df) + return + mod(floor(df/TICKSPERHOUR),HOURPERDAY), + mod(floor(df/TICKSPERMIN ),MINPERHOUR), + mod(floor(df/TICKSPERSEC ),SECPERMIN), + mod(df,TICKSPERSEC) +end +-- weekday sunday = 0, monday = 1 ... +local function weekday(dn) return mod(dn + 1, 7) end +-- yearday 0 based ... +local function yearday(dn) + return dn - dayfromyear((breakdaynum(dn))-1) +end +-- parse v as a month +local function getmontharg(v) + local m = tonumber(v); + return (m and fix(m - 1)) or inlist(tostring(v) or "", sl_months, 2) +end +-- get daynum of isoweek one of year y +local function isow1(y) + local f = makedaynum(y, 0, 4) -- get the date for the 4-Jan of year `y` + local d = weekday(f) + d = d == 0 and 7 or d -- get the ISO day number, 1 == Monday, 7 == Sunday + return f + (1 - d) +end +local function isowy(dn) + local w1; + local y = (breakdaynum(dn)) + if dn >= makedaynum(y, 11, 29) then + w1 = isow1(y + 1); + if dn < w1 then + w1 = isow1(y); + else + y = y + 1; + end + else + w1 = isow1(y); + if dn < w1 then + w1 = isow1(y-1) + y = y - 1 + end + end + return floor((dn-w1)/7)+1, y +end +local function isoy(dn) + local y = (breakdaynum(dn)) + return y + (((dn >= makedaynum(y, 11, 29)) and (dn >= isow1(y + 1))) and 1 or (dn < isow1(y) and -1 or 0)) +end +local function makedaynum_isoywd(y,w,d) + return isow1(y) + 7*w + d - 8 -- simplified: isow1(y) + ((w-1)*7) + (d-1) +end +--[[ THE DATE MODULE ]]-- +local fmtstr = "%x %X"; +--#if not DATE_OBJECT_AFX then +local date = {} +setmetatable(date, date) +-- Version: VMMMRRRR; V-Major, M-Minor, R-Revision; e.g. 5.45.321 == 50450321 +date.version = 20010001 -- 2.1.1 +--#end -- not DATE_OBJECT_AFX +--[[ THE DATE OBJECT ]]-- +local dobj = {} +dobj.__index = dobj +dobj.__metatable = dobj +-- shout invalid arg +local function date_error_arg() return error("invalid argument(s)",0) end +-- create new date object +local function date_new(dn, df) + return setmetatable({daynum=dn, dayfrc=df}, dobj) +end + +--#if not NO_LOCAL_TIME_SUPPORT then +-- magic year table +local date_epoch, yt; +local function getequivyear(y) + assert(not yt) + yt = {} + local de = date_epoch:copy() + local dw, dy + for _ = 0, 3000 do + de:setyear(de:getyear() + 1, 1, 1) + dy = de:getyear() + dw = de:getweekday() * (isleapyear(dy) and -1 or 1) + if not yt[dw] then yt[dw] = dy end --print(de) + if yt[1] and yt[2] and yt[3] and yt[4] and yt[5] and yt[6] and yt[7] and yt[-1] and yt[-2] and yt[-3] and yt[-4] and yt[-5] and yt[-6] and yt[-7] then + getequivyear = function(y) return yt[ (weekday(makedaynum(y, 0, 1)) + 1) * (isleapyear(y) and -1 or 1) ] end + return getequivyear(y) + end + end +end +-- TimeValue from date and time +local function totv(y,m,d,h,r,s) + return (makedaynum(y, m, d) - DATE_EPOCH) * SECPERDAY + ((h*60 + r)*60 + s) +end +-- TimeValue from TimeTable +local function tmtotv(tm) + return tm and totv(tm.year, tm.month - 1, tm.day, tm.hour, tm.min, tm.sec) +end +-- Returns the bias in seconds of utc time daynum and dayfrc +local function getbiasutc2(self) + local y,m,d = breakdaynum(self.daynum) + local h,r,s = breakdayfrc(self.dayfrc) + local tvu = totv(y,m,d,h,r,s) -- get the utc TimeValue of date and time + local tml = osdate("*t", tvu) -- get the local TimeTable of tvu + if (not tml) or (tml.year > (y+1) or tml.year < (y-1)) then -- failed try the magic + y = getequivyear(y) + tvu = totv(y,m,d,h,r,s) + tml = osdate("*t", tvu) + end + local tvl = tmtotv(tml) + if tvu and tvl then + return tvu - tvl, tvu, tvl + else + return error("failed to get bias from utc time") + end +end +-- Returns the bias in seconds of local time daynum and dayfrc +local function getbiasloc2(daynum, dayfrc) + local tvu + -- extract date and time + local y,m,d = breakdaynum(daynum) + local h,r,s = breakdayfrc(dayfrc) + -- get equivalent TimeTable + local tml = {year=y, month=m+1, day=d, hour=h, min=r, sec=s} + -- get equivalent TimeValue + local tvl = tmtotv(tml) + + local function chkutc() + tml.isdst = nil; local tvug = ostime(tml) if tvug and (tvl == tmtotv(osdate("*t", tvug))) then tvu = tvug return end + tml.isdst = true; local tvud = ostime(tml) if tvud and (tvl == tmtotv(osdate("*t", tvud))) then tvu = tvud return end + tvu = tvud or tvug + end + chkutc() + if not tvu then + tml.year = getequivyear(y) + tvl = tmtotv(tml) + chkutc() + end + return ((tvu and tvl) and (tvu - tvl)) or error("failed to get bias from local time"), tvu, tvl +end +--#end -- not NO_LOCAL_TIME_SUPPORT + +--#if not DATE_OBJECT_AFX then +-- the date parser +local strwalker = {} -- ^Lua regular expression is not as powerful as Perl$ +strwalker.__index = strwalker +local function newstrwalker(s)return setmetatable({s=s, i=1, e=1, c=len(s)}, strwalker) end +function strwalker:aimchr() return "\n" .. self.s .. "\n" .. rep(".",self.e-1) .. "^" end +function strwalker:finish() return self.i > self.c end +function strwalker:back() self.i = self.e return self end +function strwalker:restart() self.i, self.e = 1, 1 return self end +function strwalker:match(s) return (find(self.s, s, self.i)) end +function strwalker:__call(s, f)-- print("strwalker:__call "..s..self:aimchr()) + local is, ie; is, ie, self[1], self[2], self[3], self[4], self[5] = find(self.s, s, self.i) + if is then self.e, self.i = self.i, 1+ie; if f then f(unpack(self)) end return self end +end + local function date_parse(str) + local y,m,d, h,r,s, z, w,u, j, e, x,c, dn,df + local sw = newstrwalker(gsub(gsub(str, "(%b())", ""),"^(%s*)","")) -- remove comment, trim leading space + --local function error_out() print(y,m,d,h,r,s) end + local function error_dup(q) --[[error_out()]] error("duplicate value: " .. (q or "") .. sw:aimchr()) end + local function error_syn(q) --[[error_out()]] error("syntax error: " .. (q or "") .. sw:aimchr()) end + local function error_inv(q) --[[error_out()]] error("invalid date: " .. (q or "") .. sw:aimchr()) end + local function sety(q) y = y and error_dup() or tonumber(q); end + local function setm(q) m = (m or w or j) and error_dup(m or w or j) or tonumber(q) end + local function setd(q) d = d and error_dup() or tonumber(q) end + local function seth(q) h = h and error_dup() or tonumber(q) end + local function setr(q) r = r and error_dup() or tonumber(q) end + local function sets(q) s = s and error_dup() or tonumber(q) end + local function adds(q) s = s + tonumber(q) end + local function setj(q) j = (m or w or j) and error_dup() or tonumber(q); end + local function setz(q) z = (z ~= 0 and z) and error_dup() or q end + local function setzn(zs,zn) zn = tonumber(zn); setz( ((zn<24) and (zn*60) or (mod(zn,100) + floor(zn/100) * 60))*( zs=='+' and -1 or 1) ) end + local function setzc(zs,zh,zm) setz( ((tonumber(zh)*60) + tonumber(zm))*( zs=='+' and -1 or 1) ) end + + if not (sw("^(%d%d%d%d)",sety) and (sw("^(%-?)(%d%d)%1(%d%d)",function(_,a,b) setm(tonumber(a)); setd(tonumber(b)) end) or sw("^(%-?)[Ww](%d%d)%1(%d?)",function(_,a,b) w, u = tonumber(a), tonumber(b or 1) end) or sw("^%-?(%d%d%d)",setj) or sw("^%-?(%d%d)",function(a) setm(a);setd(1) end)) + and ((sw("^%s*[Tt]?(%d%d):?",seth) and sw("^(%d%d):?",setr) and sw("^(%d%d)",sets) and sw("^(%.%d+)",adds)) + or sw:finish() or (sw"^%s*$" or sw"^%s*[Zz]%s*$" or sw("^%s-([%+%-])(%d%d):?(%d%d)%s*$",setzc) or sw("^%s*([%+%-])(%d%d)%s*$",setzn)) + ) ) + then --print(y,m,d,h,r,s,z,w,u,j) + sw:restart(); y,m,d,h,r,s,z,w,u,j = nil,nil,nil,nil,nil,nil,nil,nil,nil,nil + repeat -- print(sw:aimchr()) + if sw("^[tT:]?%s*(%d%d?):",seth) then --print("$Time") + _ = sw("^%s*(%d%d?)",setr) and sw("^%s*:%s*(%d%d?)",sets) and sw("^(%.%d+)",adds) + elseif sw("^(%d+)[/\\%s,-]?%s*") then --print("$Digits") + x, c = tonumber(sw[1]), len(sw[1]) + if (x >= 70) or (m and d and (not y)) or (c > 3) then + sety( x + ((x >= 100 or c>3)and 0 or 1900) ) + else + if m then setd(x) else m = x end + end + elseif sw("^(%a+)[/\\%s,-]?%s*") then --print("$Words") + x = sw[1] + if inlist(x, sl_months, 2, sw) then + if m and (not d) and (not y) then d, m = m, false end + setm(mod(sw[0],12)+1) + elseif inlist(x, sl_timezone, 2, sw) then + c = fix(sw[0]) -- ignore gmt and utc + if c ~= 0 then setz(c, x) end + elseif not inlist(x, sl_weekdays, 2, sw) then + sw:back() + -- am pm bce ad ce bc + if sw("^([bB])%s*(%.?)%s*[Cc]%s*(%2)%s*[Ee]%s*(%2)%s*") or sw("^([bB])%s*(%.?)%s*[Cc]%s*(%2)%s*") then + e = e and error_dup() or -1 + elseif sw("^([aA])%s*(%.?)%s*[Dd]%s*(%2)%s*") or sw("^([cC])%s*(%.?)%s*[Ee]%s*(%2)%s*") then + e = e and error_dup() or 1 + elseif sw("^([PApa])%s*(%.?)%s*[Mm]?%s*(%2)%s*") then + x = lwr(sw[1]) -- there should be hour and it must be correct + if (not h) or (h > 12) or (h < 0) then return error_inv() end + if x == 'a' and h == 12 then h = 0 end -- am + if x == 'p' and h ~= 12 then h = h + 12 end -- pm + else error_syn() end + end + elseif not(sw("^([+-])(%d%d?):(%d%d)",setzc) or sw("^([+-])(%d+)",setzn) or sw("^[Zz]%s*$")) then -- sw{"([+-])",{"(%d%d?):(%d%d)","(%d+)"}} + error_syn("?") + end + sw("^%s*") until sw:finish() + --else print("$Iso(Date|Time|Zone)") + end + -- if date is given, it must be complete year, month & day + if (not y and not h) or ((m and not d) or (d and not m)) or ((m and w) or (m and j) or (j and w)) then return error_inv("!") end + -- fix month + if m then m = m - 1 end + -- fix year if we are on BCE + if e and e < 0 and y > 0 then y = 1 - y end + -- create date object + dn = (y and ((w and makedaynum_isoywd(y,w,u)) or (j and makedaynum(y, 0, j)) or makedaynum(y, m, d))) or DAYNUM_DEF + df = makedayfrc(h or 0, r or 0, s or 0, 0) + ((z or 0)*TICKSPERMIN) + --print("Zone",h,r,s,z,m,d,y,df) + return date_new(dn, df) -- no need to :normalize(); + end +local function date_fromtable(v) + local y, m, d = fix(v.year), getmontharg(v.month), fix(v.day) + local h, r, s, t = tonumber(v.hour), tonumber(v.min), tonumber(v.sec), tonumber(v.ticks) + -- atleast there is time or complete date + if (y or m or d) and (not(y and m and d)) then return error("incomplete table") end + return (y or h or r or s or t) and date_new(y and makedaynum(y, m, d) or DAYNUM_DEF, makedayfrc(h or 0, r or 0, s or 0, t or 0)) +end +local tmap = { + ['number'] = function(v) return date_epoch:copy():addseconds(v) end, + ['string'] = function(v) return date_parse(v) end, + ['boolean']= function(v) return date_fromtable(osdate(v and "!*t" or "*t")) end, + ['table'] = function(v) local ref = getmetatable(v) == dobj; return ref and v or date_fromtable(v), ref end +} +local function date_getdobj(v) + local o, r = (tmap[type(v)] or fnil)(v); + return (o and o:normalize() or error"invalid date time value"), r -- if r is true then o is a reference to a date obj +end +--#end -- not DATE_OBJECT_AFX +local function date_from(arg1, arg2, arg3, arg4, arg5, arg6, arg7) + local y, m, d = fix(arg1), getmontharg(arg2), fix(arg3) + local h, r, s, t = tonumber(arg4 or 0), tonumber(arg5 or 0), tonumber(arg6 or 0), tonumber(arg7 or 0) + if y and m and d and h and r and s and t then + return date_new(makedaynum(y, m, d), makedayfrc(h, r, s, t)):normalize() + else + return date_error_arg() + end +end + +--[[ THE DATE OBJECT METHODS ]]-- +function dobj:normalize() + local dn, df = fix(self.daynum), self.dayfrc + self.daynum, self.dayfrc = dn + floor(df/TICKSPERDAY), mod(df, TICKSPERDAY) + return (dn >= DAYNUM_MIN and dn <= DAYNUM_MAX) and self or error("date beyond imposed limits:"..self) +end + +function dobj:getdate() local y, m, d = breakdaynum(self.daynum) return y, m+1, d end +function dobj:gettime() return breakdayfrc(self.dayfrc) end + +function dobj:getclockhour() local h = self:gethours() return h>12 and mod(h,12) or (h==0 and 12 or h) end + +function dobj:getyearday() return yearday(self.daynum) + 1 end +function dobj:getweekday() return weekday(self.daynum) + 1 end -- in lua weekday is sunday = 1, monday = 2 ... + +function dobj:getyear() local r,_,_ = breakdaynum(self.daynum) return r end +function dobj:getmonth() local _,r,_ = breakdaynum(self.daynum) return r+1 end-- in lua month is 1 base +function dobj:getday() local _,_,r = breakdaynum(self.daynum) return r end +function dobj:gethours() return mod(floor(self.dayfrc/TICKSPERHOUR),HOURPERDAY) end +function dobj:getminutes() return mod(floor(self.dayfrc/TICKSPERMIN), MINPERHOUR) end +function dobj:getseconds() return mod(floor(self.dayfrc/TICKSPERSEC ),SECPERMIN) end +function dobj:getfracsec() return mod(floor(self.dayfrc/TICKSPERSEC ),SECPERMIN)+(mod(self.dayfrc,TICKSPERSEC)/TICKSPERSEC) end +function dobj:getticks(u) local x = mod(self.dayfrc,TICKSPERSEC) return u and ((x*u)/TICKSPERSEC) or x end + +function dobj:getweeknumber(wdb) + local wd, yd = weekday(self.daynum), yearday(self.daynum) + if wdb then + wdb = tonumber(wdb) + if wdb then + wd = mod(wd-(wdb-1),7)-- shift the week day base + else + return date_error_arg() + end + end + return (yd < wd and 0) or (floor(yd/7) + ((mod(yd, 7)>=wd) and 1 or 0)) +end + +function dobj:getisoweekday() return mod(weekday(self.daynum)-1,7)+1 end -- sunday = 7, monday = 1 ... +function dobj:getisoweeknumber() return (isowy(self.daynum)) end +function dobj:getisoyear() return isoy(self.daynum) end +function dobj:getisodate() + local w, y = isowy(self.daynum) + return y, w, self:getisoweekday() +end +function dobj:setisoyear(y, w, d) + local cy, cw, cd = self:getisodate() + if y then cy = fix(tonumber(y))end + if w then cw = fix(tonumber(w))end + if d then cd = fix(tonumber(d))end + if cy and cw and cd then + self.daynum = makedaynum_isoywd(cy, cw, cd) + return self:normalize() + else + return date_error_arg() + end +end + +function dobj:setisoweekday(d) return self:setisoyear(nil, nil, d) end +function dobj:setisoweeknumber(w,d) return self:setisoyear(nil, w, d) end + +function dobj:setyear(y, m, d) + local cy, cm, cd = breakdaynum(self.daynum) + if y then cy = fix(tonumber(y))end + if m then cm = getmontharg(m) end + if d then cd = fix(tonumber(d))end + if cy and cm and cd then + self.daynum = makedaynum(cy, cm, cd) + return self:normalize() + else + return date_error_arg() + end +end + +function dobj:setmonth(m, d)return self:setyear(nil, m, d) end +function dobj:setday(d) return self:setyear(nil, nil, d) end + +function dobj:sethours(h, m, s, t) + local ch,cm,cs,ck = breakdayfrc(self.dayfrc) + ch, cm, cs, ck = tonumber(h or ch), tonumber(m or cm), tonumber(s or cs), tonumber(t or ck) + if ch and cm and cs and ck then + self.dayfrc = makedayfrc(ch, cm, cs, ck) + return self:normalize() + else + return date_error_arg() + end +end + +function dobj:setminutes(m,s,t) return self:sethours(nil, m, s, t) end +function dobj:setseconds(s, t) return self:sethours(nil, nil, s, t) end +function dobj:setticks(t) return self:sethours(nil, nil, nil, t) end + +function dobj:spanticks() return (self.daynum*TICKSPERDAY + self.dayfrc) end +function dobj:spanseconds() return (self.daynum*TICKSPERDAY + self.dayfrc)/TICKSPERSEC end +function dobj:spanminutes() return (self.daynum*TICKSPERDAY + self.dayfrc)/TICKSPERMIN end +function dobj:spanhours() return (self.daynum*TICKSPERDAY + self.dayfrc)/TICKSPERHOUR end +function dobj:spandays() return (self.daynum*TICKSPERDAY + self.dayfrc)/TICKSPERDAY end + +function dobj:addyears(y, m, d) + local cy, cm, cd = breakdaynum(self.daynum) + if y then y = fix(tonumber(y))else y = 0 end + if m then m = fix(tonumber(m))else m = 0 end + if d then d = fix(tonumber(d))else d = 0 end + if y and m and d then + self.daynum = makedaynum(cy+y, cm+m, cd+d) + return self:normalize() + else + return date_error_arg() + end +end + +function dobj:addmonths(m, d) + return self:addyears(nil, m, d) +end + +local function dobj_adddayfrc(self,n,pt,pd) + n = tonumber(n) + if n then + local x = floor(n/pd); + self.daynum = self.daynum + x; + self.dayfrc = self.dayfrc + (n-x*pd)*pt; + return self:normalize() + else + return date_error_arg() + end +end +function dobj:adddays(n) return dobj_adddayfrc(self,n,TICKSPERDAY,1) end +function dobj:addhours(n) return dobj_adddayfrc(self,n,TICKSPERHOUR,HOURPERDAY) end +function dobj:addminutes(n) return dobj_adddayfrc(self,n,TICKSPERMIN,MINPERDAY) end +function dobj:addseconds(n) return dobj_adddayfrc(self,n,TICKSPERSEC,SECPERDAY) end +function dobj:addticks(n) return dobj_adddayfrc(self,n,1,TICKSPERDAY) end +local tvspec = { + -- Abbreviated weekday name (Sun) + ['%a']=function(self) return sl_weekdays[weekday(self.daynum) + 7] end, + -- Full weekday name (Sunday) + ['%A']=function(self) return sl_weekdays[weekday(self.daynum)] end, + -- Abbreviated month name (Dec) + ['%b']=function(self) return sl_months[self:getmonth() - 1 + 12] end, + -- Full month name (December) + ['%B']=function(self) return sl_months[self:getmonth() - 1] end, + -- Year/100 (19, 20, 30) + ['%C']=function(self) return fmt("%.2d", fix(self:getyear()/100)) end, + -- The day of the month as a number (range 1 - 31) + ['%d']=function(self) return fmt("%.2d", self:getday()) end, + -- year for ISO 8601 week, from 00 (79) + ['%g']=function(self) return fmt("%.2d", mod(self:getisoyear() ,100)) end, + -- year for ISO 8601 week, from 0000 (1979) + ['%G']=function(self) return fmt("%.4d", self:getisoyear()) end, + -- same as %b + ['%h']=function(self) return self:fmt0("%b") end, + -- hour of the 24-hour day, from 00 (06) + ['%H']=function(self) return fmt("%.2d", self:gethours()) end, + -- The hour as a number using a 12-hour clock (01 - 12) + ['%I']=function(self) return fmt("%.2d", self:getclockhour()) end, + -- The day of the year as a number (001 - 366) + ['%j']=function(self) return fmt("%.3d", self:getyearday()) end, + -- Month of the year, from 01 to 12 + ['%m']=function(self) return fmt("%.2d", self:getmonth()) end, + -- Minutes after the hour 55 + ['%M']=function(self) return fmt("%.2d", self:getminutes())end, + -- AM/PM indicator (AM) + ['%p']=function(self) return sl_meridian[self:gethours() > 11 and 1 or -1] end, --AM/PM indicator (AM) + -- The second as a number (59, 20 , 01) + ['%S']=function(self) return fmt("%.2d", self:getseconds()) end, + -- ISO 8601 day of the week, to 7 for Sunday (7, 1) + ['%u']=function(self) return self:getisoweekday() end, + -- Sunday week of the year, from 00 (48) + ['%U']=function(self) return fmt("%.2d", self:getweeknumber()) end, + -- ISO 8601 week of the year, from 01 (48) + ['%V']=function(self) return fmt("%.2d", self:getisoweeknumber()) end, + -- The day of the week as a decimal, Sunday being 0 + ['%w']=function(self) return self:getweekday() - 1 end, + -- Monday week of the year, from 00 (48) + ['%W']=function(self) return fmt("%.2d", self:getweeknumber(2)) end, + -- The year as a number without a century (range 00 to 99) + ['%y']=function(self) return fmt("%.2d", mod(self:getyear() ,100)) end, + -- Year with century (2000, 1914, 0325, 0001) + ['%Y']=function(self) return fmt("%.4d", self:getyear()) end, + -- Time zone offset, the date object is assumed local time (+1000, -0230) + ['%z']=function(self) local b = -self:getbias(); local x = abs(b); return fmt("%s%.4d", b < 0 and "-" or "+", fix(x/60)*100 + floor(mod(x,60))) end, + -- Time zone name, the date object is assumed local time + ['%Z']=function(self) return self:gettzname() end, + -- Misc -- + -- Year, if year is in BCE, prints the BCE Year representation, otherwise result is similar to "%Y" (1 BCE, 40 BCE) + ['%\b']=function(self) local x = self:getyear() return fmt("%.4d%s", x>0 and x or (-x+1), x>0 and "" or " BCE") end, + -- Seconds including fraction (59.998, 01.123) + ['%\f']=function(self) local x = self:getfracsec() return fmt("%s%.9f",x >= 10 and "" or "0", x) end, + -- percent character % + ['%%']=function(self) return "%" end, + -- Group Spec -- + -- 12-hour time, from 01:00:00 AM (06:55:15 AM); same as "%I:%M:%S %p" + ['%r']=function(self) return self:fmt0("%I:%M:%S %p") end, + -- hour:minute, from 01:00 (06:55); same as "%I:%M" + ['%R']=function(self) return self:fmt0("%I:%M") end, + -- 24-hour time, from 00:00:00 (06:55:15); same as "%H:%M:%S" + ['%T']=function(self) return self:fmt0("%H:%M:%S") end, + -- month/day/year from 01/01/00 (12/02/79); same as "%m/%d/%y" + ['%D']=function(self) return self:fmt0("%m/%d/%y") end, + -- year-month-day (1979-12-02); same as "%Y-%m-%d" + ['%F']=function(self) return self:fmt0("%Y-%m-%d") end, + -- The preferred date and time representation; same as "%x %X" + ['%c']=function(self) return self:fmt0("%x %X") end, + -- The preferred date representation, same as "%a %b %d %\b" + ['%x']=function(self) return self:fmt0("%a %b %d %\b") end, + -- The preferred time representation, same as "%H:%M:%\f" + ['%X']=function(self) return self:fmt0("%H:%M:%\f") end, + -- GroupSpec -- + -- Iso format, same as "%Y-%m-%dT%T" + ['${iso}'] = function(self) return self:fmt0("%Y-%m-%dT%T") end, + -- http format, same as "%a, %d %b %Y %T GMT" + ['${http}'] = function(self) return self:fmt0("%a, %d %b %Y %T GMT") end, + -- ctime format, same as "%a %b %d %T GMT %Y" + ['${ctime}'] = function(self) return self:fmt0("%a %b %d %T GMT %Y") end, + -- RFC850 format, same as "%A, %d-%b-%y %T GMT" + ['${rfc850}'] = function(self) return self:fmt0("%A, %d-%b-%y %T GMT") end, + -- RFC1123 format, same as "%a, %d %b %Y %T GMT" + ['${rfc1123}'] = function(self) return self:fmt0("%a, %d %b %Y %T GMT") end, + -- asctime format, same as "%a %b %d %T %Y" + ['${asctime}'] = function(self) return self:fmt0("%a %b %d %T %Y") end, +} +function dobj:fmt0(str) return (gsub(str, "%%[%a%%\b\f]", function(x) local f = tvspec[x];return (f and f(self)) or x end)) end +function dobj:fmt(str) + str = str or self.fmtstr or fmtstr + return self:fmt0((gmatch(str, "${%w+}")) and (gsub(str, "${%w+}", function(x)local f=tvspec[x];return (f and f(self)) or x end)) or str) +end + +function dobj.__lt(a, b) if (a.daynum == b.daynum) then return (a.dayfrc < b.dayfrc) else return (a.daynum < b.daynum) end end +function dobj.__le(a, b) if (a.daynum == b.daynum) then return (a.dayfrc <= b.dayfrc) else return (a.daynum <= b.daynum) end end +function dobj.__eq(a, b)return (a.daynum == b.daynum) and (a.dayfrc == b.dayfrc) end +function dobj.__sub(a,b) + local d1, d2 = date_getdobj(a), date_getdobj(b) + local d0 = d1 and d2 and date_new(d1.daynum - d2.daynum, d1.dayfrc - d2.dayfrc) + return d0 and d0:normalize() +end +function dobj.__add(a,b) + local d1, d2 = date_getdobj(a), date_getdobj(b) + local d0 = d1 and d2 and date_new(d1.daynum + d2.daynum, d1.dayfrc + d2.dayfrc) + return d0 and d0:normalize() +end +function dobj.__concat(a, b) return tostring(a) .. tostring(b) end +function dobj:__tostring() return self:fmt() end + +function dobj:copy() return date_new(self.daynum, self.dayfrc) end + +--[[ THE LOCAL DATE OBJECT METHODS ]]-- +function dobj:tolocal() + local dn,df = self.daynum, self.dayfrc + local bias = getbiasutc2(self) + if bias then + -- utc = local + bias; local = utc - bias + self.daynum = dn + self.dayfrc = df - bias*TICKSPERSEC + return self:normalize() + else + return nil + end +end + +function dobj:toutc() + local dn,df = self.daynum, self.dayfrc + local bias = getbiasloc2(dn, df) + if bias then + -- utc = local + bias; + self.daynum = dn + self.dayfrc = df + bias*TICKSPERSEC + return self:normalize() + else + return nil + end +end + +function dobj:getbias() return (getbiasloc2(self.daynum, self.dayfrc))/SECPERMIN end + +function dobj:gettzname() + local _, tvu, _ = getbiasloc2(self.daynum, self.dayfrc) + return tvu and osdate("%Z",tvu) or "" +end + +--#if not DATE_OBJECT_AFX then +function date.time(h, r, s, t) + h, r, s, t = tonumber(h or 0), tonumber(r or 0), tonumber(s or 0), tonumber(t or 0) + if h and r and s and t then + return date_new(DAYNUM_DEF, makedayfrc(h, r, s, t)) + else + return date_error_arg() + end +end + +function date:__call(arg1, args) + local arg_count = select("#", args) + (arg1 == nil and 0 or 1) + if arg_count > 1 then return (date_from(arg1, args)) + elseif arg_count == 0 then return (date_getdobj(false)) + else local o, r = date_getdobj(arg1); return r and o:copy() or o end +end + +date.diff = dobj.__sub + +function date.isleapyear(v) + local y = fix(v); + if not y then + y = date_getdobj(v) + y = y and y:getyear() + end + return isleapyear(y+0) +end + +function date.epoch() return date_epoch:copy() end + +function date.isodate(y,w,d) return date_new(makedaynum_isoywd(y + 0, w and (w+0) or 1, d and (d+0) or 1), 0) end + +-- Internal functions +function date.fmt(str) if str then fmtstr = str end; return fmtstr end +function date.daynummin(n) DAYNUM_MIN = (n and n < DAYNUM_MAX) and n or DAYNUM_MIN return n and DAYNUM_MIN or date_new(DAYNUM_MIN, 0):normalize()end +function date.daynummax(n) DAYNUM_MAX = (n and n > DAYNUM_MIN) and n or DAYNUM_MAX return n and DAYNUM_MAX or date_new(DAYNUM_MAX, 0):normalize()end +function date.ticks(t) if t then setticks(t) end return TICKSPERSEC end +--#end -- not DATE_OBJECT_AFX + +local tm = osdate("!*t", 0); +if tm then + date_epoch = date_new(makedaynum(tm.year, tm.month - 1, tm.day), makedayfrc(tm.hour, tm.min, tm.sec, 0)) + -- the distance from our epoch to os epoch in daynum + DATE_EPOCH = date_epoch and date_epoch:spandays() +else -- error will be raise only if called! + date_epoch = setmetatable({},{__index = function() error("failed to get the epoch date") end}) +end + +--#if not DATE_OBJECT_AFX then +return date +--#else +--$return date_from +--#end + diff --git a/src/Rust/benches/date.rs b/src/Rust/benches/date.rs new file mode 100644 index 0000000000000000000000000000000000000000..7898cacdea697ec71d681a7c1d87b44db769f999 --- /dev/null +++ b/src/Rust/benches/date.rs @@ -0,0 +1,21 @@ +use criterion::{criterion_group, criterion_main, Criterion}; +use vvs_parser::prelude::{ast::*, parser::*}; + +const DATE_SOURCE: &str = include_str!("./date.lua"); + +fn parse(criterion: &mut Criterion) { + criterion.bench_function("get ast from parsed date", move |b| b.iter(|| parse_lua_tree(DATE_SOURCE))); +} + +fn range(criterion: &mut Criterion) { + let ast = parse_lua_tree(DATE_SOURCE).unwrap(); + criterion.bench_function("get range of ast of date", move |b| b.iter(|| ast.nodes().range())); +} + +criterion_group! { + name = benches; + config = Criterion::default().sample_size(20); + targets = parse, range +} + +criterion_main!(benches); diff --git a/src/Rust/benches/t.lua b/src/Rust/benches/t.lua new file mode 100644 index 0000000000000000000000000000000000000000..ced68d9c947a5787cdb4f83eaee81af7ebdd6d7f --- /dev/null +++ b/src/Rust/benches/t.lua @@ -0,0 +1,1135 @@ +-- Sourced from https://github.com/osyrisrblx/t + +-- The MPL 2.0 license of Full Moon does not apply to this file. +-- The license of this file is as follows: + +-- MIT License + +-- Copyright (c) 2018 Osyris +-- +-- Permission is hereby granted, free of charge, to any person obtaining a copy +-- of this software and associated documentation files (the "Software"), to deal +-- in the Software without restriction, including without limitation the rights +-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +-- copies of the Software, and to permit persons to whom the Software is +-- furnished to do so, subject to the following conditions: +-- +-- The above copyright notice and this permission notice shall be included in all +-- copies or substantial portions of the Software. +-- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +-- SOFTWARE. + +-- t: a runtime typechecker for Roblox + +-- regular lua compatibility +local typeof = typeof or type + +local function primitive(typeName) + return function(value) + local valueType = typeof(value) + if valueType == typeName then + return true + else + return false, string.format("%s expected, got %s", typeName, valueType) + end + end +end + +local t = {} + +--[[** + matches any type except nil + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +function t.any(value) + if value ~= nil then + return true + else + return false, "any expected, got nil" + end +end + +--Lua primitives + +--[[** + ensures Lua primitive boolean type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.boolean = primitive("boolean") + +--[[** + ensures Lua primitive thread type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.thread = primitive("thread") + +--[[** + ensures Lua primitive callback type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.callback = primitive("function") + +--[[** + ensures Lua primitive none type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.none = primitive("nil") + +--[[** + ensures Lua primitive string type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.string = primitive("string") + +--[[** + ensures Lua primitive table type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.table = primitive("table") + +--[[** + ensures Lua primitive userdata type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.userdata = primitive("userdata") + +--[[** + ensures value is a number and non-NaN + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +function t.number(value) + local valueType = typeof(value) + if valueType == "number" then + if value == value then + return true + else + return false, "unexpected NaN value" + end + else + return false, string.format("number expected, got %s", valueType) + end +end + +--[[** + ensures value is NaN + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +function t.nan(value) + if value ~= value then + return true + else + return false, "unexpected non-NaN value" + end +end + +-- roblox types + +--[[** + ensures Roblox Axes type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.Axes = primitive("Axes") + +--[[** + ensures Roblox BrickColor type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.BrickColor = primitive("BrickColor") + +--[[** + ensures Roblox CFrame type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.CFrame = primitive("CFrame") + +--[[** + ensures Roblox Color3 type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.Color3 = primitive("Color3") + +--[[** + ensures Roblox ColorSequence type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.ColorSequence = primitive("ColorSequence") + +--[[** + ensures Roblox ColorSequenceKeypoint type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.ColorSequenceKeypoint = primitive("ColorSequenceKeypoint") + +--[[** + ensures Roblox DockWidgetPluginGuiInfo type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.DockWidgetPluginGuiInfo = primitive("DockWidgetPluginGuiInfo") + +--[[** + ensures Roblox Faces type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.Faces = primitive("Faces") + +--[[** + ensures Roblox Instance type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.Instance = primitive("Instance") + +--[[** + ensures Roblox NumberRange type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.NumberRange = primitive("NumberRange") + +--[[** + ensures Roblox NumberSequence type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.NumberSequence = primitive("NumberSequence") + +--[[** + ensures Roblox NumberSequenceKeypoint type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.NumberSequenceKeypoint = primitive("NumberSequenceKeypoint") + +--[[** + ensures Roblox PathWaypoint type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.PathWaypoint = primitive("PathWaypoint") + +--[[** + ensures Roblox PhysicalProperties type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.PhysicalProperties = primitive("PhysicalProperties") + +--[[** + ensures Roblox Random type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.Random = primitive("Random") + +--[[** + ensures Roblox Ray type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.Ray = primitive("Ray") + +--[[** + ensures Roblox Rect type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.Rect = primitive("Rect") + +--[[** + ensures Roblox Region3 type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.Region3 = primitive("Region3") + +--[[** + ensures Roblox Region3int16 type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.Region3int16 = primitive("Region3int16") + +--[[** + ensures Roblox TweenInfo type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.TweenInfo = primitive("TweenInfo") + +--[[** + ensures Roblox UDim type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.UDim = primitive("UDim") + +--[[** + ensures Roblox UDim2 type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.UDim2 = primitive("UDim2") + +--[[** + ensures Roblox Vector2 type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.Vector2 = primitive("Vector2") + +--[[** + ensures Roblox Vector3 type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.Vector3 = primitive("Vector3") + +--[[** + ensures Roblox Vector3int16 type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.Vector3int16 = primitive("Vector3int16") + +-- roblox enum types + +--[[** + ensures Roblox Enum type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.Enum = primitive("Enum") + +--[[** + ensures Roblox EnumItem type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.EnumItem = primitive("EnumItem") + +--[[** + ensures Roblox RBXScriptSignal type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.RBXScriptSignal = primitive("RBXScriptSignal") + +--[[** + ensures Roblox RBXScriptConnection type + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +t.RBXScriptConnection = primitive("RBXScriptConnection") + +--[[** + ensures value is a given literal value + + @param literal The literal to use + + @returns A function that will return true iff the condition is passed +**--]] +function t.literal(args) + local size = select("#", args) + if size == 1 then + local literal = args + return function(value) + if value ~= literal then + return false, string.format("expected %s, got %s", tostring(literal), tostring(value)) + end + return true + end + else + local literals = {} + for i = 1, size do + local value = select(i, args) + literals[i] = t.literal(value) + end + return t.union(unpack(literals)) + end +end + +--[[** + DEPRECATED + Please use t.literal +**--]] +t.exactly = t.literal + +--[[** + Returns a t.union of each key in the table as a t.literal + + @param keyTable The table to get keys from + + @returns True iff the condition is satisfied, false otherwise +**--]] +function t.keyOf(keyTable) + local keys = {} + for key in pairs(keyTable) do + keys[#keys + 1] = key + end + return t.literal(unpack(keys)) +end + +--[[** + Returns a t.union of each value in the table as a t.literal + + @param valueTable The table to get values from + + @returns True iff the condition is satisfied, false otherwise +**--]] +function t.valueOf(valueTable) + local values = {} + for _, value in pairs(valueTable) do + values[#values + 1] = value + end + return t.literal(unpack(values)) +end + +--[[** + ensures value is an integer + + @param value The value to check against + + @returns True iff the condition is satisfied, false otherwise +**--]] +function t.integer(value) + local success, errMsg = t.number(value) + if not success then + return false, errMsg or "" + end + if value%1 == 0 then + return true + else + return false, string.format("integer expected, got %s", value) + end +end + +--[[** + ensures value is a number where min <= value + + @param min The minimum to use + + @returns A function that will return true iff the condition is passed +**--]] +function t.numberMin(min) + return function(value) + local success, errMsg = t.number(value) + if not success then + return false, errMsg or "" + end + if value >= min then + return true + else + return false, string.format("number >= %s expected, got %s", min, value) + end + end +end + +--[[** + ensures value is a number where value <= max + + @param max The maximum to use + + @returns A function that will return true iff the condition is passed +**--]] +function t.numberMax(max) + return function(value) + local success, errMsg = t.number(value) + if not success then + return false, errMsg + end + if value <= max then + return true + else + return false, string.format("number <= %s expected, got %s", max, value) + end + end +end + +--[[** + ensures value is a number where min < value + + @param min The minimum to use + + @returns A function that will return true iff the condition is passed +**--]] +function t.numberMinExclusive(min) + return function(value) + local success, errMsg = t.number(value) + if not success then + return false, errMsg or "" + end + if min < value then + return true + else + return false, string.format("number > %s expected, got %s", min, value) + end + end +end + +--[[** + ensures value is a number where value < max + + @param max The maximum to use + + @returns A function that will return true iff the condition is passed +**--]] +function t.numberMaxExclusive(max) + return function(value) + local success, errMsg = t.number(value) + if not success then + return false, errMsg or "" + end + if value < max then + return true + else + return false, string.format("number < %s expected, got %s", max, value) + end + end +end + +--[[** + ensures value is a number where value > 0 + + @returns A function that will return true iff the condition is passed +**--]] +t.numberPositive = t.numberMinExclusive(0) + +--[[** + ensures value is a number where value < 0 + + @returns A function that will return true iff the condition is passed +**--]] +t.numberNegative = t.numberMaxExclusive(0) + +--[[** + ensures value is a number where min <= value <= max + + @param min The minimum to use + @param max The maximum to use + + @returns A function that will return true iff the condition is passed +**--]] +function t.numberConstrained(min, max) + assert(t.number(min) and t.number(max)) + local minCheck = t.numberMin(min) + local maxCheck = t.numberMax(max) + return function(value) + local minSuccess, minErrMsg = minCheck(value) + if not minSuccess then + return false, minErrMsg or "" + end + + local maxSuccess, maxErrMsg = maxCheck(value) + if not maxSuccess then + return false, maxErrMsg or "" + end + + return true + end +end + +--[[** + ensures value is a number where min < value < max + + @param min The minimum to use + @param max The maximum to use + + @returns A function that will return true iff the condition is passed +**--]] +function t.numberConstrainedExclusive(min, max) + assert(t.number(min) and t.number(max)) + local minCheck = t.numberMinExclusive(min) + local maxCheck = t.numberMaxExclusive(max) + return function(value) + local minSuccess, minErrMsg = minCheck(value) + if not minSuccess then + return false, minErrMsg or "" + end + + local maxSuccess, maxErrMsg = maxCheck(value) + if not maxSuccess then + return false, maxErrMsg or "" + end + + return true + end +end + +--[[** + ensures value matches string pattern + + @param string pattern to check against + + @returns A function that will return true iff the condition is passed +**--]] +function t.match(pattern) + assert(t.string(pattern)) + return function(value) + local stringSuccess, stringErrMsg = t.string(value) + if not stringSuccess then + return false, stringErrMsg + end + + if string.match(value, pattern) == nil then + return false, string.format("\"%s\" failed to match pattern \"%s\"", value, pattern) + end + + return true + end +end + +--[[** + ensures value is either nil or passes check + + @param check The check to use + + @returns A function that will return true iff the condition is passed +**--]] +function t.optional(check) + assert(t.callback(check)) + return function(value) + if value == nil then + return true + end + local success, errMsg = check(value) + if success then + return true + else + return false, string.format("(optional) %s", errMsg or "") + end + end +end + +--[[** + matches given tuple against tuple type definition + + @param ... The type definition for the tuples + + @returns A function that will return true iff the condition is passed +**--]] +function t.tuple(args) + local checks = args + return function(args) + for i = 1, #checks do + local success, errMsg = checks[i](args[i]) + if success == false then + return false, string.format("Bad tuple index #%s:\n\t%s", i, errMsg or "") + end + end + return true + end +end + +--[[** + ensures all keys in given table pass check + + @param check The function to use to check the keys + + @returns A function that will return true iff the condition is passed +**--]] +function t.keys(check) + assert(t.callback(check)) + return function(value) + local tableSuccess, tableErrMsg = t.table(value) + if tableSuccess == false then + return false, tableErrMsg or "" + end + + for key in pairs(value) do + local success, errMsg = check(key) + if success == false then + return false, string.format("bad key %s:\n\t%s", tostring(key), errMsg or "") + end + end + + return true + end +end + +--[[** + ensures all values in given table pass check + + @param check The function to use to check the values + + @returns A function that will return true iff the condition is passed +**--]] +function t.values(check) + assert(t.callback(check)) + return function(value) + local tableSuccess, tableErrMsg = t.table(value) + if tableSuccess == false then + return false, tableErrMsg or "" + end + + for key, val in pairs(value) do + local success, errMsg = check(val) + if success == false then + return false, string.format("bad value for key %s:\n\t%s", tostring(key), errMsg or "") + end + end + + return true + end +end + +--[[** + ensures value is a table and all keys pass keyCheck and all values pass valueCheck + + @param keyCheck The function to use to check the keys + @param valueCheck The function to use to check the values + + @returns A function that will return true iff the condition is passed +**--]] +function t.map(keyCheck, valueCheck) + assert(t.callback(keyCheck), t.callback(valueCheck)) + local keyChecker = t.keys(keyCheck) + local valueChecker = t.values(valueCheck) + return function(value) + local keySuccess, keyErr = keyChecker(value) + if not keySuccess then + return false, keyErr or "" + end + + local valueSuccess, valueErr = valueChecker(value) + if not valueSuccess then + return false, valueErr or "" + end + + return true + end +end + +do + local arrayKeysCheck = t.keys(t.integer) + --[[** + ensures value is an array and all values of the array match check + + @param check The check to compare all values with + + @returns A function that will return true iff the condition is passed + **--]] + function t.array(check) + assert(t.callback(check)) + local valuesCheck = t.values(check) + return function(value) + local keySuccess, keyErrMsg = arrayKeysCheck(value) + if keySuccess == false then + return false, string.format("[array] %s", keyErrMsg or "") + end + + -- # is unreliable for sparse arrays + -- Count upwards using ipairs to avoid false positives from the behavior of # + local arraySize = 0 + + for _, _ in ipairs(value) do + arraySize = arraySize + 1 + end + + for key in pairs(value) do + if key < 1 or key > arraySize then + return false, string.format("[array] key %s must be sequential", tostring(key)) + end + end + + local valueSuccess, valueErrMsg = valuesCheck(value) + if not valueSuccess then + return false, string.format("[array] %s", valueErrMsg or "") + end + + return true + end + end +end + +do + local callbackArray = t.array(t.callback) + --[[** + creates a union type + + @param ... The checks to union + + @returns A function that will return true iff the condition is passed + **--]] + function t.union(args) + local checks = args + assert(callbackArray(checks)) + return function(value) + for _, check in pairs(checks) do + if check(value) then + return true + end + end + return false, "bad type for union" + end + end + + --[[** + Alias for t.union + **--]] + t.some = t.union + + --[[** + creates an intersection type + + @param ... The checks to intersect + + @returns A function that will return true iff the condition is passed + **--]] + function t.intersection(args) + local checks = args + assert(callbackArray(checks)) + return function(value) + for _, check in pairs(checks) do + local success, errMsg = check(value) + if not success then + return false, errMsg or "" + end + end + return true + end + end + + --[[** + Alias for t.intersection + **--]] + t.every = t.intersection +end + +do + local checkInterface = t.map(t.any, t.callback) + --[[** + ensures value matches given interface definition + + @param checkTable The interface definition + + @returns A function that will return true iff the condition is passed + **--]] + function t.interface(checkTable) + assert(checkInterface(checkTable)) + return function(value) + local tableSuccess, tableErrMsg = t.table(value) + if tableSuccess == false then + return false, tableErrMsg or "" + end + + for key, check in pairs(checkTable) do + local success, errMsg = check(value[key]) + if success == false then + return false, string.format("[interface] bad value for %s:\n\t%s", tostring(key), errMsg or "") + end + end + return true + end + end + + --[[** + ensures value matches given interface definition strictly + + @param checkTable The interface definition + + @returns A function that will return true iff the condition is passed + **--]] + function t.strictInterface(checkTable) + assert(checkInterface(checkTable)) + return function(value) + local tableSuccess, tableErrMsg = t.table(value) + if tableSuccess == false then + return false, tableErrMsg or "" + end + + for key, check in pairs(checkTable) do + local success, errMsg = check(value[key]) + if success == false then + return false, string.format("[interface] bad value for %s:\n\t%s", tostring(key), errMsg or "") + end + end + + for key in pairs(value) do + if not checkTable[key] then + return false, string.format("[interface] unexpected field '%s'", tostring(key)) + end + end + + return true + end + end +end + +--[[** + ensure value is an Instance and it's ClassName matches the given ClassName + + @param className The class name to check for + + @returns A function that will return true iff the condition is passed +**--]] +function t.instanceOf(className, childTable) + assert(t.string(className)) + + local childrenCheck + if childTable ~= nil then + childrenCheck = t.children(childTable) + end + + return function(value) + local instanceSuccess, instanceErrMsg = t.Instance(value) + if not instanceSuccess then + return false, instanceErrMsg or "" + end + + if value.ClassName ~= className then + return false, string.format("%s expected, got %s", className, value.ClassName) + end + + if childrenCheck then + local childrenSuccess, childrenErrMsg = childrenCheck(value) + if not childrenSuccess then + return false, childrenErrMsg + end + end + + return true + end +end +t.instance = t.instanceOf + +--[[** + ensure value is an Instance and it's ClassName matches the given ClassName by an IsA comparison + + @param className The class name to check for + + @returns A function that will return true iff the condition is passed +**--]] +function t.instanceIsA(className, childTable) + assert(t.string(className)) + + local childrenCheck + if childTable ~= nil then + childrenCheck = t.children(childTable) + end + + return function(value) + local instanceSuccess, instanceErrMsg = t.Instance(value) + if not instanceSuccess then + return false, instanceErrMsg or "" + end + + if not value:IsA(className) then + return false, string.format("%s expected, got %s", className, value.ClassName) + end + + if childrenCheck then + local childrenSuccess, childrenErrMsg = childrenCheck(value) + if not childrenSuccess then + return false, childrenErrMsg + end + end + + return true + end +end + +--[[** + ensures value is an enum of the correct type + + @param enum The enum to check + + @returns A function that will return true iff the condition is passed +**--]] +function t.enum(enum) + assert(t.Enum(enum)) + return function(value) + local enumItemSuccess, enumItemErrMsg = t.EnumItem(value) + if not enumItemSuccess then + return false, enumItemErrMsg + end + + if value.EnumType == enum then + return true + else + return false, string.format("enum of %s expected, got enum of %s", tostring(enum), tostring(value.EnumType)) + end + end +end + +do + local checkWrap = t.tuple(t.callback, t.callback) + + --[[** + wraps a callback in an assert with checkArgs + + @param callback The function to wrap + @param checkArgs The functon to use to check arguments in the assert + + @returns A function that first asserts using checkArgs and then calls callback + **--]] + function t.wrap(callback, checkArgs) + assert(checkWrap(callback, checkArgs)) + return function(args) + assert(checkArgs(args)) + return callback(args) + end + end +end + +--[[** + asserts a given check + + @param check The function to wrap with an assert + + @returns A function that simply wraps the given check in an assert +**--]] +function t.strict(check) + return function(args) + assert(check(args)) + end +end + +do + local checkChildren = t.map(t.string, t.callback) + + --[[** + Takes a table where keys are child names and values are functions to check the children against. + Pass an instance tree into the function. + If at least one child passes each check, the overall check passes. + + Warning! If you pass in a tree with more than one child of the same name, this function will always return false + + @param checkTable The table to check against + + @returns A function that checks an instance tree + **--]] + function t.children(checkTable) + assert(checkChildren(checkTable)) + + return function(value) + local instanceSuccess, instanceErrMsg = t.Instance(value) + if not instanceSuccess then + return false, instanceErrMsg or "" + end + + local childrenByName = {} + for _, child in pairs(value:GetChildren()) do + local name = child.Name + if checkTable[name] then + if childrenByName[name] then + return false, string.format("Cannot process multiple children with the same name \"%s\"", name) + end + childrenByName[name] = child + end + end + + for name, check in pairs(checkTable) do + local success, errMsg = check(childrenByName[name]) + if not success then + return false, string.format("[%s.%s] %s", value:GetFullName(), name, errMsg or "") + end + end + + return true + end + end +end + +return t diff --git a/src/Rust/benches/t.rs b/src/Rust/benches/t.rs new file mode 100644 index 0000000000000000000000000000000000000000..ea31bac1d958c9eae6432cb7ab005d1418cf172a --- /dev/null +++ b/src/Rust/benches/t.rs @@ -0,0 +1,21 @@ +use criterion::{criterion_group, criterion_main, Criterion}; +use vvs_parser::prelude::{ast::*, parser::*}; + +const T_SOURCE: &str = include_str!("./t.lua"); + +fn parse(criterion: &mut Criterion) { + criterion.bench_function("get ast from parsed t", move |b| b.iter(|| parse_lua_tree(T_SOURCE))); +} + +fn range(criterion: &mut Criterion) { + let ast = parse_lua_tree(T_SOURCE).unwrap(); + criterion.bench_function("get range of ast of t", move |b| b.iter(|| ast.nodes().range())); +} + +criterion_group! { + name = benches; + config = Criterion::default().sample_size(20); + targets = parse, range +} + +criterion_main!(benches); diff --git a/src/Rust/rustfmt.toml b/src/Rust/rustfmt.toml index abc68cf273d033f6350083ce7f0a05eedabf2222..9ef09980ff314c41685fc44ddb7990cd7888f160 100644 --- a/src/Rust/rustfmt.toml +++ b/src/Rust/rustfmt.toml @@ -1,12 +1,12 @@ edition = "2021" -max_width = 120 newline_style = "Unix" # Let's use the horizontal space of the screen -fn_call_width = 70 -single_line_if_else_max_width = 70 -struct_lit_width = 70 -struct_variant_width = 70 +max_width = 120 +fn_call_width = 100 +single_line_if_else_max_width = 100 +struct_lit_width = 100 +struct_variant_width = 100 # Modern rust use_try_shorthand = true diff --git a/src/Rust/vvs_ass/Cargo.toml b/src/Rust/vvs_ass/Cargo.toml index 2a9a1f6421ec74443e6fa4519b7109258ba28118..7200e2fcdd7a7e85d77688163aaf949033467e20 100644 --- a/src/Rust/vvs_ass/Cargo.toml +++ b/src/Rust/vvs_ass/Cargo.toml @@ -1,18 +1,18 @@ [package] -name = "vvs_ass" +name = "vvs_ass" +description = "ASS specification and VVS specificities for VVCC" version.workspace = true authors.workspace = true edition.workspace = true license.workspace = true -description = "ASS specification and VVS specificities for VVCC" [dependencies] -vvs_procmacro = { path = "../vvs_procmacro" } -vvs_utils = { path = "../vvs_utils" } -vvs_font = { path = "../vvs_font" } +vvs_procmacro.workspace = true +vvs_utils.workspace = true +vvs_font.workspace = true unicode-segmentation.workspace = true -thiserror.workspace = true -anyhow.workspace = true -serde.workspace = true -log.workspace = true +thiserror.workspace = true +anyhow.workspace = true +serde.workspace = true +log.workspace = true diff --git a/src/Rust/vvs_ass/src/colors.rs b/src/Rust/vvs_ass/src/colors.rs index 380a9a1ac0f36cf70dd744f8790460dc7f5af815..d4047bb8a9d9a8da9ac7ac86c4d8d0f772f80306 100644 --- a/src/Rust/vvs_ass/src/colors.rs +++ b/src/Rust/vvs_ass/src/colors.rs @@ -36,6 +36,7 @@ impl ASSColor { rgb! { FUCHSIA => 255 0 255 } rgb! { PURPLE => 128 0 128 } + #[inline] fn skip_delimiters(str: &str) -> &str { str.trim() .trim_start_matches('#') @@ -44,6 +45,7 @@ impl ASSColor { .trim_end_matches('&') } + #[inline] pub fn try_from_rgba(str: impl AsRef<str>) -> Result<Self, String> { let color = Self::skip_delimiters(str.as_ref()); if !(color.len() == 6 || color.len() == 8) { @@ -61,6 +63,7 @@ impl ASSColor { }) } + #[inline] pub fn try_from_bgra(str: impl AsRef<str>) -> Result<Self, String> { let color = Self::skip_delimiters(str.as_ref()); if !(color.len() == 6 || color.len() == 8) { @@ -78,6 +81,7 @@ impl ASSColor { }) } + #[inline] pub fn into_rgba(self) -> Self { match self { this @ ASSColor::RGBA { .. } => this, @@ -113,6 +117,7 @@ impl ASSColor { } } + #[inline] pub fn into_hsla(self) -> Self { match self { this @ ASSColor::HSLA { .. } => this, @@ -132,6 +137,7 @@ impl ASSColor { } /// Returns the HUE from the color (the H in HSL/HSV). + #[inline] fn hue(&self) -> f32 { match self { ASSColor::HSLA { h, .. } => *h, diff --git a/src/Rust/vvs_ass/src/definitions.rs b/src/Rust/vvs_ass/src/definitions.rs index dcd1b2012835759e6ad06fa51d7ab8deef428b8d..bb488d6fb04b66ec2eef0d6b00570857a3330199 100644 --- a/src/Rust/vvs_ass/src/definitions.rs +++ b/src/Rust/vvs_ass/src/definitions.rs @@ -17,17 +17,17 @@ pub struct ASSEvent { /// Subtitles having different layer number will be ignored during the collusion detection. /// Higher numbered layers will be drawn over the lower numbered. - pub layer: i64, + pub layer: i32, /// Start Time of the Event, in 0:00:00:00 format ie. Hrs:Mins:Secs:hundredths. This is the /// time elapsed during script playback at which the text will appear onscreen. Note that there /// is a single digit for the hours! - pub start: i64, + pub start: i32, /// End Time of the Event, in 0:00:00:00 format ie. Hrs:Mins:Secs:hundredths. This is the time /// elapsed during script playback at which the text will disappear offscreen. Note that there /// is a single digit for the hours! - pub end: i64, + pub end: i32, /// Style name. If it is "Default", then your own *Default style will be subtituted. However, /// the Default style used by the script author IS stored in the script even though SSA ignores @@ -171,6 +171,7 @@ pub enum ScriptInfoKey { impl FromStr for ScriptInfoKey { type Err = String; + #[inline] fn from_str(s: &str) -> Result<Self, Self::Err> { use ScriptInfoKey::*; match s.trim() { @@ -199,6 +200,7 @@ impl FromStr for ScriptInfoKey { impl FromStr for ASSFileSection { type Err = String; + #[inline] fn from_str(s: &str) -> Result<Self, Self::Err> { use ASSFileSection::*; const TRIM_PAT: &[char] = &['[', ']', ' ', '\t']; diff --git a/src/Rust/vvs_ass/src/drawing.rs b/src/Rust/vvs_ass/src/drawing.rs index c2d2a88260a55919d2179b0a9e5301ce3a3c1053..7e5c7bf8af91919718686de83e4120bc9396310c 100644 --- a/src/Rust/vvs_ass/src/drawing.rs +++ b/src/Rust/vvs_ass/src/drawing.rs @@ -21,49 +21,22 @@ #[derive(Debug, Clone, PartialEq)] pub enum ASSDrawingCmd { // Moves the cursor to <x>, <y> - M { - x: i64, - y: i64, - }, + M { x: i64, y: i64 }, // Moves the cursor to <x>, <y> (unclosed shapes will be left open) - N { - x: i64, - y: i64, - }, + N { x: i64, y: i64 }, // Draws a line to <x>, <y> - L { - x: i64, - y: i64, - }, + L { x: i64, y: i64 }, // 3rd degree bezier curve to point 3 using point 1 and 2 as the control points - B { - x1: i64, - y1: i64, - x2: i64, - y2: i64, - x3: i64, - y3: i64, - }, + B { x1: i64, y1: i64, x2: i64, y2: i64, x3: i64, y3: i64 }, // 3rd degree uniform b-spline to point N, must contain at least 3 coordinates - S { - x1: i64, - y1: i64, - x2: i64, - y2: i64, - x3: i64, - y3: i64, - others: Vec<(i64, i64)>, - }, + S { x1: i64, y1: i64, x2: i64, y2: i64, x3: i64, y3: i64, others: Vec<(i64, i64)> }, // Extend b-spline to <x>, <y> - P { - x: i64, - y: i64, - }, + P { x: i64, y: i64 }, // close b-spline C, @@ -76,6 +49,7 @@ pub struct ASSDrawing { } impl ASSDrawingCmd { + #[inline] pub fn is_move_cmd(&self) -> bool { use ASSDrawingCmd::*; matches!(self, M { .. } | N { .. }) diff --git a/src/Rust/vvs_ass/src/elements/aux_table.rs b/src/Rust/vvs_ass/src/elements/aux_table.rs new file mode 100644 index 0000000000000000000000000000000000000000..78da4efe8f263e013dbc0d3443f41f4583a06f6c --- /dev/null +++ b/src/Rust/vvs_ass/src/elements/aux_table.rs @@ -0,0 +1,3 @@ +pub trait AuxTable: Default + PartialEq { + fn deep_clone(&self) -> Self; +} diff --git a/src/Rust/vvs_ass/src/elements/line.rs b/src/Rust/vvs_ass/src/elements/line.rs index 63df87f09256b591a6ed13421f264e77b0585aff..8e86b8aaac1846185b95937361a6dafb71e0cc62 100644 --- a/src/Rust/vvs_ass/src/elements/line.rs +++ b/src/Rust/vvs_ass/src/elements/line.rs @@ -1,78 +1,20 @@ -use crate::{ASSAuxTable, ASSPosition, ASSSyllabePtr}; +use crate::{ASSPosition, ASSSyllabe, AuxTable}; -#[derive(Debug, Default, Clone, PartialEq)] -pub struct ASSLine { +#[derive(Debug, Default, PartialEq)] +pub struct ASSLine<T: AuxTable> { + pub is_comment: bool, + pub start: i32, + pub fini: i32, pub position: ASSPosition, - pub content: Vec<ASSSyllabePtr>, - pub aux: ASSAuxTable, - pub start: i64, - pub fini: i64, + pub content: Vec<ASSSyllabe<T>>, + pub aux: T, } -#[derive(Debug, Default, Clone)] -#[repr(transparent)] -pub struct ASSLinePtr(pub crate::Ptr<ASSLine>); - -#[derive(Debug, Default, Clone)] -#[repr(transparent)] -pub struct ASSLines(pub Vec<ASSLinePtr>); - -impl PartialEq for ASSLinePtr { - fn eq(&self, other: &Self) -> bool { - *self.0.try_read().unwrap() == *other.0.try_read().unwrap() - } -} - -impl PartialEq for ASSLines { - fn eq(&self, Self(other): &Self) -> bool { - let Self(this) = self; - (this.len() != other.len()) && { - this.iter() - .zip(other.iter()) - .fold(true, |acc, (ASSLinePtr(this), ASSLinePtr(other))| { - acc && (*this.try_read().unwrap() == *other.try_read().unwrap()) - }) - } - } -} - -impl From<ASSLine> for ASSLinePtr { - fn from(value: ASSLine) -> Self { - ASSLinePtr(crate::ptr!(value)) - } -} - -impl ASSLines { - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn is_empty(&self) -> bool { - self.0.is_empty() - } - - pub fn push(&mut self, value: impl Into<ASSLinePtr>) { - self.0.push(value.into()) - } -} - -impl Extend<ASSLinePtr> for ASSLines { - fn extend<T: IntoIterator<Item = ASSLinePtr>>(&mut self, iter: T) { - self.0.extend(iter) - } -} - -impl Extend<ASSLine> for ASSLines { - fn extend<T: IntoIterator<Item = ASSLine>>(&mut self, iter: T) { - self.extend(iter.into_iter().map(|line| ASSLinePtr(crate::ptr!(line)))) - } -} - -impl IntoIterator for ASSLines { - type Item = ASSLinePtr; - type IntoIter = <Vec<ASSLinePtr> as IntoIterator>::IntoIter; - - fn into_iter(self) -> Self::IntoIter { - self.0.into_iter() +impl<T: AuxTable> Clone for ASSLine<T> { + fn clone(&self) -> Self { + let Self { is_comment, start, fini, position, .. } = *self; + let content = self.content.clone(); + let aux = self.aux.deep_clone(); + Self { is_comment, start, fini, position, content, aux } } } diff --git a/src/Rust/vvs_ass/src/elements/mod.rs b/src/Rust/vvs_ass/src/elements/mod.rs index 2de364b6fb53687854afc8678fe8c23baffb5e62..d585f9a29e1fe7d4c714df72890efabf20549acc 100644 --- a/src/Rust/vvs_ass/src/elements/mod.rs +++ b/src/Rust/vvs_ass/src/elements/mod.rs @@ -1,39 +1,27 @@ +mod aux_table; mod line; mod syllabe; -pub use self::{line::*, syllabe::*}; +pub use self::{aux_table::*, line::*, syllabe::*}; use crate::{definitions::ScriptInfoKey, ASSStyle}; use std::collections::HashMap; #[derive(Debug, Clone)] -pub struct ASSContainer { - pub lines: ASSLines, +pub struct ASSContainer<T: AuxTable> { + pub lines: Vec<ASSLine<T>>, pub script_info: HashMap<ScriptInfoKey, String>, pub styles: HashMap<String, ASSStyle>, } -#[derive(Debug, Clone)] -#[repr(transparent)] -pub struct ASSContainerPtr(pub crate::Ptr<ASSContainer>); - -impl ASSContainer { +impl<T: AuxTable> ASSContainer<T> { /// Create an ASS container from its parts, they must be valide! + #[inline] pub(crate) fn from_parts( - lines: impl IntoIterator<Item = ASSLine>, + lines: impl IntoIterator<Item = ASSLine<T>>, script_info: HashMap<ScriptInfoKey, String>, styles: HashMap<String, ASSStyle>, ) -> Self { - Self { - lines: ASSLines(lines.into_iter().map(|line| ASSLinePtr(crate::ptr!(line))).collect()), - script_info, - styles, - } - } -} - -impl From<ASSContainer> for ASSContainerPtr { - fn from(value: ASSContainer) -> Self { - Self(crate::ptr!(value)) + Self { lines: lines.into_iter().collect(), script_info, styles } } } diff --git a/src/Rust/vvs_ass/src/elements/syllabe.rs b/src/Rust/vvs_ass/src/elements/syllabe.rs index 4c098045cfe2de182e5e9b54e8c20922cec6435e..76898ff35df2cf6e1b924ebd9b66127b055777a3 100644 --- a/src/Rust/vvs_ass/src/elements/syllabe.rs +++ b/src/Rust/vvs_ass/src/elements/syllabe.rs @@ -1,78 +1,19 @@ -use crate::{ASSAuxTable, ASSPosition}; +use crate::{ASSPosition, AuxTable}; -#[derive(Debug, Default, Clone, PartialEq)] -pub struct ASSSyllabe { +#[derive(Debug, Default, PartialEq)] +pub struct ASSSyllabe<T: AuxTable> { pub position: ASSPosition, pub content: String, - pub aux: ASSAuxTable, - pub start: i64, - pub fini: i64, + pub aux: T, + pub start: i32, + pub fini: i32, } -#[derive(Debug, Default, Clone)] -#[repr(transparent)] -pub struct ASSSyllabePtr(pub crate::Ptr<ASSSyllabe>); - -#[derive(Debug, Default, Clone)] -#[repr(transparent)] -pub struct ASSSyllabes(pub Vec<ASSSyllabePtr>); - -impl PartialEq for ASSSyllabePtr { - fn eq(&self, other: &Self) -> bool { - *self.0.try_read().unwrap() == *other.0.try_read().unwrap() - } -} - -impl PartialEq for ASSSyllabes { - fn eq(&self, Self(other): &Self) -> bool { - let Self(this) = self; - (this.len() != other.len()) && { - this.iter() - .zip(other.iter()) - .fold(true, |acc, (ASSSyllabePtr(this), ASSSyllabePtr(other))| { - acc && (*this.try_read().unwrap() == *other.try_read().unwrap()) - }) - } - } -} - -impl From<ASSSyllabe> for ASSSyllabePtr { - fn from(value: ASSSyllabe) -> Self { - ASSSyllabePtr(crate::ptr!(value)) - } -} - -impl ASSSyllabes { - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn is_empty(&self) -> bool { - self.0.is_empty() - } - - pub fn push(&mut self, value: impl Into<ASSSyllabePtr>) { - self.0.push(value.into()) - } -} - -impl Extend<ASSSyllabePtr> for ASSSyllabes { - fn extend<T: IntoIterator<Item = ASSSyllabePtr>>(&mut self, iter: T) { - self.0.extend(iter) - } -} - -impl Extend<ASSSyllabe> for ASSSyllabes { - fn extend<T: IntoIterator<Item = ASSSyllabe>>(&mut self, iter: T) { - self.extend(iter.into_iter().map(|syllabe| ASSSyllabePtr(crate::ptr!(syllabe)))) - } -} - -impl IntoIterator for ASSSyllabes { - type Item = ASSSyllabePtr; - type IntoIter = <Vec<ASSSyllabePtr> as IntoIterator>::IntoIter; - - fn into_iter(self) -> Self::IntoIter { - self.0.into_iter() +impl<T: AuxTable> Clone for ASSSyllabe<T> { + fn clone(&self) -> Self { + let Self { position, start, fini, .. } = *self; + let content = self.content.clone(); + let aux = self.aux.deep_clone(); + Self { position, content, aux, start, fini } } } diff --git a/src/Rust/vvs_ass/src/lib.rs b/src/Rust/vvs_ass/src/lib.rs index 59575219123c8918200d5218621b456152507680..ef883672035ccdc5317d3d94cfe8b171291d12f5 100644 --- a/src/Rust/vvs_ass/src/lib.rs +++ b/src/Rust/vvs_ass/src/lib.rs @@ -9,23 +9,9 @@ mod position; mod reader; mod styles; mod types; -mod values; #[cfg(test)] mod tests; -pub use crate::{colors::*, drawing::*, elements::*, position::*, styles::*, types::*, values::*}; +pub use crate::{colors::*, drawing::*, elements::*, position::*, styles::*, types::*}; pub use reader::{ass_container_from_file, ass_container_from_str, ASSElementReaderError, ContainerFileType}; - -pub type Ptr<T> = std::sync::Arc<std::sync::RwLock<T>>; - -#[macro_export] -macro_rules! ptr { - ($expr: expr) => { - std::sync::Arc::new(std::sync::RwLock::new($expr)) - }; -} - -/// A trait to parameterize the ASS element types. It can be a mutable pointer (Arc<RwLock>), a -/// pointer to a constant thing (Arc) or no pointer at all (just the ASS element). -pub trait ASSPtr<T>: std::ops::Deref<Target = T> {} diff --git a/src/Rust/vvs_ass/src/position.rs b/src/Rust/vvs_ass/src/position.rs index bc335d235b228340a98591e5d0518edee28b60ab..1f9c49868fd8050036c45fb452501163c6eb7817 100644 --- a/src/Rust/vvs_ass/src/position.rs +++ b/src/Rust/vvs_ass/src/position.rs @@ -53,6 +53,7 @@ pub type ASSPositionPtr = std::sync::Arc<ASSPosition>; impl std::str::FromStr for ASSAlign { type Err = String; + #[inline] fn from_str(s: &str) -> Result<Self, Self::Err> { match s.trim() { "1" => Ok(ASSAlign::BL), @@ -70,12 +71,14 @@ impl std::str::FromStr for ASSAlign { } impl From<vvs_font::Point> for ASSPosition { + #[inline] fn from(vvs_font::Point { x, y }: vvs_font::Point) -> Self { ASSPosition::Pos { x, y } } } impl ASSPosition { + #[inline] pub fn into_ptr(self) -> ASSPositionPtr { std::sync::Arc::new(self) } diff --git a/src/Rust/vvs_ass/src/reader/ass.rs b/src/Rust/vvs_ass/src/reader/ass.rs index 77c1425508eaa808a62935e72e6d18a2d79fe13a..d3a95ae7a6a7cedb13d0c18b0f7d82439e2d9594 100644 --- a/src/Rust/vvs_ass/src/reader/ass.rs +++ b/src/Rust/vvs_ass/src/reader/ass.rs @@ -1,8 +1,4 @@ -use crate::{ - definitions::{ASSEvent, ASSFileSection, ScriptInfoKey}, - reader::ASSElementReader, - ASSColor, ASSContainer, ASSElementReaderError, ASSLine, ASSStyle, -}; +use crate::{definitions::*, reader::ASSElementReader, *}; use std::collections::HashMap; use vvs_procmacro::EnumVariantFromStr; @@ -76,9 +72,9 @@ impl<'a, K: Eq + Copy + std::hash::Hash + std::fmt::Debug> UnwrapHashMap<'a, K> name: &str, ) -> Result<T, ASSElementReaderError> { let Self(hashmap) = self; - let element = hashmap.get(&key).ok_or(ASSElementReaderError::Custom(format!( - "failed to find entry with key {key:?}" - )))?; + let element = hashmap + .get(&key) + .ok_or(ASSElementReaderError::Custom(format!("failed to find entry with key {key:?}")))?; parser(element, name) } @@ -117,9 +113,7 @@ fn parse_boolean(boolean: &str, name: &str) -> Result<bool, ASSElementReaderErro match boolean.trim() { "-1" | "1" | "+1" => Ok(true), "0" => Ok(false), - boolean => Err(ASSElementReaderError::Custom(format!( - "invalid ass boolean for {name} found: {boolean}" - ))), + boolean => Err(ASSElementReaderError::Custom(format!("invalid ass boolean for {name} found: {boolean}"))), } } @@ -129,13 +123,13 @@ fn parse_float(float: &str, name: &str) -> Result<f64, ASSElementReaderError> { .map_err(|err| ASSElementReaderError::Custom(format!("invalid float value for {name}: {err}"))) } -fn parse_int(int: &str, name: &str) -> Result<i64, ASSElementReaderError> { - int.parse::<i64>() +fn parse_int(int: &str, name: &str) -> Result<i32, ASSElementReaderError> { + int.parse::<i32>() .map_err(|err| ASSElementReaderError::Custom(format!("invalid integer value for {name}: {err}"))) } /// Parse dates in the `0:00:00:00` format -fn parse_date(date: &str, name: &str) -> Result<i64, ASSElementReaderError> { +fn parse_date(date: &str, name: &str) -> Result<i32, ASSElementReaderError> { let std_err = "invalid date for {name}, expected \"h:mm:ss.cc\", got {date:?}".to_string(); let [h, m, sc] = &date.split(':').collect::<Vec<_>>()[..] else { return Err(ASSElementReaderError::Custom(std_err)); @@ -149,7 +143,7 @@ fn parse_date(date: &str, name: &str) -> Result<i64, ASSElementReaderError> { } else { Ok(str.parse::<u16>().map_err(|err| { ASSElementReaderError::Custom(format!("invalid component {compnent} for date {name}: {err}")) - })? as i64) + })? as i32) } }; let (h, m, s, c) = ( @@ -164,9 +158,7 @@ fn parse_date(date: &str, name: &str) -> Result<i64, ASSElementReaderError> { impl ASSReader { fn read_script_info(&mut self, line: &str) -> Result<(), ASSElementReaderError> { let Some((key, value)) = line.split_once(':') else { - return Err(ASSElementReaderError::Custom(format!( - "invalid script info line: {line}" - ))); + return Err(ASSElementReaderError::Custom(format!("invalid script info line: {line}"))); }; let value = value.trim(); let key = match key @@ -187,9 +179,9 @@ impl ASSReader { key => key, }; match self.script_info.get(&key) { - Some(_) => Err(ASSElementReaderError::Custom(format!( - "redefinition of key '{key:?}' in script info section" - ))), + Some(_) => { + Err(ASSElementReaderError::Custom(format!("redefinition of key '{key:?}' in script info section"))) + } None => { self.script_info.insert(key, value.to_string()); Ok(()) @@ -198,6 +190,8 @@ impl ASSReader { } fn read_v4_style(&mut self, line: &str) -> Result<(), ASSElementReaderError> { + use V4PlusStyleFields::*; + let line = if line.starts_with("Format:") { let line = line.split_once(':').unwrap().1.trim(); self.styles_format = line @@ -220,57 +214,49 @@ impl ASSReader { let fields: UnwrapHashMap<V4PlusStyleFields> = UnwrapHashMap(HashMap::from_iter(self.styles_format.iter().copied().zip(fields))); - let encoding = fields.get(V4PlusStyleFields::Encoding); + let encoding = fields.get(Encoding); if encoding.ne("1") { - return Err(ASSElementReaderError::Custom(format!( - "we expected the encoding '1', got: {encoding}" - ))); + return Err(ASSElementReaderError::Custom(format!("we expected the encoding '1', got: {encoding}"))); } - let name = fields.get(V4PlusStyleFields::Name); + let name = fields.get(Name); let style = ASSStyle { name: name.to_string(), - font_name: fields.get(V4PlusStyleFields::Fontname).to_string(), - font_size: fields.parsed(V4PlusStyleFields::Fontsize, parse_int, "font size")?, - primary_color: fields.parsed(V4PlusStyleFields::PrimaryColour, parse_color, "primary")?, - secondary_color: fields.parsed(V4PlusStyleFields::SecondaryColour, parse_color, "secondary")?, - outline_color: fields.parsed(V4PlusStyleFields::OutlineColour, parse_color, "outline")?, - back_color: fields.parsed(V4PlusStyleFields::BackColour, parse_color, "back")?, - bold: fields.parsed(V4PlusStyleFields::Bold, parse_boolean, "bold")?, - italic: fields.parsed(V4PlusStyleFields::Italic, parse_boolean, "italic")?, - underline: fields.parsed(V4PlusStyleFields::Underline, parse_boolean, "underline")?, - strikeout: fields.parsed(V4PlusStyleFields::StrikeOut, parse_boolean, "strikeout")?, - scale_x: fields.parsed(V4PlusStyleFields::ScaleX, parse_float, "scale_x")?, - scale_y: fields.parsed(V4PlusStyleFields::ScaleY, parse_float, "scale_y")?, - spacing: fields.parsed(V4PlusStyleFields::Spacing, parse_float, "spacing")?, - angle: fields.parsed(V4PlusStyleFields::Angle, parse_float, "angle")?, - border_style: fields - .get(V4PlusStyleFields::BorderStyle) - .parse() - .map_err(ASSElementReaderError::Custom)?, - outline: fields.parsed(V4PlusStyleFields::Outline, parse_float, "outline")?, - shadow: fields.parsed(V4PlusStyleFields::Shadow, parse_float, "shadow")?, - alignment: fields - .get(V4PlusStyleFields::Alignment) - .parse() - .map_err(ASSElementReaderError::Custom)?, - margin_l: fields.parsed(V4PlusStyleFields::MarginL, parse_int, "margin_l")?, - margin_r: fields.parsed(V4PlusStyleFields::MarginR, parse_int, "margin_r")?, - margin_v: fields.parsed(V4PlusStyleFields::MarginV, parse_int, "margin_v")?, + font_name: fields.get(Fontname).to_string(), + font_size: fields.parsed(Fontsize, parse_int, "font size")?, + primary_color: fields.parsed(PrimaryColour, parse_color, "primary")?, + secondary_color: fields.parsed(SecondaryColour, parse_color, "secondary")?, + outline_color: fields.parsed(OutlineColour, parse_color, "outline")?, + back_color: fields.parsed(BackColour, parse_color, "back")?, + bold: fields.parsed(Bold, parse_boolean, "bold")?, + italic: fields.parsed(Italic, parse_boolean, "italic")?, + underline: fields.parsed(Underline, parse_boolean, "underline")?, + strikeout: fields.parsed(StrikeOut, parse_boolean, "strikeout")?, + scale_x: fields.parsed(ScaleX, parse_float, "scale_x")?, + scale_y: fields.parsed(ScaleY, parse_float, "scale_y")?, + spacing: fields.parsed(Spacing, parse_float, "spacing")?, + angle: fields.parsed(Angle, parse_float, "angle")?, + border_style: fields.get(BorderStyle).parse().map_err(ASSElementReaderError::Custom)?, + outline: fields.parsed(Outline, parse_float, "outline")?, + shadow: fields.parsed(Shadow, parse_float, "shadow")?, + alignment: fields.get(Alignment).parse().map_err(ASSElementReaderError::Custom)?, + margin_l: fields.parsed(MarginL, parse_int, "margin_l")?, + margin_r: fields.parsed(MarginR, parse_int, "margin_r")?, + margin_v: fields.parsed(MarginV, parse_int, "margin_v")?, }; match self.styles.insert(name.to_string(), style) { None => Ok(()), Some(old) => { log::error!(target: "ass", "redefine style '{name}', previous style was: {old:#?}"); - Err(ASSElementReaderError::Custom(format!( - "redefinition of style '{name}'" - ))) + Err(ASSElementReaderError::Custom(format!("redefinition of style '{name}'"))) } } } fn read_event(&mut self, line: &str) -> Result<(), ASSElementReaderError> { + use EventFields::*; + let line = if line.starts_with("Format:") { let line = line.split_once(':').unwrap().1.trim(); self.events_format = line @@ -278,11 +264,8 @@ impl ASSReader { .flat_map(|str| str.trim().parse::<EventFields>()) .collect(); return match self.events_format.last() { - Some(EventFields::Text) => Ok(()), - _ => Err(ASSElementReaderError::Custom(format!( - "invalid format line: {:?}", - self.events_format - ))), + Some(Text) => Ok(()), + _ => Err(ASSElementReaderError::Custom(format!("invalid format line: {:?}", self.events_format))), }; } else { line.split_once(':').unwrap().1.trim() @@ -302,21 +285,23 @@ impl ASSReader { .zip(fields.into_iter().map(|s| s.trim())), )); self.events.push(ASSEvent { - marked: fields.parsed_or(EventFields::Marked, parse_boolean, "marked", false), - layer: fields.parsed_or(EventFields::Layer, parse_int, "layer", 0), - start: fields.parsed(EventFields::Start, parse_date, "start")?, - end: fields.parsed(EventFields::End, parse_date, "end")?, - style: fields.get_or(EventFields::Style, "Default").to_string(), - name: fields.get_or(EventFields::Name, "").to_string(), - effect: fields.get_or(EventFields::Effect, "").to_string(), - text: fields.get(EventFields::Text).to_string(), + marked: fields.parsed_or(Marked, parse_boolean, "marked", false), + layer: fields.parsed_or(Layer, parse_int, "layer", 0), + start: fields.parsed(Start, parse_date, "start")?, + end: fields.parsed(End, parse_date, "end")?, + style: fields.get_or(Style, "Default").to_string(), + name: fields.get_or(Name, "").to_string(), + effect: fields.get_or(Effect, "").to_string(), + text: fields.get(Text).to_string(), }); Ok(()) } } -impl ASSElementReader for ASSReader { - fn try_read(mut self, file: impl std::io::BufRead) -> Result<ASSContainer, ASSElementReaderError> { +impl<T: AuxTable> ASSElementReader<T> for ASSReader { + fn try_read(mut self, file: impl std::io::BufRead) -> Result<ASSContainer<T>, ASSElementReaderError> { + use ASSFileSection::*; + // Parse the file let mut skip_that_section = false; for line in file.lines() { @@ -337,9 +322,9 @@ impl ASSElementReader for ASSReader { }; } else if !skip_that_section { match self.section { - Some(ASSFileSection::ScriptInfo) => self.read_script_info(line)?, - Some(ASSFileSection::V4Styles) => self.read_v4_style(line)?, - Some(ASSFileSection::Events) => self.read_event(line)?, + Some(ScriptInfo) => self.read_script_info(line)?, + Some(V4Styles) => self.read_v4_style(line)?, + Some(Events) => self.read_event(line)?, None => { return Err(ASSElementReaderError::Custom(format!( "found the following line without a section: {line}" diff --git a/src/Rust/vvs_ass/src/reader/json.rs b/src/Rust/vvs_ass/src/reader/json.rs index b6df22660a63567121c6baed741b698cba79d07c..fb12dbc45755e4e69e0307468ede9dd3c24ab85b 100644 --- a/src/Rust/vvs_ass/src/reader/json.rs +++ b/src/Rust/vvs_ass/src/reader/json.rs @@ -1,12 +1,12 @@ -use crate::{reader::ASSElementReader, ASSContainer, ASSElementReaderError}; +use crate::{reader::ASSElementReader, ASSContainer, ASSElementReaderError, AuxTable}; /// Documentation available here: http://www.tcax.org/docs/ass-specs.html or in the `utils/manual` /// folder. #[derive(Debug, Default)] pub struct JSONReader {} -impl ASSElementReader for JSONReader { - fn try_read(self, _file: impl std::io::BufRead) -> Result<ASSContainer, ASSElementReaderError> { +impl<T: AuxTable> ASSElementReader<T> for JSONReader { + fn try_read(self, _file: impl std::io::BufRead) -> Result<ASSContainer<T>, ASSElementReaderError> { todo!() } } diff --git a/src/Rust/vvs_ass/src/reader/mod.rs b/src/Rust/vvs_ass/src/reader/mod.rs index 70f904a9d664113a6fb22452e74cb29a5cff7591..b2165a0588c28fa4a5255071fdc6bb1fda8084b7 100644 --- a/src/Rust/vvs_ass/src/reader/mod.rs +++ b/src/Rust/vvs_ass/src/reader/mod.rs @@ -1,7 +1,7 @@ //! Read the content of an ASS file / a Vivy subtitle file and creates an //! [vvs_ass::elements::lines::ASSLinesPtr] structure accordingly. -use crate::ASSContainer; +use crate::{ASSContainer, AuxTable}; use std::{ fs::File, io::{BufReader, Error as IoError}, @@ -38,11 +38,11 @@ pub enum ASSElementReaderError { Custom(String), } -trait ASSElementReader { - fn try_read(self, file: impl std::io::BufRead) -> Result<ASSContainer, ASSElementReaderError>; +trait ASSElementReader<T: AuxTable> { + fn try_read(self, file: impl std::io::BufRead) -> Result<ASSContainer<T>, ASSElementReaderError>; } -pub fn ass_container_from_file(file: impl AsRef<Path>) -> Result<ASSContainer, ASSElementReaderError> { +pub fn ass_container_from_file<T: AuxTable>(file: impl AsRef<Path>) -> Result<ASSContainer<T>, ASSElementReaderError> { let file = file.as_ref(); let Some(extension) = file.extension() else { return Err(ASSElementReaderError::NoExtension(file.to_path_buf())); @@ -57,10 +57,10 @@ pub fn ass_container_from_file(file: impl AsRef<Path>) -> Result<ASSContainer, A } } -pub fn ass_container_from_str( +pub fn ass_container_from_str<T: AuxTable>( extension: ContainerFileType, str: impl AsRef<str>, -) -> Result<ASSContainer, ASSElementReaderError> { +) -> Result<ASSContainer<T>, ASSElementReaderError> { use ContainerFileType::*; let content = BufReader::new(str.as_ref().as_bytes()); match extension { diff --git a/src/Rust/vvs_ass/src/styles.rs b/src/Rust/vvs_ass/src/styles.rs index 81252927a34c624b9c392c61bd352438f1d9073b..612e64df91a186d653dc23e95d376cb0b0d7d654 100644 --- a/src/Rust/vvs_ass/src/styles.rs +++ b/src/Rust/vvs_ass/src/styles.rs @@ -17,7 +17,7 @@ pub struct ASSStyle { pub font_name: String, /// The size of the font. Don't use a thing that is too big... Must be positive. - pub font_size: i64, + pub font_size: i32, /// The colour that a subtitle will normally appear in. pub primary_color: ASSColor, @@ -84,23 +84,24 @@ pub struct ASSStyle { /// subtitle text will be displayed. /// /// Must be a positive integer. - pub margin_l: i64, + pub margin_l: i32, /// This defines the Right Margin in pixels. It is the distance from the right-hand edge of the /// screen. The three onscreen margins (margin_l, margin_r, margin_v) define areas in which the /// subtitle text will be displayed. - pub margin_r: i64, + pub margin_r: i32, /// This defines the vertical Left Margin in pixels. /// - For a subtitle, it is the distance from the bottom of the screen. /// - For a toptitle, it is the distance from the top of the screen. /// - For a midtitle, the value is ignored - the text will be vertically centred - pub margin_v: i64, + pub margin_v: i32, } impl std::str::FromStr for ASSBorderStyle { type Err = String; + #[inline] fn from_str(s: &str) -> Result<Self, Self::Err> { match s.trim() { "1" => Ok(ASSBorderStyle::OutlineAndDropShadow), @@ -111,10 +112,12 @@ impl std::str::FromStr for ASSBorderStyle { } impl ASSStyle { + #[inline] pub fn default_name() -> &'static str { "Default" } + #[inline] pub fn default_name_string() -> String { Self::default_name().to_string() } @@ -122,9 +125,19 @@ impl ASSStyle { impl Default for ASSStyle { fn default() -> Self { + let font = vvs_font::embeded_fonts() + .first() + .expect("we should at least bundle one font"); + let font = vvs_font::Font::try_from(font.1).expect("the font we bundle is not valid"); + let font_name = font.name().expect("the font we bundle doesn't have a valid name"); + match &font.font_types()[..] { + [vvs_font::FontType::Regular] => {} + _ => panic!("the font we bundle is not regular"), + } + Self { name: Self::default_name_string(), - font_name: Default::default(), + font_name, font_size: 14, primary_color: ASSColor::WHITE, secondary_color: ASSColor::RED, diff --git a/src/Rust/vvs_ass/src/tests.rs b/src/Rust/vvs_ass/src/tests.rs index 12c6ec72cd1c0f35d88dffac3c7e80cfc8793a51..a85f04b45e8538a8062479eac96174e6a81dbbfe 100644 --- a/src/Rust/vvs_ass/src/tests.rs +++ b/src/Rust/vvs_ass/src/tests.rs @@ -1,3 +1,5 @@ +use crate::*; + mod color { use crate::*; @@ -32,10 +34,7 @@ mod color { assert!(ASSColor::try_from_rgba("AABBCC").is_ok()); assert!(ASSColor::try_from_rgba("AABBCCAA").is_ok()); - assert_eq!( - ASSColor::try_from_rgba("AABBCC").unwrap(), - ASSColor::try_from_bgra("CCBBAA").unwrap() - ); + assert_eq!(ASSColor::try_from_rgba("AABBCC").unwrap(), ASSColor::try_from_bgra("CCBBAA").unwrap()); } #[test] @@ -46,18 +45,9 @@ mod color { let ASSColor::HSLA { h, s, l, .. } = ASSColor::try_from_rgba(rgb).unwrap().into_hsla() else { unreachable!() }; - assert!( - (h_target - h).abs() <= EPSILON_DEG, - "invalid convertion for color #{rgb}, hue {h_target} != {h}" - ); - assert!( - (s - s1_target).abs() <= EPSILON_0_1, - "invalid convertion for color #{rgb}, s {s1_target} != {s}" - ); - assert!( - (l - l1_target).abs() <= EPSILON_0_1, - "invalid convertion for color #{rgb}, l {l1_target} != {l}" - ); + assert!((h_target - h).abs() <= EPSILON_DEG, "invalid convertion for color #{rgb}, hue {h_target} != {h}"); + assert!((s - s1_target).abs() <= EPSILON_0_1, "invalid convertion for color #{rgb}, s {s1_target} != {s}"); + assert!((l - l1_target).abs() <= EPSILON_0_1, "invalid convertion for color #{rgb}, l {l1_target} != {l}"); } } @@ -81,13 +71,21 @@ mod color { eq! { b_target, b, "invalid convertion on blue for #{rgb}: {b_target} != {b}"} } } +} - #[test] - fn test_parse_empty_ass() { - use crate::reader::ass_container_from_str; - let content = include_str!("../utils/empty.ass"); - if let Err(err) = ass_container_from_str(reader::ContainerFileType::ASS, content) { - panic!("{err}") +#[test] +fn test_parse_empty_ass() { + #[derive(Default, Clone, Copy, PartialEq, Eq)] + struct AT(); + impl AuxTable for AT { + fn deep_clone(&self) -> Self { + *self } } + + if let Err(err) = + reader::ass_container_from_str::<AT>(reader::ContainerFileType::ASS, include_str!("../utils/empty.ass")) + { + panic!("{err}") + } } diff --git a/src/Rust/vvs_ass/src/types.rs b/src/Rust/vvs_ass/src/types.rs index a3db26679a57b7879c7fd8862234d71f22f707c8..f217f8a47848b95724ce53efb05df7ac03b9ca47 100644 --- a/src/Rust/vvs_ass/src/types.rs +++ b/src/Rust/vvs_ass/src/types.rs @@ -50,6 +50,7 @@ pub enum ASSType { impl ASSType { /// Get the name of the ASS type. + #[inline] pub fn as_str(&self) -> &'static str { match self { ASSType::Lines => "lines", @@ -60,6 +61,7 @@ impl ASSType { } /// Get the name of the type, but padded with spaces. + #[inline] pub fn as_padded_str(&self) -> &'static str { match self { ASSType::Lines => "lines ", @@ -70,6 +72,7 @@ impl ASSType { } /// Returns the base type. + #[inline] pub fn base_type(&self) -> Self { match self { ASSType::Lines | ASSType::Line => ASSType::Line, @@ -78,6 +81,7 @@ impl ASSType { } /// Returns the vec type. + #[inline] pub fn vec_type(&self) -> Self { match self { ASSType::Lines | ASSType::Line => ASSType::Lines, @@ -87,12 +91,14 @@ impl ASSType { } impl AsRef<str> for ASSType { + #[inline] fn as_ref(&self) -> &str { self.as_str() } } impl std::fmt::Display for ASSType { + #[inline] fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str(self.as_str()) } diff --git a/src/Rust/vvs_ass/src/values.rs b/src/Rust/vvs_ass/src/values.rs deleted file mode 100644 index 32a1681984392632070e14ada2b58787f6570096..0000000000000000000000000000000000000000 --- a/src/Rust/vvs_ass/src/values.rs +++ /dev/null @@ -1,200 +0,0 @@ -use serde::{Deserialize, Serialize}; -use std::{collections::HashMap, convert::TryFrom}; - -/// The values that can be added to an ASS element. -#[derive(Clone, PartialEq, Serialize, Deserialize)] -pub enum ASSAuxValue { - Integer(i64), - Floating(f64), - Boolean(bool), - String(String), -} - -/// The auxiliary table of user values associated to ASS elements. -#[derive(Debug, Default, Clone, PartialEq)] -pub struct ASSAuxTable(HashMap<String, ASSAuxValue>); - -impl std::fmt::Debug for ASSAuxValue { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::Integer(arg0) => write!(f, "{arg0}"), - Self::Floating(arg0) => write!(f, "{arg0}"), - Self::String(arg0) => write!(f, "{arg0:?}"), - Self::Boolean(arg0) => write!(f, "{arg0}"), - } - } -} - -impl ASSAuxValue { - pub fn type_str(&self) -> &'static str { - match self { - ASSAuxValue::Floating(_) => "floating", - ASSAuxValue::Integer(_) => "integer", - ASSAuxValue::Boolean(_) => "boolean", - ASSAuxValue::String(_) => "string", - } - } - - pub fn coerce_like(self, like: &ASSAuxValue) -> Option<ASSAuxValue> { - use ASSAuxValue::*; - match (&self, like) { - (Floating(_), Floating(_)) - | (Integer(_), Integer(_)) - | (Boolean(_), Boolean(_)) - | (String(_), String(_)) => Some(self), - - (Integer(v), Floating(_)) => Some(Floating(i32::try_from(*v).ok()? as f64)), - (Integer(0), Boolean(_)) => Some(Boolean(false)), - (Integer(_), Boolean(_)) => Some(Boolean(true)), - - (Boolean(v), String(_)) => Some(String(format!("{v}"))), - (Integer(v), String(_)) => Some(String(format!("{v}"))), - (Floating(v), String(_)) => Some(String(format!("{v}"))), - - (Boolean(v), Integer(_)) => Some(Integer(*v as i64)), - - (String(_), Integer(_)) => todo!(), - (String(_), Floating(_)) => todo!(), - (String(_), Boolean(_)) => todo!(), - - (Floating(_), Integer(_)) | (Floating(_), Boolean(_)) | (Boolean(_), Floating(_)) => { - log::error!(target: "lua", "invalid convertion from type `{}` to `{}`", self.type_str(), like.type_str()); - None - } - } - } -} - -impl From<String> for ASSAuxValue { - fn from(value: String) -> Self { - Self::String(value) - } -} - -impl From<&str> for ASSAuxValue { - fn from(value: &str) -> Self { - Self::String(value.to_string()) - } -} - -impl From<bool> for ASSAuxValue { - fn from(value: bool) -> Self { - Self::Boolean(value) - } -} - -impl From<f32> for ASSAuxValue { - fn from(value: f32) -> Self { - Self::Floating(value as f64) - } -} - -impl From<f64> for ASSAuxValue { - fn from(value: f64) -> Self { - Self::Floating(value) - } -} - -impl From<i64> for ASSAuxValue { - fn from(value: i64) -> Self { - Self::Integer(value) - } -} - -impl From<i32> for ASSAuxValue { - fn from(value: i32) -> Self { - Self::Integer(value as i64) - } -} - -impl From<u32> for ASSAuxValue { - fn from(value: u32) -> Self { - Self::Integer(value as i64) - } -} - -impl From<i16> for ASSAuxValue { - fn from(value: i16) -> Self { - Self::Integer(value as i64) - } -} - -impl From<u16> for ASSAuxValue { - fn from(value: u16) -> Self { - Self::Integer(value as i64) - } -} - -impl From<i8> for ASSAuxValue { - fn from(value: i8) -> Self { - Self::Integer(value as i64) - } -} - -impl From<u8> for ASSAuxValue { - fn from(value: u8) -> Self { - Self::Integer(value as i64) - } -} - -impl std::fmt::Display for ASSAuxValue { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - ASSAuxValue::Floating(val) => write!(f, "{val}"), - ASSAuxValue::Integer(val) => write!(f, "{val}"), - ASSAuxValue::Boolean(val) => write!(f, "{val}"), - ASSAuxValue::String(val) => f.write_str(val), - } - } -} - -impl ASSAuxTable { - pub fn new() -> Self { - Default::default() - } - - pub fn set(&mut self, name: impl AsRef<str>, value: ASSAuxValue) { - let name = name.as_ref(); - let new = value.type_str(); - match self.0.get_mut(name) { - Some(old) => match value.coerce_like(old) { - Some(new) => *old = new, - None => log::error!( - target: "lua", - "can't set new value for `{name}`, old value was of type `{}` and new one is of type `{new}`", - old.type_str() - ), - }, - None => { - let _ = self.0.insert(name.to_string(), value); - } - } - } - - pub fn get_copy(&self, name: impl AsRef<str>) -> Option<ASSAuxValue> { - self.0.get(name.as_ref()).cloned() - } - - pub fn get(&self, name: impl AsRef<str>) -> Option<&ASSAuxValue> { - self.0.get(name.as_ref()) - } - - pub fn get_mut(&mut self, name: impl AsRef<str>) -> Option<&mut ASSAuxValue> { - self.0.get_mut(name.as_ref()) - } -} - -impl IntoIterator for ASSAuxTable { - type Item = <HashMap<String, ASSAuxValue> as IntoIterator>::Item; - type IntoIter = <HashMap<String, ASSAuxValue> as IntoIterator>::IntoIter; - - fn into_iter(self) -> Self::IntoIter { - self.0.into_iter() - } -} - -impl FromIterator<(String, ASSAuxValue)> for ASSAuxTable { - fn from_iter<T: IntoIterator<Item = (String, ASSAuxValue)>>(iter: T) -> Self { - Self(HashMap::from_iter(iter)) - } -} diff --git a/src/Rust/vvs_cli/Cargo.toml b/src/Rust/vvs_cli/Cargo.toml index 004cbf2662f52157f3948e890c96e9a6f7a4e83f..2f958d4b5ed1a8990f181b679817732f416b352b 100644 --- a/src/Rust/vvs_cli/Cargo.toml +++ b/src/Rust/vvs_cli/Cargo.toml @@ -11,26 +11,23 @@ name = "vvcc" path = "src/main.rs" [dependencies] -vvs_font = { path = "../vvs_font" } -vvs_utils = { path = "../vvs_utils" } +vvs_ass.workspace = true +vvs_font.workspace = true +vvs_utils.workspace = true +vvs_parser.workspace = true +vvs_runtime.workspace = true +vvs_codegen.workspace = true thiserror.workspace = true -anyhow.workspace = true -serde.workspace = true -toml.workspace = true -log.workspace = true +anyhow.workspace = true +serde.workspace = true +toml.workspace = true +log.workspace = true -clap_mangen = "^0.2" -clap_complete = "^4" -clap = { version = "^4", default-features = false, features = [ - "usage", - "help", - "std", - "suggestions", - "error-context", - "derive", - "wrap_help", -] } +clap_mangen.workspace = true +clap_complete.workspace = true +clap.workspace = true -[target.'cfg(unix)'.dependencies] -# vvs_repl = { path = "../vvs_repl" } +[build-dependencies] +anyhow.workspace = true +vvs_llvm.workspace = true diff --git a/src/Rust/vvs_cli/build.rs b/src/Rust/vvs_cli/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..a01480722a65c2a0de92058e860bdc41610328d4 --- /dev/null +++ b/src/Rust/vvs_cli/build.rs @@ -0,0 +1,3 @@ +fn main() -> anyhow::Result<()> { + vvs_llvm::build::llvm_link() +} diff --git a/src/Rust/vvs_cli/src/args.rs b/src/Rust/vvs_cli/src/args.rs index 1c1d6343e8644ad1147bb0660d34fac8fefd0911..9f75870f5beebbeed4763fa6fe89b713cedea39d 100644 --- a/src/Rust/vvs_cli/src/args.rs +++ b/src/Rust/vvs_cli/src/args.rs @@ -2,44 +2,17 @@ use crate::parser::FileTypeValueParser; use clap::Parser; use clap_complete::Shell; use std::path::PathBuf; -use vvs_utils::*; - -fn get_cli_groups() -> impl IntoIterator<Item = clap::ArgGroup> { - #[cfg(unix)] - fn is_unix_target() -> bool { - true - } - #[cfg(not(unix))] - fn is_unix_target() -> bool { - false - } - - use clap::ArgGroup as grp; - [ - grp::new("action").args(["manpage", "shell", "font-file", "script.vvs"]), - grp::new("ass") - .args(["subtitle.ass"]) - .conflicts_with_all(["manpage", "font-file"]), - grp::new("opts") - .args(["options.toml"]) - .conflicts_with_all(["shell", "manpage", "font-file"]), - grp::new("infos") - .args(["info"]) - .conflicts_with_all(["shell", "manpage", "font-file"]), - ] - .into_iter() - .chain(either!(!is_unix_target() => None; Some( - clap::ArgGroup::new("repl") .args(["interactive"]) .conflicts_with_all(["shell", "manpage", "font-file"]) - ))) -} #[derive(Parser, Debug)] #[command( author , version , about - , name = "vvcc" - , groups = get_cli_groups() -)] + , name = "vvcc" + , groups = [ clap::ArgGroup::new("action").args(["manpage", "shell", "font-file", "script.vvs"]) + , clap::ArgGroup::new("ass") .args(["subtitle.ass"]).conflicts_with_all(["manpage", "font-file"]) + , clap::ArgGroup::new("opts") .args(["options.ini"]) .conflicts_with_all(["shell", "manpage", "font-file"]) + , clap::ArgGroup::new("infos") .args(["info"]) .conflicts_with_all(["shell", "manpage", "font-file"]) +])] pub struct Args { /// The script to run. /// @@ -68,8 +41,8 @@ pub struct Args { #[arg( short = 't' , long = "option" , action = clap::ArgAction::Set - , id = "options.toml" - , value_parser = FileTypeValueParser::new("toml") + , id = "options.ini" + , value_parser = FileTypeValueParser::new("ini") )] pub options: Option<PathBuf>, @@ -85,17 +58,6 @@ pub struct Args { )] pub include_folders: Vec<PathBuf>, - /// Launch vvcc REPL after loading the passed script if any. - /// - /// In REPL mode you must not touch to fields that begins by underscores, never. Those fields - /// are reserved for vivy or for library developpers. Note that even library developpers must - /// not touch or call fields from vivy that begins by underscores. - #[cfg(unix)] - #[arg( short = 'i' - , action = clap::ArgAction::SetTrue - )] - pub interactive: bool, - /// Shows informations about a script. /// /// The informations consists of the loaded modules, all the options, their possible values, @@ -129,12 +91,14 @@ pub struct Args { /// `$HOME/.local/share/man/man1/` or `/usr/share/man/man1` folder #[arg( long = "manpage" , action = clap::ArgAction::SetTrue + , hide = true )] pub manpage: bool, /// Generate completion script for the given shell #[arg( long = "shell" , action = clap::ArgAction::Set + , hide = true )] pub shell: Option<Shell>, } diff --git a/src/Rust/vvs_cli/src/config.rs b/src/Rust/vvs_cli/src/config.rs index 38b4d3040d0a292ffbb13e44292f53a289b18d95..0222b83d2f3338f549828a08875c1f2d3d06cfde 100644 --- a/src/Rust/vvs_cli/src/config.rs +++ b/src/Rust/vvs_cli/src/config.rs @@ -29,7 +29,6 @@ pub struct Config { pub script: Option<PathBuf>, pub ass_file: Option<PathBuf>, pub options: Option<PathBuf>, - pub interactive: bool, pub info: bool, pub manpage: bool, pub shell: Option<Shell>, @@ -92,23 +91,26 @@ impl Extend<Args> for Config { append args => self, { include_folders }; set_if_not args => self, { script, ass_file, options, shell, font_info }; max args => self, { verbose }; - override args => self, { info, manpage, interactive }; + override args => self, { info, manpage }; } }); } } impl ConfigFile { + #[inline] pub fn serialize(&self) -> Result<String, Box<dyn std::error::Error>> { Ok(toml::to_string_pretty(self).map_err(Box::new)?) } + #[inline] pub fn deserialize(input: String) -> Result<Self, Box<dyn std::error::Error>> { Ok(toml::from_str(&input).map_err(Box::new)?) } } impl Default for ConfigKaraMaker { + #[inline] fn default() -> Self { Self { kara_maker: "Viieux".to_string(), email: Default::default() } } diff --git a/src/Rust/vvs_cli/src/main.rs b/src/Rust/vvs_cli/src/main.rs index da51848fb4528aff924b7a16f7f1495181a3bbb1..345a2bbe6bd8c4dff0463a6d2cf8b5bd9461c3f8 100644 --- a/src/Rust/vvs_cli/src/main.rs +++ b/src/Rust/vvs_cli/src/main.rs @@ -1,12 +1,18 @@ //! The VivyScript cli -#![forbid(unsafe_code)] -use anyhow::{Context, Result}; +use crate::args::Args; +use anyhow::{anyhow, Context, Result}; +use clap::CommandFactory; +use std::{fs, io}; +use vvs_ass::{ass_container_from_file, ASSContainer}; use vvs_cli::{ args, config::{Config, ConfigFile}, logger, }; +use vvs_codegen::LowererBuilder; +use vvs_parser::prelude::*; +use vvs_runtime::{types::VVRTTable, JIT}; use vvs_utils::xdg::*; fn print_face_info(name: &str, font: &[u8]) -> Result<()> { @@ -20,10 +26,7 @@ fn print_face_info(name: &str, font: &[u8]) -> Result<()> { .join(", "); println!("###"); - println!( - "# Family Name: {}", - font.name().with_context(|| "failed to get the font name")? - ); + println!("# Family Name: {}", font.name().context("failed to get the font name")?); println!("# Name(s): {}", font.family_names().join(", ")); println!("# Font Type(s): {font_types}"); println!("# Number of glyph(s): {}", font.number_of_glyphs()); @@ -32,68 +35,100 @@ fn print_face_info(name: &str, font: &[u8]) -> Result<()> { } fn main() -> Result<()> { - logger::init(None).map_err(Box::new)?; - + logger::init(None).context("failed to init logger")?; let mut config = Config::default(); config.extend([ XDGConfig::<ConfigFile, XDGConfigMergedSilent>::new("vvcc", ConfigFile::deserialize) .file("vvcc.toml") .read_or_default(ConfigFile::serialize), ]); - config.extend([<args::Args as clap::Parser>::parse()]); + config.extend([<Args as clap::Parser>::parse()]); let Config { script, - ass_file: _, - options: _, - #[cfg(unix)] - interactive, - info: _, + ass_file: ass_file_path, + options: options_path, + info, manpage, shell, font_info, verbose, include_folders: _, - .. + kara_maker, } = config; - #[cfg(not(unix))] - let interactive = false; logger::level(verbose); if manpage { log::debug!(target: "vvcc", "generate the manpage for vvcc"); - use clap::CommandFactory; - return clap_mangen::Man::new(args::Args::command()) - .render(&mut std::io::stdout()) - .with_context(|| "failed to render manpage for vvcc"); - } else if let Some(shell) = shell { + return clap_mangen::Man::new(Args::command()) + .render(&mut io::stdout()) + .context("failed to render manpage for vvcc"); + } + + if let Some(shell) = shell { log::debug!(target: "vvcc", "generate shell completion script for shell {shell}"); - use clap::CommandFactory; - let mut command = args::Args::command(); + let mut command = Args::command(); let command_name = command.get_name().to_string(); - clap_complete::generate(shell, &mut command, command_name, &mut std::io::stdout()); + clap_complete::generate(shell, &mut command, command_name, &mut io::stdout()); return Ok(()); - } else if let Some(font_info) = font_info { - match font_info { - Some(path) => { - let font = - std::fs::read(&path).with_context(|| format!("failed to read font: {}", path.to_string_lossy()))?; - print_face_info(&path.to_string_lossy(), &font)?; + } + + if let Some(font_info) = font_info { + return match font_info { + Some(path) => print_face_info( + &path.to_string_lossy(), + &fs::read(&path).with_context(|| format!("failed to read font: {}", path.to_string_lossy()))?, + ), + None => vvs_font::embeded_fonts() + .iter() + .try_for_each(|(n, f)| print_face_info(n, f)), + }; + } + + match script { + None => Args::command() + .print_help() + .context("failed to print help message for vvcc"), + + Some(script) => { + let script = SourceCode::from_path(script)?; + log::info!("run as `{kara_maker}` script `{}`", script.name()); + if let Some(ref options) = options_path { + log::info!("use option file `{}`", options.display()) } - None => { - for (name, font) in vvs_font::embeded_fonts() { - print_face_info(name, font)?; + + let output = FrontendPipeline::new(&script) + .passes(&[]) + .options(options_path.as_ref()) + .context("failed to parse option file")? + .run() + .context("failed to parse script files")?; + + if info { + match ass_file_path { + Some(ref path) => println!("ass file ........... {}", path.display()), + None => println!("ass file ........... ø"), + } + match options_path { + Some(path) => println!("options file ....... {}", path.display()), + None => println!("options file ....... ø"), } + println!("{output}"); } - } - return Ok(()); - } - if script.is_none() && !interactive { - use clap::CommandFactory; - return args::Args::command() - .print_help() - .with_context(|| "failed to print help message for vvcc"); - } + // let FrontendOutput { ast, imports, main, options, library } = output; - Ok(()) + let ass: ASSContainer<VVRTTable> = ass_container_from_file( + ass_file_path.ok_or_else(|| anyhow!("no subtitle file to run the script `{}` on", script.name()))?, + ) + .context("failed to parse the subtitle file")?; + + let jit = JIT::new()?; + let module = unsafe { LowererBuilder::new(script.name(), jit.ctx()) }.build().lower(); + unsafe { jit.add_module(module)? }; + + log::error!("use the ASS container and insert it into the JIT: {ass:#?}"); + + unimplemented!() + } + } } diff --git a/src/Rust/vvs_cli/src/parser.rs b/src/Rust/vvs_cli/src/parser.rs index 21f29bfd2c7dfa81092cf289294bf4102ed88079..1e03bbc71f039064636ad4b9c9eeb5b90120f598 100644 --- a/src/Rust/vvs_cli/src/parser.rs +++ b/src/Rust/vvs_cli/src/parser.rs @@ -42,19 +42,13 @@ impl TypedValueParser for FileTypeValueParser { None => { err.insert( ContextKind::InvalidValue, - ContextValue::String(format!( - "file has no extension, expected extension {}", - self.extension - )), + ContextValue::String(format!("file has no extension, expected extension {}", self.extension)), ); Err(err) } }, None => { - err.insert( - ContextKind::InvalidValue, - ContextValue::String("invalid utf8 string".to_string()), - ); + err.insert(ContextKind::InvalidValue, ContextValue::String("invalid utf8 string".to_string())); Err(err) } } diff --git a/src/Rust/vvs_codegen/Cargo.toml b/src/Rust/vvs_codegen/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..39d9009a8a15a410ccde25c5f138d8af5fb2a3ee --- /dev/null +++ b/src/Rust/vvs_codegen/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "vvs_codegen" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true +description = "The codegen into LLVM for Vivy Script" + +[dependencies] +log.workspace = true +serde.workspace = true +serde_json.workspace = true +anyhow.workspace = true +hashbrown.workspace = true + +vvs_runtime_types.workspace = true +vvs_utils.workspace = true +vvs_llvm.workspace = true +vvs_lang.workspace = true + +[build-dependencies] +vvs_llvm = { workspace = true, features = ["link"] } +anyhow.workspace = true diff --git a/src/Rust/vvs_codegen/build.rs b/src/Rust/vvs_codegen/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..a01480722a65c2a0de92058e860bdc41610328d4 --- /dev/null +++ b/src/Rust/vvs_codegen/build.rs @@ -0,0 +1,3 @@ +fn main() -> anyhow::Result<()> { + vvs_llvm::build::llvm_link() +} diff --git a/src/Rust/vvs_codegen/src/context.rs b/src/Rust/vvs_codegen/src/context.rs new file mode 100644 index 0000000000000000000000000000000000000000..6088a63392892ff5f0a7e8c1600f1e9e7872e4c8 --- /dev/null +++ b/src/Rust/vvs_codegen/src/context.rs @@ -0,0 +1,105 @@ +use crate::Value; +use hashbrown::HashMap; +use vvs_llvm::*; +use vvs_runtime_types::vvll::LLVMTypeIsManaged; + +/// Just a hashmap used to store values in scope. +#[derive(Default, Clone)] +pub(crate) struct ValueContext { + /// The values in context. + values: HashMap<Box<str>, Value>, + + /// The values that are to be droped, in the order of their définition! They must be dropped in + /// the reverse order in which they are stored! + to_drop: Vec<Value>, + + /// The number of anon values present in this context. + anon_count: u64, +} + +impl ValueContext { + /// Create a new sub-context. We clone the available values but not the destructors to run as + /// we don't want to run them too early. + pub fn sub_context(&self) -> Self { + let Self { values, anon_count: i, .. } = self; + Self { values: values.clone(), anon_count: *i, to_drop: vec![] } + } + + /// Register a new value in the context. We don't give a shit about its name, see if we need a + /// destructor for this value. + pub fn register_anon(&mut self, value: Value) { + if let Some(name) = value.as_str() { + let name = format!(".anon.{}:{}", self.anon_count, name); + self.anon_count += 1; + self.register(name, value) + } + } + + /// Clone the context and register a new value into it. Used to reduce a bit calls to clone + /// everywhere... + pub fn to_register(&self, name: impl AsRef<str>, value: Value) -> Self { + let mut this = self.clone(); + this.register(name, value); + this + } + + /// Clone the context and register a new value into it. Used to reduce a bit calls to clone + /// everywhere... + pub fn to_register_anon(&self, value: Value) -> Self { + let mut this = self.clone(); + this.register_anon(value); + this + } + + /// Register a new value in the context. + pub fn register(&mut self, name: impl AsRef<str>, value: Value) { + fn inner(this: &mut ValueContext, name: &str, value: Value) { + log::error!("take into account destructors for {name}"); + if Value::Nil == value { + panic!("can't register nil value `{name}`") + } else if this.values.insert(name.into(), value).is_some() { + panic!("multiple definitions of `{name}`") + } + } + inner(self, name.as_ref(), value) + } + + /// Register a multiple values in the context. + pub fn register_all(&mut self, iter: impl IntoIterator<Item = (impl AsRef<str>, Value)>) { + iter.into_iter().for_each(|(name, value)| self.register(name, value)); + } + + /// Get the values to drop in this context in the order of their definition. Also remove them + /// from this context. + pub fn get_values_to_drop(&mut self) -> Vec<Value> { + std::mem::take(&mut self.to_drop) + } + + /// Forget a value to drop by its llvm value ref. This way we can also forget anon values. + pub fn forget_by_llvm_value(&mut self, value: LLVMValueRef) { + use Value::*; + if let Some(idx) = self.to_drop.iter().enumerate().find_map(|(idx, val)| { + matches!(*val, Const(_, val) | Alloca(_, _, val) | Function(_, _, val) if val == value).then_some(idx) + }) { + self.to_drop.remove(idx); + } + } + + /// Add values to drop from another context to extend their lifetime. We can't fail that thing + /// because we ignore values that are re-registered. + pub fn add_values_to_drop(&mut self, mut values: Vec<Value>) { + values.retain(|v| { + v.llvm_value() + .is_some_and(|v| self.to_drop.iter().any(|u| u.llvm_value().is_some_and(|u| u == v))) + && v.llvm_type().is_some_and(|t| unsafe { LLVMTypeIsManaged(t) }) + }); + self.to_drop.append(&mut values); + } + + /// Get the value by its name in the context, or panic! + pub fn get_value(&self, name: impl AsRef<str>) -> &Value { + self.values + .get(name.as_ref()) + .unwrap_or_else(|| panic!("failed to find value `{}`", name.as_ref())) + } +} diff --git a/src/Rust/vvs_codegen/src/graph.rs b/src/Rust/vvs_codegen/src/graph.rs new file mode 100644 index 0000000000000000000000000000000000000000..51388796c18151008c8f36df269106c662443e36 --- /dev/null +++ b/src/Rust/vvs_codegen/src/graph.rs @@ -0,0 +1,103 @@ +//! Small utility to store a basic block graph of a function to compute dominance of values. + +use hashbrown::HashSet; +use std::{collections::VecDeque, hash::Hash, iter}; + +#[derive(Debug)] +pub(crate) struct Graph<N: Copy + Clone + PartialEq + Eq + Hash> { + /// The nodes of the graph. + content: Vec<N>, + + /// Encodes the edges of the graph. In general we have at most 2 outgoing edges per node (one + /// for test false, one for test true). We should not encounter a switch, or at least not that + /// many... + adjacence: Vec<(usize, usize)>, +} + +impl<N: Copy + Clone + PartialEq + Eq + Hash> Default for Graph<N> { + fn default() -> Self { + Self { content: Vec::default(), adjacence: Vec::default() } + } +} + +impl<N: Copy + Clone + PartialEq + Eq + Hash> Graph<N> { + /// Create a new empty graph but with a given capacity. + pub fn with_capacity(capacity: usize) -> Self { + Self { content: Vec::with_capacity(capacity), adjacence: Vec::with_capacity(capacity.saturating_mul(2)) } + } + + /// Insert a new node in the graph. If the node is already present we do nothing. + pub fn add_node(mut self, node: N) -> Self { + if !self.content.contains(&node) { + self.content.push(node); + } + self + } + + /// Insert a list of nodes in the graph. + pub fn add_nodes(self, nodes: impl IntoIterator<Item = N>) -> Self { + nodes.into_iter().fold(self, |this, node| this.add_node(node)) + } + + /// Insert an edge in the graph. If the edge already exists we do nothing. + pub fn add_edge(mut self, from: N, to: N) -> Self { + let (from, to) = (self.node_index(from), self.node_index(to)); + if !self.adjacence.iter().any(|(ef, et)| *ef == from && *et == to) { + self.adjacence.push((from, to)); + } + self + } + + /// Find the index of a node in the graph or panic! + fn node_index(&self, node: N) -> usize { + self.content + .iter() + .enumerate() + .find_map(|(idx, n)| (*n == node).then_some(idx)) + .expect("failed to find node") + } + + /// Get all the direct next nodes from a given node. + fn nexts(&self, from: N) -> Vec<N> { + let node = self.node_index(from); + self.adjacence + .iter() + .filter(|&&(from, _)| (from == node)) + .map(|&(_, to)| self.content[to]) + .collect() + } + + /// Returns all the nodes in all the simple paths between two nodes. The nodes can be the same, + /// in this case we return only this node. When computing the the paths we don't take loop edges. + pub fn any_path_content(&self, from: N, to: N) -> HashSet<N> { + // Don't ever reallocate. + let mut visited = VecDeque::with_capacity(self.content.len()); + let mut stack = Vec::with_capacity(self.content.len()); + let mut ret = HashSet::with_capacity(self.content.len()); + + // Init the state. + visited.push_front(from); + stack.push(self.nexts(from)); + + // Just do the search. + while let Some(children) = stack.last_mut() { + match children.pop() { + Some(child) if child == to => { + ret.extend(visited.iter().copied().chain(iter::once(to))); + } + Some(child) if !visited.contains(&child) => { + visited.push_front(child); + stack.push(self.nexts(child)); + } + Some(_visited_child) => {} + None => { + visited.pop_back(); + stack.pop(); + } + } + } + + // We only have to returns the traversed nodes from the paths that found to. + ret + } +} diff --git a/src/Rust/vvs_codegen/src/lib.rs b/src/Rust/vvs_codegen/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..8f74fd9dbe8ab9ae93e7867b78a63e1ab558590a --- /dev/null +++ b/src/Rust/vvs_codegen/src/lib.rs @@ -0,0 +1,29 @@ +//! The code used to lower the Vivy Script AST into LLVM code. + +mod context; +mod graph; +mod lowerer; +mod value; + +// Exports in this crate. +use crate::{context::*, graph::*, value::*}; + +// Re-exports. +pub use lowerer::{Lowerer, LowererBuilder}; + +type LLVMLowerContext = (vvs_llvm::LLVMModuleRef, vvs_llvm::LLVMContextRef, vvs_llvm::LLVMBuilderRef); + +/// The number of temp / unnamed values. +static mut TEMP_NAME_COUNTER: u64 = 0; + +#[macro_export] +macro_rules! cstr { + ($str: literal, $($arg: expr),+ $(,)?) => { + format!(concat!($str, "\0"), $($arg),+).as_ptr() as *const i8 + }; + + () => {{ + $crate::TEMP_NAME_COUNTER += 1; + format!(".temp.{}\0", $crate::TEMP_NAME_COUNTER).as_ptr() as *const i8 + }}; +} diff --git a/src/Rust/vvs_codegen/src/lowerer/calls.rs b/src/Rust/vvs_codegen/src/lowerer/calls.rs new file mode 100644 index 0000000000000000000000000000000000000000..b9d0be84745db6340f37115bf7aeee52750df422 --- /dev/null +++ b/src/Rust/vvs_codegen/src/lowerer/calls.rs @@ -0,0 +1,108 @@ +use crate::lowerer::*; +use vvs_lang::ast::*; +use vvs_llvm::*; + +/// Lower a single instruction. +pub(super) struct CallLowerer<'a> { + llvm: LLVMLowerContext, + ctx: &'a ValueContext, +} + +impl<'a> CallLowerer<'a> { + pub(super) fn new(llvm: LLVMLowerContext, ctx: &'a ValueContext) -> Self { + Self { llvm, ctx } + } + + pub(super) unsafe fn call_intrinsic<const N: usize>( + name: &'static str, + (m, _, b): LLVMLowerContext, + ret: LLVMTypeRef, + mut args: [LLVMValueRef; N], + ) -> LLVMValueRef { + let id = LLVMLookupIntrinsicID(name.as_ptr() as *const _, name.len()); + let mut args_ty: Vec<_> = args.iter().map(|val| LLVMTypeOf(*val)).collect(); + let (args_ty, args_len, args) = (args_ty.as_mut_ptr(), args.len().try_into().unwrap(), args.as_mut_ptr()); + let (functy, func) = ( + LLVMFunctionType(ret, args_ty, args_len, 0), + LLVMGetIntrinsicDeclaration(m, id, args_ty, args_len as usize), + ); + LLVMBuildCall2(b, functy, func, args, args_len, cstr!()) + } + + pub(super) fn lower_method_invok( + self, + obj: &ASTExpr, + func: impl AsRef<str>, + args: &[ASTExpr], + ) -> (ValueContext, Value) { + let Self { llvm: llvm @ (_, c, b), ctx } = self; + + let (ctx, object) = ExpressionLowerer::with_assumed_type(llvm, obj, ctx).lower(); + let (oty, obj) = (object.get_ast_type(), object.loaded(c, b)); + + let (aargs, rty, lty, lfn) = match ctx.get_value(VVRTSymbol::method(oty, func.as_ref()).unwrap().to_string()) { + Value::Function(ASTType::Function(aargs, rty), lty, lfn) if args.len() == aargs.len() => { + (aargs.clone(), rty.clone(), *lty, *lfn) + } + val => unreachable!("unexpected not a function value: {val:?}"), + }; + + let mut largs = Vec::with_capacity(args.len()); + let largc = 1 + args.len() as u32; + largs.push(obj); + let ctx = args.iter().zip(aargs).fold(ctx, |ctx, (arg, ty)| { + let (ctx, arg) = ExpressionLowerer::with_expected_type(llvm, arg, &ty, &ctx).lower(); + largs.push(arg.loaded(c, b)); + ctx + }); + + match *rty { + ASTType::Nil => unsafe { + LLVMBuildCall2(b, lty, lfn, largs.as_mut_ptr(), largc, c"".as_ptr()); + (ctx, Value::Nil) + }, + ty => unsafe { + let ret_ty = TypeLowerer::new(c, &ty).lower(); + let ptr = LLVMBuildAlloca(b, ret_ty, cstr!()); + let val = LLVMBuildCall2(b, lty, lfn, largs.as_mut_ptr(), largc, cstr!()); + LLVMBuildStore(b, val, ptr); + (ctx, Value::Alloca(ty, ret_ty, ptr)) + }, + } + } + + pub(super) fn lower_func_call(self, func: &ASTExpr, args: &[ASTExpr]) -> (ValueContext, Value) { + let Self { llvm: llvm @ (_, c, b), ctx } = self; + + let (ctx, aty, rty_ast, lty, lfn) = + match ExpressionLowerer::with_expected_type(llvm, func, &ASTType::Nil, ctx).lower() { + (ctx, Value::Function(ASTType::Function(aty, rty), lty, lfn)) if args.len() == aty.len() => { + (ctx, aty, rty, lty, lfn) + } + (_, what) => unreachable!("unexpected not-a-function-thingy: {what:?}"), + }; + + let mut largs = Vec::with_capacity(args.len()); + let args_len = args.len().try_into().expect("too many arguments"); + let mut ctx = args.iter().zip(aty).fold(ctx, |ctx, (arg, ty)| { + let (ctx, expr) = ExpressionLowerer::with_expected_type(llvm, arg, &ty, &ctx).lower(); + largs.push(expr.loaded(c, b)); + ctx + }); + + match unsafe { LLVMGetReturnType(lty) } { + rty if rty == unsafe { LLVMVoidTypeInContext(c) } => unsafe { + LLVMBuildCall2(b, lty, lfn, largs.as_mut_ptr(), args_len, c"".as_ptr()); + (ctx, Value::Nil) + }, + rty => unsafe { + let val = LLVMBuildCall2(b, lty, lfn, largs.as_mut_ptr(), args_len, cstr!()); + let ptr = LLVMBuildAlloca(b, rty, c".ignored".as_ptr()); + LLVMBuildStore(b, val, ptr); + let value = Value::Alloca(*rty_ast, rty, ptr); + ctx.register_anon(value.clone()); + (ctx, value) + }, + } + } +} diff --git a/src/Rust/vvs_codegen/src/lowerer/cast.rs b/src/Rust/vvs_codegen/src/lowerer/cast.rs new file mode 100644 index 0000000000000000000000000000000000000000..4d818f3ab21fea9f7e00a4ce2c8811367d839748 --- /dev/null +++ b/src/Rust/vvs_codegen/src/lowerer/cast.rs @@ -0,0 +1,329 @@ +use crate::lowerer::*; +use vvs_lang::ast::*; +use vvs_llvm::*; +use vvs_runtime_types::{types::*, vvll::LLVMExported}; + +pub(super) struct CastLowerer<'a> { + llvm: LLVMLowerContext, + + source: &'a Value, + from_type: &'a ASTType, + as_type: &'a ASTType, + + ctx: &'a ValueContext, +} + +/// Represents the value that was casted by the [CastLowerer] lowerer. +#[derive(Debug)] +pub(super) enum CastedValue { + /// A value can be [CastedValue::Unchanged] which means that we did nothing to it. you don't + /// need to register it again to trop it as it's nothing new... + Unchanged { value: Value }, + + /// A value can be [CastedValue::Dynamic] which means that we generated code to try to convert + /// the thing at runtime. The first element is the flag which is set to true if we did succeed, + /// false otherwise. This is an `i8` and must be checked at runtime. Because we created a + /// value, we muste register it to be dropped latter if needed. + Dynamic { flag: LLVMValueRef, value: Value }, + + /// A value can be [CastedValue::Static], which means that we did generate the code to cast the + /// thing and that we will always succeed. We still need to register this value to be dropped + /// if necessary... + Static { value: Value }, +} + +impl<'a> CastLowerer<'a> { + /// Create a new [CastLowerer] from an AST value. + pub fn from_ast(llvm: LLVMLowerContext, source: &'a ASTVar, as_type: &'a ASTType, ctx: &'a ValueContext) -> Self { + Self::from_llvm(llvm, ctx.get_value(source.name()), as_type, ctx) + } + + /// Create a new [CastLowerer] from a LLVM value. + pub fn from_llvm(llvm: LLVMLowerContext, source: &'a Value, as_type: &'a ASTType, ctx: &'a ValueContext) -> Self { + Self { llvm, source, as_type, from_type: source.get_ast_type(), ctx } + } + + /// Tells if the types are the same and we don't need to do the casting. + fn is_same_type(from: &ASTType, to: &ASTType) -> bool { + (to == from) + || (to.is_table() && from.is_table()) + || (to.is_sequence() && from.is_sequence()) + || (to.is_variant() && from.is_variant()) + } + + /// Lower in a static context, meaning that we assume that the casting process must succeed and + /// must not require a runtime check. + pub fn lower_static(self) -> CastedValue { + use ASTType::*; + let Self { llvm: llvm @ (_, c, b), source, from_type, as_type, ctx } = self; + + if matches!(as_type, Nil) { + return CastedValue::Unchanged { value: ConstantLowerer::new(c, &ASTConst::Nil).lower() }; + } else if Self::is_same_type(from_type, as_type) { + return CastedValue::Unchanged { value: source.clone() }; + } + + let loaded = source.loaded(c, b); + let store_into_ptr = |ty: ASTType, value: LLVMValueRef| unsafe { + let ptr = LLVMBuildAlloca(b, LLVMTypeOf(value), cstr!()); + LLVMBuildStore(b, value, ptr); + CastedValue::Static { value: Value::Alloca(ty, LLVMTypeOf(value), ptr) } + }; + + macro_rules! build_into { + ($ty: ident: $conv: ident) => { + unsafe { + let llvm_type = TypeLowerer::new(c, &$ty).lower(); + let ptr = LLVMBuildAlloca(b, llvm_type, cstr!()); + LLVMBuildStore(b, $conv(b, loaded, llvm_type, cstr!()), ptr); + CastedValue::Static { value: Value::Alloca($ty, llvm_type, ptr) } + } + }; + } + + match from_type { + Nil => match as_type { + Integer => CastedValue::Static { + value: Value::Const(Integer, unsafe { + LLVMConstInt(TypeLowerer::new(c, &Integer).lower(), Default::default(), 0) + }), + }, + Floating => CastedValue::Static { + value: Value::Const(Floating, unsafe { + LLVMConstReal(TypeLowerer::new(c, &Floating).lower(), Default::default()) + }), + }, + Boolean => CastedValue::Static { + value: Value::Const(Boolean, unsafe { + LLVMConstInt(TypeLowerer::new(c, &Boolean).lower(), Default::default(), 0) + }), + }, + ty if ty.is_table() => store_into_ptr(AnyTable, ctx.get_value("VVRTTable_new").call(b, [])), + ty if ty.is_sequence() => store_into_ptr(AnySequence, ctx.get_value("VVRTSeq_new").call(b, [])), + Any => store_into_ptr(Any, ctx.get_value("VVRTAny_nil").call(b, [])), + as_type => panic!("can't convert `{from_type} into {as_type}`"), + }, + + Integer => match as_type { + Integer => CastedValue::Unchanged { value: source.clone() }, + Boolean => build_into! { Boolean: LLVMBuildIntCast }, + Floating => build_into! { Floating: LLVMBuildSIToFP }, + Any => store_into_ptr(Any, ctx.get_value("VVRTAny_from_integer").call(b, [loaded])), + as_type => panic!("can't convert `{from_type} into {as_type}`"), + }, + + Floating => match as_type { + Floating => CastedValue::Unchanged { value: source.clone() }, + Integer => build_into! { Integer: LLVMBuildFPToSI }, + Boolean => build_into! { Boolean: LLVMBuildFPToSI }, + Any => store_into_ptr(Any, ctx.get_value("VVRTAny_from_floating").call(b, [loaded])), + as_type => panic!("can't convert `{from_type} into {as_type}`"), + }, + + Boolean => match as_type { + Boolean => CastedValue::Unchanged { value: source.clone() }, + Integer => build_into! { Integer: LLVMBuildIntCast }, + Floating => build_into! { Floating: LLVMBuildSIToFP }, + Any => store_into_ptr(Any, ctx.get_value("VVRTAny_from_boolean").call(b, [loaded])), + as_type => panic!("can't convert `{from_type} into {as_type}`"), + }, + + ty if ty.is_sequence() => match as_type { + Any => store_into_ptr(Any, ctx.get_value("VVRTAny_from_seq").call(b, [source.loaded(c, b)])), + as_type => panic!("can't convert `{from_type} into {as_type}`"), + }, + + Tuple(tuple) => match as_type { + Tuple(as_tuple) if tuple.len() == as_tuple.len() => unsafe { + let as_llvm = TypeLowerer::new(c, as_type).lower(); + let from_tuple = TypeLowerer::new(c, from_type).lower(); + let ptr = LLVMBuildAlloca(b, as_llvm, cstr!()); + + tuple.iter().enumerate().for_each(|(idx, from)| { + // Get the value that we must coerce. + let from_ptr = LLVMBuildStructGEP2(b, from_tuple, loaded, idx as u32, cstr!()); + let from_val = Value::Alloca(from.clone(), TypeLowerer::new(c, from).lower(), from_ptr); + + // Because of how we define tuples, we don't have to register the temp + // values here, they should only be integers, floats or booleans. + let value = match CastLowerer::from_llvm(llvm, &from_val, as_type, ctx).lower_static() { + CastedValue::Unchanged { value } | CastedValue::Static { value } => value.loaded(c, b), + casted => unreachable!("should have statically casted, got: {casted:?}"), + }; + let mut idxs = [ + LLVMConstInt(LLVMInt32TypeInContext(c), 0, 0), + LLVMConstInt(LLVMInt32TypeInContext(c), idx as u64, 0), + ]; + let ptr = LLVMBuildGEP2(b, as_llvm, ptr, idxs.as_mut_ptr(), idxs.len() as u32, cstr!()); + LLVMBuildStore(b, value, ptr); + }); + + CastedValue::Static { value: Value::Alloca(as_type.clone(), as_llvm, ptr) } + }, + + ty if ty.is_numeric() && tuple.len() == 1 => unsafe { + let from_val = Value::Alloca( + tuple[0].clone(), + TypeLowerer::new(c, &tuple[0]).lower(), + LLVMBuildStructGEP2(b, TypeLowerer::new(c, from_type).lower(), loaded, 0, cstr!()), + ); + CastLowerer::from_llvm(llvm, &from_val, ty, ctx).lower_static() + }, + + ty if ty.is_table() => unsafe { + let table = ctx.get_value("VVRTTable_new").call(b, []); + let from_tuple = TypeLowerer::new(c, from_type).lower(); + + tuple.iter().enumerate().for_each(|(idx, from)| { + let from_ptr = LLVMBuildStructGEP2(b, from_tuple, loaded, idx as u32, cstr!()); + let from_val = Value::Alloca(from.clone(), TypeLowerer::new(c, from).lower(), from_ptr); + + // Here we don't need to clone because we know that all types whithing a + // tuple are trivially copiable. + let value = match CastLowerer::from_llvm(llvm, &from_val, &Any, ctx).lower_static() { + CastedValue::Unchanged { value } | CastedValue::Static { value } => value.loaded(c, b), + casted => unreachable!("should have statically casted, got: {casted:?}"), + }; + + let key = idx.to_string(); + let (key, len) = ( + LLVMConstStringInContext(c, key.as_ptr() as *const _, key.len() as u32, 1), + LLVMConstInt(LLVMInt32TypeInContext(c), key.len() as u64, 0), + ); + ctx.get_value("VVRTTable_insert_from_raw_key") + .call(b, [table, key, len, value]); + }); + + let ptr = LLVMBuildAlloca(b, VVRTTable::llvm_type(c), cstr!()); + LLVMBuildStore(b, table, ptr); + CastedValue::Static { value: Value::Alloca(AnyTable, VVRTTable::llvm_type(c), ptr) } + }, + + ty if ty.is_sequence() => unsafe { + let seq = ctx.get_value("VVRTSeq_new").call(b, []); + let from_tuple = TypeLowerer::new(c, from_type).lower(); + + tuple.iter().enumerate().for_each(|(idx, from)| { + let from_ptr = LLVMBuildStructGEP2(b, from_tuple, loaded, idx as u32, cstr!()); + let from_val = Value::Alloca(from.clone(), TypeLowerer::new(c, from).lower(), from_ptr); + + // Here we don't need to clone because we know that all types whithing a + // tuple are trivially copiable. + let value = match CastLowerer::from_llvm(llvm, &from_val, &Any, ctx).lower_static() { + CastedValue::Unchanged { value } | CastedValue::Static { value } => value.loaded(c, b), + casted => unreachable!("should have statically casted, got: {casted:?}"), + }; + + ctx.get_value("VVRTSeq_push").call(b, [seq, value]); + }); + + let ptr = LLVMBuildAlloca(b, VVRTSeq::llvm_type(c), cstr!()); + LLVMBuildStore(b, seq, ptr); + CastedValue::Static { value: Value::Alloca(AnySequence, VVRTSeq::llvm_type(c), ptr) } + }, + + as_type => panic!("can't convert `{from_type} into {as_type}`"), + }, + + ty if ty.is_variant() => match as_type { + as_type if as_type.is_table() => todo!(), + String => store_into_ptr(String, ctx.get_value("VVRTVariant_to_string").call(b, [loaded])), + Any => store_into_ptr(Any, ctx.get_value("VVRTAny_from_variant").call(b, [loaded])), + as_type => panic!("can't convert `{from_type} into {as_type}`"), + }, + + // Forbiden casts or Dynamic casts + ty => panic!("can't cast a value of type `{ty}` or this type need a runtime check to do the cast"), + } + } + + /// Try to do the lowering at runtime, if it failed we guarenty that the value will be nil and + /// that no values will need to be dropped. In case of success we calling function must + /// register the value in the context. + pub fn lower_dynamic(self) -> CastedValue { + use ASTType::*; + let Self { llvm: (_, c, b), source, from_type, as_type, ctx } = self; + + if matches!(as_type, Nil) && !matches!(from_type, ASTType::Any) { + return CastedValue::Unchanged { value: ConstantLowerer::new(c, &ASTConst::Nil).lower() }; + } else if Self::is_same_type(from_type, as_type) { + return CastedValue::Unchanged { value: source.clone() }; + } + + let loaded = source.loaded(c, b); + let store_into_ptr = |ty: ASTType, value: LLVMValueRef| unsafe { + let ptr = LLVMBuildAlloca(b, LLVMTypeOf(value), cstr!()); + LLVMBuildStore(b, value, ptr); + Value::Alloca(ty, LLVMTypeOf(value), ptr) + }; + let any_is_ty = |ty: VVRTType| { + ctx.get_value("VVRTAny_is_ty") + .call(b, [loaded, unsafe { ty.as_llvm_const(c) }]) + }; + + match from_type { + ty if ty.is_table() => match as_type { + Any => CastedValue::Static { + value: store_into_ptr(Any, ctx.get_value("VVRTAny_from_table").call(b, [loaded])), + }, + ty if ty.is_variant() => todo!(), + ty if ty.is_sequence() => todo!(), + as_type => panic!("can't convert `{from_type} into {as_type}`"), + }, + + // Get value out of any. + Any => match as_type { + Nil => CastedValue::Dynamic { + flag: any_is_ty(VVRTType::Nil), + value: ConstantLowerer::new(c, &ASTConst::Nil).lower(), + }, + Integer => CastedValue::Dynamic { + flag: any_is_ty(VVRTType::Number), + value: store_into_ptr(Integer, ctx.get_value("VVRTAny_maybe_as_integer").call(b, [loaded])), + }, + Boolean => CastedValue::Dynamic { + flag: any_is_ty(VVRTType::Number), + value: store_into_ptr(Boolean, ctx.get_value("VVRTAny_maybe_as_boolean").call(b, [loaded])), + }, + Floating => CastedValue::Dynamic { + flag: any_is_ty(VVRTType::Number), + value: store_into_ptr(Floating, ctx.get_value("VVRTAny_maybe_as_floating").call(b, [loaded])), + }, + String => { + let val = ctx.get_value("VVRTAny_maybe_as_string").call(b, [loaded]); + let val = ctx.get_value("VVRTString_clone").call(b, [val]); + CastedValue::Dynamic { flag: any_is_ty(VVRTType::String), value: store_into_ptr(String, val) } + } + Syllabe => { + let val = ctx.get_value("VVRTAny_maybe_as_syllabe").call(b, [loaded]); + let val = ctx.get_value("VVRTSyllabe_clone").call(b, [val]); + CastedValue::Dynamic { flag: any_is_ty(VVRTType::ASSSyllabe), value: store_into_ptr(Syllabe, val) } + } + Line => { + let val = ctx.get_value("VVRTAny_maybe_as_line").call(b, [loaded]); + let val = ctx.get_value("VVRTLine_clone").call(b, [val]); + CastedValue::Dynamic { flag: any_is_ty(VVRTType::ASSLine), value: store_into_ptr(Line, val) } + } + ty if ty.is_variant() => { + let val = ctx.get_value("VVRTAny_maybe_as_variant").call(b, [loaded]); + let val = ctx.get_value("VVRTVariant_clone").call(b, [val]); + CastedValue::Dynamic { flag: any_is_ty(VVRTType::Variant), value: store_into_ptr(Variant, val) } + } + ty if ty.is_table() => { + let val = ctx.get_value("VVRTAny_maybe_as_table").call(b, [loaded]); + let val = ctx.get_value("VVRTTable_clone").call(b, [val]); + CastedValue::Dynamic { flag: any_is_ty(VVRTType::Table), value: store_into_ptr(AnyTable, val) } + } + ty if ty.is_sequence() => { + let val = ctx.get_value("VVRTAny_maybe_as_seq").call(b, [loaded]); + let val = ctx.get_value("VVRTSeq_clone").call(b, [val]); + CastedValue::Dynamic { flag: any_is_ty(VVRTType::Seq), value: store_into_ptr(AnySequence, val) } + } + as_type => panic!("can't convert `{from_type} into {as_type}`"), + }, + + // Don't need to perform a runtime check to do the cast, use the lower function + _ => self.lower_static(), + } + } +} diff --git a/src/Rust/vvs_codegen/src/lowerer/constant.rs b/src/Rust/vvs_codegen/src/lowerer/constant.rs new file mode 100644 index 0000000000000000000000000000000000000000..e8a67e172b4a79b50f9220d9f8d260570c289dc9 --- /dev/null +++ b/src/Rust/vvs_codegen/src/lowerer/constant.rs @@ -0,0 +1,59 @@ +use crate::Value; +use std::mem; +use vvs_lang::ast::*; +use vvs_llvm::*; + +/// Lower a single constant. We only need the LLVM context what should be the type... +pub(crate) struct ConstantLowerer<'a> { + /// The context. + c: LLVMContextRef, + + /// We expression we want to lower. + constant: &'a ASTConst, +} + +impl<'a> ConstantLowerer<'a> { + /// Create a new constant expression lowerer. + pub fn new(c: LLVMContextRef, constant: &'a ASTConst) -> Self { + Self { c, constant } + } + + /// Create a sub-lowerer, for constants that need a recursive descent. + fn sub_lowerer(&self, constant: &'a ASTConst) -> Self { + Self { c: self.c, constant } + } + + /// Lower the constant. + pub fn lower(self) -> Value { + let Self { c, constant } = self; + let ty = constant.get_const_type(); + use {ASTConst::*, Value::*}; + unsafe { + match constant { + ASTConst::Nil => Const(ty, LLVMConstPointerNull(LLVMInt64TypeInContext(c))), + False => Const(ty, LLVMConstInt(LLVMInt1TypeInContext(c), 0, 0)), + True => Const(ty, LLVMConstInt(LLVMInt1TypeInContext(c), 1, 0)), + Floating(f) => Const(ty, LLVMConstReal(LLVMFloatTypeInContext(c), *f as f64)), + String(s) => { + let (ptr, len) = (s.as_bytes().as_ptr() as *const _, s.len().try_into().unwrap()); + Const(ty, LLVMConstString(ptr, len, 1)) + } + Integer(i) => { + let int = mem::transmute::<i64, u64>(*i as i64); + Const(ty, LLVMConstInt(LLVMInt32TypeInContext(c), int, 1)) + } + Tuple(inner) => { + let i = inner.iter().map(|cnst| match self.sub_lowerer(cnst).lower() { + Value::Const(_, val) => val, + val => unreachable!("expected a constant, got {val:?}"), + }); + let mut i = i.collect::<Vec<_>>(); + let (ptr, len) = (i.as_mut_ptr(), i.len().try_into().unwrap()); + Const(ty, LLVMConstStructInContext(c, ptr, len, 0)) + } + Color(_) => panic!("need to implement colors"), + Table(_) => panic!("need to implement tables"), + } + } + } +} diff --git a/src/Rust/vvs_codegen/src/lowerer/drops.rs b/src/Rust/vvs_codegen/src/lowerer/drops.rs new file mode 100644 index 0000000000000000000000000000000000000000..3c56022ce8c6dbb584e167ec7f7ce30ea4ab3989 --- /dev/null +++ b/src/Rust/vvs_codegen/src/lowerer/drops.rs @@ -0,0 +1,109 @@ +use crate::{value::Value, Graph, ValueContext}; +use std::collections::BTreeSet; +use vvs_llvm::*; + +/// Drop all the values in the correct order at the end of a given basic block. We take into +/// account any terminator of said basic block. +pub(super) struct DropLowerer<'a> { + /// The context. + c: LLVMContextRef, + + /// Our own builder. + b: LLVMBuilderRef, + + /// The values to drop, they are in the order of their declaration. We drop them in the reverse + /// order! + values: &'a [Value], + + /// The function from which the values must be dropped. + func: LLVMValueRef, + + /// The basic block to use to drop things. We will create our own builder to do the thing, so + /// we don't need others things to pass their builder. + bb: LLVMBasicBlockRef, + + /// The value context. + ctx: &'a ValueContext, +} + +impl<'a> DropLowerer<'a> { + /// Create a new lowerer to drop the specified values from a given function at the end of a + /// given basic block. + /// + /// # Safety + /// All the values must have been declared inside the passed the function. The basic block must + /// be from the passed function. + pub unsafe fn new( + c: LLVMContextRef, + func: LLVMValueRef, + values: &'a [Value], + bb: LLVMBasicBlockRef, + ctx: &'a ValueContext, + ) -> Self { + let b = unsafe { LLVMCreateBuilderInContext(c) }; + Self { c, b, values, func, bb, ctx } + } + + pub fn lower(self) { + use LLVMOpcode::*; + let Self { c, b, values, bb, func, ctx } = self; + + // Position the builder correcly. + + unsafe { + match LLVMGetLastInstruction(bb) { + last if last.is_null() => LLVMPositionBuilderAtEnd(b, bb), + last => match LLVMGetInstructionOpcode(last) { + LLVMRet | LLVMBr | LLVMSwitch | LLVMIndirectBr | LLVMCallBr => LLVMPositionBuilderBefore(b, last), + _ => LLVMPositionBuilderAtEnd(b, bb), + }, + }; + }; + + // Get the dominance graph to filter the values that we must really drop here! + + let bbs_iter = unsafe { LLVMFunctionIter::new(func) }; + let bbs = Graph::with_capacity(bbs_iter.count()).add_nodes(bbs_iter); + let bbs = bbs_iter.fold(bbs, |bbs, bb| unsafe { + match LLVMBasicBlockIter::new(bb).last() { + Some(instr) => match LLVMGetInstructionOpcode(instr) { + LLVMBr => match LLVMGetNumOperands(instr) { + 1 => bbs.add_edge(bb, LLVMValueAsBasicBlock(LLVMGetOperand(instr, 0))), + 3 => bbs + .add_edge(bb, LLVMValueAsBasicBlock(LLVMGetOperand(instr, 1))) + .add_edge(bb, LLVMValueAsBasicBlock(LLVMGetOperand(instr, 2))), + n => unreachable!("got br instruction with {n} operands"), + }, + LLVMSwitch => todo!("handle switch, got {} operands", LLVMGetNumOperands(instr)), + LLVMIndirectBr => todo!("handle indirectbr, got {} operands", LLVMGetNumOperands(instr)), + _ => bbs, + }, + None => bbs, + } + }); + + // Filter the values that we must really delete and call the destructors. We can destroy + // the values in any order because things are reference-counted. Also, just drop the values + + let declared_values: BTreeSet<LLVMValueRef> = unsafe { + bbs.any_path_content(LLVMGetEntryBasicBlock(func), bb) + .into_iter() + .flat_map(|bb| LLVMBasicBlockIter::new(bb)) + .collect() + }; + + values + .iter() + .filter(|val| val.llvm_value().map_or(false, |val| declared_values.contains(&val))) + .flat_map(|val| val.get_dropper_name().map(|drop| (val, drop))) + .for_each(|(val, drop)| { + ctx.get_value(drop).call(b, [val.loaded(c, b)]); + }); + } +} + +impl<'a> Drop for DropLowerer<'a> { + fn drop(&mut self) { + unsafe { LLVMDisposeBuilder(self.b) }; + } +} diff --git a/src/Rust/vvs_codegen/src/lowerer/expression.rs b/src/Rust/vvs_codegen/src/lowerer/expression.rs new file mode 100644 index 0000000000000000000000000000000000000000..6caad5f2c15a085be5979fb43d4404eb4dc43c9c --- /dev/null +++ b/src/Rust/vvs_codegen/src/lowerer/expression.rs @@ -0,0 +1,347 @@ +use crate::{lowerer::*, Value, ValueContext}; +use vvs_lang::ast::*; +use vvs_llvm::{LLVMIntPredicate::*, LLVMRealPredicate::*, *}; +use vvs_runtime_types::{ + types::{VVRTString, VVRTTable}, + vvll::LLVMExported, +}; +use vvs_utils::either; + +/// Lower a single expression. +pub(super) struct ExpressionLowerer<'a> { + llvm: LLVMLowerContext, + + /// We expression we want to lower. + expr: &'a ASTExpr, + + /// The expected type, to see if we need to generate coertion. + as_type: Option<&'a ASTType>, + + /// The value context, this stores available already-lowered LLVM values. + ctx: &'a ValueContext, +} + +impl<'a> ExpressionLowerer<'a> { + /// Create a new expression lowerer. + pub(super) fn with_assumed_type(llvm: LLVMLowerContext, expr: &'a ASTExpr, ctx: &'a ValueContext) -> Self { + Self { llvm, expr, as_type: None, ctx } + } + + /// Create a new expression lowerer with an expected type for the lowered expression. If needed + /// the lower process will call [CastLowerer]. + pub(super) fn with_expected_type( + llvm: LLVMLowerContext, + expr: &'a ASTExpr, + as_type: &'a ASTType, + ctx: &'a ValueContext, + ) -> Self { + Self { llvm, expr, as_type: Some(as_type), ctx } + } + + /// Overwrite the used [ValueContext] used to do the lowering. + pub(super) fn with_ctx(mut self, ctx: &'a ValueContext) -> Self { + self.ctx = ctx; + self + } + + /// Set the type that is expected by the expression, calling the [CastLowerer] if needed! + pub(super) fn into_type(mut self, ty: &'a ASTType) -> Self { + self.as_type = Some(ty); + self + } + + /// Create a new sub-expression lowerer. Used for recusive descent to lower complexe + /// expressions, thus private. + fn sub_lowerer(&self, expr: &'a ASTExpr) -> Self { + let Self { llvm, ctx, .. } = *self; + Self { llvm, expr, as_type: None, ctx } + } + + /// Lower an equality. + unsafe fn lower_equality( + llvm @ (_, c, b): LLVMLowerContext, + ctx: &ValueContext, + (l, lty): (LLVMValueRef, &ASTType), + (r, rty): (LLVMValueRef, &ASTType), + ) -> LLVMValueRef { + use ASTType::*; + match lty { + Nil => LLVMConstInt(LLVMInt1TypeInContext(c), 1, 0), + Boolean | Integer => LLVMBuildICmp(b, LLVMIntEQ, l, r, cstr!()), + Floating => { + let flt = LLVMFloatTypeInContext(c); + let diff = LLVMBuildFSub(b, l, r, c"".as_ptr()); + let diff = CallLowerer::call_intrinsic("llvm.fabs.f32", llvm, flt, [diff]); + LLVMBuildFCmp(b, LLVMRealOLE, diff, LLVMConstReal(flt, 10e-5), c"".as_ptr()) + } + + Tuple(lt) => match rty { + Tuple(rt) if lt.len() == rt.len() => lt.iter().zip(rt).enumerate().fold( + LLVMConstInt(LLVMInt1TypeInContext(c), 1, 0), + |acc, (idx, (lt, rt))| { + let idx = idx.try_into().expect("too many elements"); + let l = LLVMBuildStructGEP2(b, LLVMTypeOf(l), l, idx, cstr!()); + let r = LLVMBuildStructGEP2(b, LLVMTypeOf(r), r, idx, cstr!()); + let ret = Self::lower_equality(llvm, ctx, (l, lt), (r, rt)); + LLVMBuildAnd(b, ret, acc, cstr!()) + }, + ), + _ => LLVMConstInt(LLVMInt1TypeInContext(c), 0, 0), + }, + + Any => ctx.get_value("VVRTAny_eq").call(b, [l, r]), + Line => ctx.get_value("VVRTLine_eq").call(b, [l, r]), + String => ctx.get_value("VVRTString_eq").call(b, [l, r]), + Syllabe => ctx.get_value("VVRTSyllabe_eq").call(b, [l, r]), + ty if ty.is_sequence() => ctx.get_value("VVRTSeq_eq").call(b, [l, r]), + ty if ty.is_variant() => ctx.get_value("VVRTVariant_eq").call(b, [l, r]), + ty if ty.is_table() => ctx.get_value("VVRTTable_eq").call(b, [l, r]), + + _ => panic!("can't apply `{:?}` to expressions of type `{lty}` and `{rty}`", ASTBinop::CmpEQ), + } + } + + /// Lower the value into LLVM-IR at the position specified by the builder passed at + /// construction time. If any value is created it will be added in the returned [ValueContext]. + pub(super) fn lower(self) -> (ValueContext, Value) { + let Self { llvm: llvm @ (_, c, b), expr: ASTExpr { content, .. }, as_type, ctx } = self; + let (bln, int, flt) = (unsafe { LLVMInt1TypeInContext(c) }, unsafe { LLVMInt32TypeInContext(c) }, unsafe { + LLVMFloatTypeInContext(c) + }); + let (false_, true_, zero_, one_) = ( + unsafe { LLVMConstInt(bln, 0, 0) }, + unsafe { LLVMConstInt(bln, 1, 0) }, + unsafe { LLVMConstInt(int, 0, 0) }, + unsafe { LLVMConstInt(int, 1, 0) }, + ); + let store_scalar = |ctx: ValueContext, val: LLVMValueRef, ty: LLVMTypeRef, ast: ASTType| unsafe { + let ptr = LLVMBuildAlloca(b, ty, cstr!()); + LLVMBuildStore(b, val, ptr); + (ctx, Value::Alloca(ast, ty, ptr)) + }; + + match content { + ASTExprVariant::Var(var) => (ctx.clone(), ctx.get_value(var.name()).clone()), + + ASTExprVariant::Const(value) => { + let value = ConstantLowerer::new(c, value).lower(); + match as_type { + Some(expected_type) if expected_type != value.get_ast_type() => { + match CastLowerer::from_llvm(llvm, &value, expected_type, ctx).lower_static() { + CastedValue::Unchanged { value } => (ctx.clone(), value), + CastedValue::Static { value } => (ctx.to_register_anon(value.clone()), value), + CastedValue::Dynamic { .. } => unreachable!(), + } + } + _ => (ctx.clone(), value), + } + } + + ASTExprVariant::Tuple(tuple) => unsafe { + let (mut lowered_tuple, mut types, mut tuple_ty) = + (Vec::with_capacity(tuple.len()), Vec::with_capacity(tuple.len()), Vec::with_capacity(tuple.len())); + + let ctx = tuple.iter().fold(self.ctx.clone(), |ctx, item| { + let (ctx, expr) = self.sub_lowerer(item).with_ctx(&ctx).lower(); + let (ast_type, expr) = (expr.get_ast_type(), expr.loaded(c, b)); + lowered_tuple.push(expr); + types.push(LLVMTypeOf(expr)); + tuple_ty.push(ast_type.clone()); + ctx + }); + + let tuple_len = types.len().try_into().expect("too many elements"); + let types = LLVMStructTypeInContext(c, types.as_mut_ptr(), tuple_len, 0); + let tuple_ptr = LLVMBuildAlloca(b, types, c"".as_ptr()); + + for (idx, val) in lowered_tuple.into_iter().enumerate() { + let idx = idx.try_into().expect("too many elements"); + let ptr = LLVMBuildStructGEP2(b, types, tuple_ptr, idx, c"".as_ptr()); + LLVMBuildStore(b, val, ptr); + } + + (ctx, Value::Alloca(ASTType::Tuple(tuple_ty), types, tuple_ptr)) + }, + + ASTExprVariant::Table(table) => unsafe { + let ty = VVRTTable::llvm_type(c); + let ptr = LLVMBuildAlloca(b, ty, c"".as_ptr()); + LLVMBuildStore(b, ctx.get_value("VVRTTable_new").call(b, []), ptr); + let mut ctx = table.iter().fold(self.ctx.clone(), |_, (key, value)| { + // Static key! The table will create it's own string. + let key_len: u32 = key.len().try_into().expect("too many elements"); + let key = LLVMConstStringInContext(c, key.as_ptr() as *const _, key_len, 1); + let key_len = LLVMConstInt(LLVMInt32TypeInContext(c), key_len as u64, 0); + + // Lower the value and cast it into an Any. + let (mut ctx, value) = self.sub_lowerer(value).into_type(&ASTType::Any).lower(); + let value = value.loaded(c, b); + ctx.forget_by_llvm_value(value); + + // Insert the value with the correct key. + ctx.get_value("VVRTTable_insert_from_raw_key") + .call(b, [ptr, key, key_len, value]); + ctx + }); + let value = Value::Alloca(ASTType::AnyTable, ty, ptr); + ctx.register_anon(value.clone()); + (ctx, value) + }, + + ASTExprVariant::FuncCall(func, args) => { + let (ctx, value) = CallLowerer::new(llvm, self.ctx).lower_func_call(func, args); + (ctx.to_register_anon(value.clone()), value) + } + ASTExprVariant::MethodInvok(obj, method, args) => { + let (ctx, value) = CallLowerer::new(llvm, self.ctx).lower_method_invok(obj, method, args); + (ctx.to_register_anon(value.clone()), value) + } + + ASTExprVariant::Unop(op, inner) => unsafe { + use vvs_lang::ast::{ASTType::*, ASTUnop::*}; + + let (ctx, inner) = match as_type { + Some(ty) => self.sub_lowerer(inner).into_type(ty).lower(), + None => self.sub_lowerer(inner).lower(), + }; + let (ty, inner) = (inner.get_ast_type(), inner.loaded(c, b)); + let call_len = |ctx: ValueContext, func: &str| { + let value = ctx.get_value(func).call(b, [inner]); + store_scalar(ctx, value, int, Integer) + }; + + match op { + LogicNot | BitNot | Neg if matches!(ty, Boolean) => { + let cmp = LLVMBuildICmp(b, LLVMIntEQ, inner, false_, cstr!()); + let res = LLVMBuildSelect(b, cmp, true_, false_, cstr!()); + store_scalar(ctx, res, bln, Boolean) + } + + LogicNot if matches!(ty, Integer) => { + let cmp = LLVMBuildICmp(b, LLVMIntEQ, inner, zero_, cstr!()); + let res = LLVMBuildSelect(b, cmp, one_, zero_, cstr!()); + store_scalar(ctx, res, int, Integer) + } + + BitNot if matches!(ty, Integer) => { + let res = CallLowerer::call_intrinsic("llvm.bitreverse.i32", llvm, int, [inner]); + store_scalar(ctx, res, int, Integer) + } + + #[rustfmt::skip] Neg if matches!(ty, Integer ) => store_scalar(ctx, LLVMBuildNeg (b, inner, cstr!()), int, Integer ), + #[rustfmt::skip] Neg if matches!(ty, Floating) => store_scalar(ctx, LLVMBuildFNeg(b, inner, cstr!()), flt, Floating), + + #[rustfmt::skip] Len => match ty { + Line => call_len(ctx, "VVRTLine_len"), + String => call_len(ctx, "VVRTString_len"), + Syllabe => call_len(ctx, "VVRTSyllabe_len"), + ty if ty.is_sequence() => call_len(ctx, "VVRTSeq_len"), + ty if ty.is_table() => call_len(ctx, "VVRTTable_len"), + Tuple(len) => { + let len = TryInto::<i32>::try_into(len.len()).expect("too many elements") as u64; + (ctx, Value::Const(Integer, LLVMConstInt(int, len, 0))) + } + ty => panic!("can't apply `{op:?}` to expression of type `{ty}`"), + }, + + op => panic!("can't apply `{op:?}` to expression of type `{ty}`"), + } + }, + + ASTExprVariant::Binop(left, op, right) => unsafe { + use vvs_lang::ast::{ASTBinop::*, ASTType::*}; + + let (ctx, left) = match as_type { + Some(ty) => self.sub_lowerer(left).into_type(ty).lower(), + None => self.sub_lowerer(left).lower(), + }; + let lty = left.get_ast_type(); + let (ctx, right) = self + .sub_lowerer(right) + .into_type(either!(*op == Power => &Integer; lty)) + .with_ctx(&ctx) + .lower(); + let (l, r, rty) = (left.loaded(c, b), right.loaded(c, b), right.get_ast_type()); + let (is_int, is_flt, is_bln) = + (matches!(lty, Integer), matches!(lty, Floating), matches!(lty, Boolean)); + + let (res, ty, ast) = match op { + Power if is_int => todo!(), + Power if is_flt => todo!(), + + #[rustfmt::skip] Mul if is_int => (LLVMBuildMul (b, l, r, cstr!()), int, Integer), + #[rustfmt::skip] Div if is_int => (LLVMBuildSDiv(b, l, r, cstr!()), int, Integer), + #[rustfmt::skip] Add if is_int => (LLVMBuildAdd (b, l, r, cstr!()), int, Integer), + #[rustfmt::skip] Sub if is_int => (LLVMBuildSub (b, l, r, cstr!()), int, Integer), + + #[rustfmt::skip] Mul if is_flt => (LLVMBuildFMul(b, l, r, cstr!()), flt, Floating), + #[rustfmt::skip] Div if is_flt => (LLVMBuildFDiv(b, l, r, cstr!()), flt, Floating), + #[rustfmt::skip] Add if is_flt => (LLVMBuildFAdd(b, l, r, cstr!()), flt, Floating), + #[rustfmt::skip] Sub if is_flt => (LLVMBuildFSub(b, l, r, cstr!()), flt, Floating), + + #[rustfmt::skip] Mod if is_int => (LLVMBuildSRem(b, l, r, cstr!()), int, Integer ), + #[rustfmt::skip] Mod if is_flt => (LLVMBuildFRem(b, l, r, cstr!()), flt, Floating), + + #[rustfmt::skip] StrCat if matches!(lty, String) => { + (ctx.get_value("VVRTString_cat").call(b, [l, r]), VVRTString::llvm_type(c), String) + }, + + #[rustfmt::skip] CmpLE if is_int => (LLVMBuildICmp(b, LLVMIntSLE, l, r, cstr!()), bln, Boolean), + #[rustfmt::skip] CmpLT if is_int => (LLVMBuildICmp(b, LLVMIntSLT, l, r, cstr!()), bln, Boolean), + #[rustfmt::skip] CmpGE if is_int => (LLVMBuildICmp(b, LLVMIntSGE, l, r, cstr!()), bln, Boolean), + #[rustfmt::skip] CmpGT if is_int => (LLVMBuildICmp(b, LLVMIntSGT, l, r, cstr!()), bln, Boolean), + + #[rustfmt::skip] CmpLE if is_flt => (LLVMBuildFCmp(b, LLVMRealOLE, l, r, cstr!()), flt, Floating), + #[rustfmt::skip] CmpLT if is_flt => (LLVMBuildFCmp(b, LLVMRealOLT, l, r, cstr!()), flt, Floating), + #[rustfmt::skip] CmpGE if is_flt => (LLVMBuildFCmp(b, LLVMRealOGE, l, r, cstr!()), flt, Floating), + #[rustfmt::skip] CmpGT if is_flt => (LLVMBuildFCmp(b, LLVMRealOGT, l, r, cstr!()), flt, Floating), + + #[rustfmt::skip] BitAnd | LogicAnd if is_bln => (LLVMBuildAnd(b, l, r, cstr!()), bln, Boolean), + #[rustfmt::skip] BitXor | LogicXor if is_bln => (LLVMBuildXor(b, l, r, cstr!()), bln, Boolean), + #[rustfmt::skip] BitOr | LogicOr if is_bln => (LLVMBuildOr (b, l, r, cstr!()), bln, Boolean), + + #[rustfmt::skip] BitAnd if is_int => (LLVMBuildAnd(b, l, r, cstr!()), int, Integer), + #[rustfmt::skip] BitXor if is_int => (LLVMBuildXor(b, l, r, cstr!()), int, Integer), + #[rustfmt::skip] BitOr if is_int => (LLVMBuildOr (b, l, r, cstr!()), int, Integer), + #[rustfmt::skip] LogicAnd if is_int => (LLVMBuildICmp(b, LLVMIntEQ, LLVMBuildAnd(b, l, r, cstr!()), one_, cstr!()), bln, Boolean), + #[rustfmt::skip] LogicXor if is_int => (LLVMBuildICmp(b, LLVMIntEQ, LLVMBuildXor(b, l, r, cstr!()), one_, cstr!()), bln, Boolean), + #[rustfmt::skip] LogicOr if is_int => (LLVMBuildICmp(b, LLVMIntEQ, LLVMBuildOr (b, l, r, cstr!()), one_, cstr!()), bln, Boolean), + + #[rustfmt::skip] BitShiftLeft if is_int => (LLVMBuildShl (b, l, r, cstr!()), int, Integer), + #[rustfmt::skip] BitShiftRight if is_int => (LLVMBuildAShr(b, l, r, cstr!()), int, Integer), + + CmpEQ => (Self::lower_equality(llvm, &ctx, (l, lty), (r, rty)), bln, Boolean), + CmpNE => { + let not = Self::lower_equality(llvm, &ctx, (l, lty), (r, rty)); + (LLVMBuildNot(b, not, cstr!()), bln, Boolean) + } + + op => panic!("can't apply `{op:?}` to expressions of type `{lty}` and `{rty}`"), + }; + store_scalar(ctx, res, ty, ast) + }, + + ASTExprVariant::Suffixed(table, _fields) => { + let (_ctx, _table) = self.sub_lowerer(table).lower(); + todo!() + } + + ASTExprVariant::Color(variant) | ASTExprVariant::Movement(variant) => { + let mut arguments = Vec::with_capacity(variant.args_len()); + let _ctx = variant.args().iter().fold(ctx.clone(), |ctx, expr| { + let (ctx, expr) = self.sub_lowerer(expr).with_ctx(&ctx).lower(); + arguments.push(expr); + ctx + }); + let _variant = variant.variant(); + + todo!() + } + + ASTExprVariant::Default(_) => todo!(), + + // See later for clozures + ASTExprVariant::FuncBind(_, _) => unreachable!(), + } + } +} diff --git a/src/Rust/vvs_codegen/src/lowerer/function.rs b/src/Rust/vvs_codegen/src/lowerer/function.rs new file mode 100644 index 0000000000000000000000000000000000000000..fd8ab0870c39c666eb0cdde6db946863bbc44892 --- /dev/null +++ b/src/Rust/vvs_codegen/src/lowerer/function.rs @@ -0,0 +1,55 @@ +use crate::{lowerer::*, ValueContext}; +use vvs_lang::ast::*; +use vvs_llvm::*; + +pub(super) struct FunctionLowerer<'a> { + llvm: LLVMLowerContext, + + /// The global context, we store a reference, then we will add it the arguments of the + /// function. + ctx: &'a ValueContext, + + /// The llvm function. + value: LLVMValueRef, + + /// The vivy function. + function: &'a ASTFunction, +} + +impl<'a> FunctionLowerer<'a> { + pub fn new(llvm: LLVMLowerContext, ctx: &'a ValueContext, v: LLVMValueRef, f: &'a ASTFunction) -> Self { + Self { llvm, ctx, value: v, function: f } + } + + pub fn lower(self) { + let Self { llvm: llvm @ (_, c, b), value, function, .. } = self; + let ASTFunction { arguments, content, returns, .. } = function; + let mut ctx = self.ctx.clone(); + + let mut ctx = unsafe { + LLVMPositionBuilderAtEnd(b, LLVMAppendBasicBlockInContext(c, value, c"entry".as_ptr())); + for (idx, arg) in arguments.iter().enumerate() { + let ty = arg + .get_specified_type() + .expect("the type should be specified at this point"); + let llvm_ty = TypeLowerer::new(c, ty).lower(); + let arg_name = CString::new(arg.name().as_ref()).expect("invalid name"); + let arg_param = LLVMGetParam(value, idx.try_into().expect("too many arguments")); + let ptr = LLVMBuildAlloca(b, llvm_ty, arg_name.as_ptr()); + LLVMBuildStore(b, arg_param, ptr); + ctx.register(arg.name(), Value::Alloca(ty.clone(), llvm_ty, ptr)); + } + + InstructionLowerer::new(llvm, value, content, returns.clone(), ctx).lower() + }; + + let to_drop = ctx.get_values_to_drop(); + unsafe { LLVMFunctionIter::new(value) } + .filter(|&bb| unsafe { + LLVMBasicBlockIter::new(bb) + .last() + .map_or(false, |instr| LLVMGetInstructionOpcode(instr) == LLVMOpcode::LLVMRet) + }) + .for_each(|bb| unsafe { DropLowerer::new(c, value, &to_drop, bb, &ctx) }.lower()); + } +} diff --git a/src/Rust/vvs_codegen/src/lowerer/instruction.rs b/src/Rust/vvs_codegen/src/lowerer/instruction.rs new file mode 100644 index 0000000000000000000000000000000000000000..d731bfd93a73079e4cfa7e933da62f6f7fae92bb --- /dev/null +++ b/src/Rust/vvs_codegen/src/lowerer/instruction.rs @@ -0,0 +1,431 @@ +use crate::lowerer::*; +use std::sync::OnceLock; +use vvs_lang::{anon_expression, anon_instruction, ast::*}; +use vvs_llvm::*; +use vvs_utils::either; + +#[derive(Clone, Copy)] +struct BBLoop { + body_entry: LLVMBasicBlockRef, + loop_exit: LLVMBasicBlockRef, +} + +/// Lower a single instruction. +pub(super) struct InstructionLowerer<'a> { + llvm: LLVMLowerContext, + + /// The function containing the instruction to lower. + func: LLVMValueRef, + + /// Remeber the last loop to be able to break or continue. + last_loop: Option<BBLoop>, + + /// The instruction we want to lower. + instr: &'a ASTInstr, + + /// The return type of the function, to see if we need to generetate coertion. + func_return_type: ASTType, + + /// The value context, this stores available already-lowered LLVM values. + ctx: ValueContext, +} + +impl<'a> InstructionLowerer<'a> { + /// Create a new expression lowerer. + pub(super) fn new( + llvm: LLVMLowerContext, + func: LLVMValueRef, + instruction: &'a ASTInstr, + func_return_type: ASTType, + ctx: ValueContext, + ) -> Self { + let last_loop = Default::default(); + Self { llvm, func, instr: instruction, func_return_type, ctx, last_loop } + } + + /// Create a new sub-expression lowerer. Used for recusive descent to lower complexe + /// expressions, thus private. + fn sub_lowerer(&self, instruction: &'a ASTInstr) -> Self { + let Self { llvm, func, last_loop, .. } = *self; + let func_return_type = self.func_return_type.clone(); + let ctx = self.ctx.clone(); + Self { llvm, instr: instruction, func, func_return_type, ctx, last_loop } + } + + /// Short-hand to create an expression lowerer by passing some arguments correctly. + fn expr(&'a self, expr: &'a ASTExpr) -> ExpressionLowerer<'a> { + ExpressionLowerer::with_assumed_type(self.llvm, expr, &self.ctx) + } + + /// Get a new sub-expression lowerer. We need to know the exit block of this scope so that we + /// can build the calls to drop for this scope. + fn scoped_lowerer(&mut self, exit_bb: LLVMBasicBlockRef, cb: impl FnOnce(Self) -> ValueContext) { + static mut NOOP: OnceLock<ASTInstr> = OnceLock::new(); + + // Save context. + let pre_ctx = self.ctx.clone(); + self.ctx = pre_ctx.sub_context(); + + // Build an empty instruction to give as parent lowerer in scope. + let Self { llvm: llvm @ (_, c, _), func, last_loop, .. } = *self; + let instruction = unsafe { NOOP.get_or_init(|| anon_instruction!(Noop)) }; + let func_return_type = self.func_return_type.clone(); + let ctx = self.ctx.sub_context(); + let this = Self { llvm, func, last_loop, instr: instruction, func_return_type, ctx }; + + // Drop what was declared in the scope + let mut ctx = cb(this); + unsafe { DropLowerer::new(c, func, &ctx.get_values_to_drop(), exit_bb, &ctx) }.lower(); + + // Restore context. + self.ctx = pre_ctx; + } + + /// Set the last loop to lower a given instruction. + fn with_loop(mut self, r#loop: BBLoop) -> Self { + self.last_loop = Some(r#loop); + self + } + + /// Set the value context. + fn with_ctx(mut self, ctx: ValueContext) -> Self { + self.ctx = ctx; + self + } + + pub(super) fn lower(mut self) -> ValueContext { + let Self { llvm: llvm @ (_, c, b), func, instr: ASTInstr { content, span }, .. } = self; + match content { + // Nop + ASTInstrVariant::Noop => self.ctx, + + // A simple list of instructions + ASTInstrVariant::Block(instructions) => unsafe { + let exit = LLVMAppendBasicBlockInContext(c, self.func, c".block".as_ptr()); + self.scoped_lowerer(exit, |this| { + instructions + .iter() + .fold(this.ctx.clone(), |ctx, instruction| this.sub_lowerer(instruction).with_ctx(ctx).lower()) + }); + LLVMBuildBr(b, exit); + LLVMPositionBuilderAtEnd(b, exit); + self.ctx + }, + + // Breaks/Continue + ASTInstrVariant::Break | ASTInstrVariant::Continue if self.last_loop.is_none() => { + panic!("try to lower break/continue while not being inside a loop") + } + ASTInstrVariant::Break => unsafe { + LLVMBuildBr(b, self.last_loop.expect("internal error").loop_exit); + self.ctx + }, + ASTInstrVariant::Continue => unsafe { + LLVMBuildBr(b, self.last_loop.expect("internal error").body_entry); + self.ctx + }, + + // Return from function + ASTInstrVariant::Return(expr) => unsafe { + let (ctx, value) = self.expr(expr).lower(); + match value { + Value::Nil => LLVMBuildRetVoid(b), + Value::Function(..) => panic!("error at `{span}`: can't return a function for now"), + value => LLVMBuildRet(b, value.loaded(c, b)), + }; + ctx + }, + + // Assignation + ASTInstrVariant::Assign(dests, srcs) if dests.len() != srcs.len() => { + unreachable!("internal error: verifier failed for assignations at `{span}`") + } + ASTInstrVariant::Assign(dests, srcs) => dests.iter().zip(srcs).fold(self.ctx, |ctx, (dest, src)| { + let (dest, dest_ty) = Self::compute_dest_location(c, b, &ctx, dest); + let (ctx, src) = ExpressionLowerer::with_expected_type(llvm, src, dest_ty, &ctx).lower(); + Self::store_into(c, b, dest, &src); + ctx + }), + + // Declarations + ASTInstrVariant::Decl(dests, srcs) if dests.len() != srcs.len() => { + unreachable!("internal error: verifier failed for declarations at `{span}`") + } + ASTInstrVariant::Decl(dests, srcs) => { + let mut declarations = Vec::with_capacity(dests.len()); + let ctx = dests.iter().zip(srcs).fold(self.ctx.clone(), |ctx, (dest, src)| { + let dest_ast_ty = dest.get_specified_type().expect("internal error"); + let dest_llvm_ty = TypeLowerer::new(c, dest_ast_ty).lower(); + let val = unsafe { LLVMBuildAlloca(b, dest_llvm_ty, cstr!("{}", dest.name())) }; + let (ctx, expr) = self.expr(src).with_ctx(&ctx).into_type(dest_ast_ty).lower(); + Self::store_into(c, b, val, &expr); + declarations.push((dest.name(), Value::Alloca(dest_ast_ty.clone(), dest_llvm_ty, val))); + ctx + }); + declarations.into_iter().fold(ctx, |mut ctx, (name, val)| { + ctx.register(name, val); + ctx + }) + } + + // Call a function, discard the result + ASTInstrVariant::FuncCall(func, args) => { + let (ctx, value) = CallLowerer::new(llvm, &self.ctx).lower_func_call(func, args); + ctx.to_register_anon(value) + } + ASTInstrVariant::MethodInvok(obj, method, args) => { + let (ctx, value) = CallLowerer::new(llvm, &self.ctx).lower_method_invok(obj, method, args); + ctx.to_register_anon(value) + } + + // If/Else/Elseif blocks + ASTInstrVariant::Cond { if_blocks, else_block } => unsafe { + let exit = LLVMAppendBasicBlockInContext(c, self.func, c".if.exit".as_ptr()); + let pre_ctx = self.ctx.clone(); + let true_cond = ASTCondition::BooleanTrue(anon_expression!(Const(ASTConst::True))); + + let get_bb = move |idx: usize, what: &str| { + LLVMAppendBasicBlockInContext(c, self.func, cstr!(".if.{}.{}", idx, what)) + }; + let mut bbs: HashMap<usize, LLVMBasicBlockRef> = Default::default(); + let mut get_bb_cond = move |idx| *bbs.entry(idx).or_insert_with(move || get_bb(idx, "condition")); + + /// Use a macro to not write the same code twice by forgeting something... + macro_rules! build_cond_block { + (($if_num: expr, $if_cond: expr, $if_inner: expr), $else_bb: expr, $exit: expr) => {{ + let (if_bb_body, if_bb_body_exit) = (get_bb($if_num, "body"), get_bb($if_num, "body.exit")); + self.scoped_lowerer(if_bb_body_exit, |mut scoped| { + // CONDITION: We don't need to drop things even if we didn't succeded, + // add the new ctx to lower the conditional body. The head + // BB of the conditional is cached by it's number. + LLVMPositionBuilderAtEnd(b, get_bb_cond($if_num)); + let ctx = scoped.lower_condition($if_cond, if_bb_body, $else_bb); + + // BODY: We need to drop things after the exit of the loop, we also + // drop the conditional stuff + LLVMPositionBuilderAtEnd(b, if_bb_body); + let ctx = scoped.sub_lowerer($if_inner).with_ctx(ctx).lower(); + LLVMBuildBr(b, if_bb_body_exit); + LLVMPositionBuilderAtEnd(b, if_bb_body_exit); + LLVMBuildBr(b, $exit); + + // WARN: scoped.ctx -> contains also the temporary values! We must drop + // all of those if we succeded or not. + DropLowerer::new(c, func, &scoped.ctx.get_values_to_drop(), $else_bb, &ctx).lower(); + DropLowerer::new(c, func, &scoped.ctx.get_values_to_drop(), if_bb_body_exit, &ctx).lower(); + + ctx + }) + }}; + } + + let else_block = else_block.as_ref().map(|instr| (&true_cond, instr.as_ref())); + let if_blocks = if_blocks.iter().map(|(cond, instr): &_| (cond, instr)); + let blocks = if_blocks.chain(else_block).enumerate().collect::<Vec<(_, (&_, &_))>>(); + assert!(!blocks.is_empty(), "empty conditionals not allowed"); + + // IF -> Need to jump to the first condition checker + LLVMBuildBr(b, get_bb_cond(0)); + + // Build IF, for ELSE -> will be handled at next iteration + blocks.windows(2).for_each(|slice| match slice { + [(if_num, (if_cond, if_inner)), (else_num, _)] => { + build_cond_block!((*if_num, if_cond, if_inner), get_bb_cond(*else_num), exit) + } + _ => unreachable!(), + }); + + // ELSE / IF in the case where we have only one conditional -> Handle last item + let (else_num, (else_cond, else_inner)) = blocks.last().expect("internal error"); + build_cond_block!((*else_num, else_cond, else_inner), exit, exit); + + LLVMPositionBuilderAtEnd(b, exit); + pre_ctx + }, + + // While loops + ASTInstrVariant::WhileDo(condition, inner) => unsafe { + let (cond, exit, body, body_exit) = ( + LLVMAppendBasicBlockInContext(c, self.func, c".while.cond".as_ptr()), + LLVMAppendBasicBlockInContext(c, self.func, c".while.exit".as_ptr()), + LLVMAppendBasicBlockInContext(c, self.func, c".while.body".as_ptr()), + LLVMAppendBasicBlockInContext(c, self.func, c".while.body.exit".as_ptr()), + ); + + self.scoped_lowerer(body_exit, |mut scoped| { + // For a WhileDo the condition binding variables are only visible in the body + // of the loop. Here we ensure variables are only available inside the loop. + LLVMBuildBr(b, cond); + LLVMPositionBuilderAtEnd(b, cond); + let ctx = scoped.lower_condition(condition, body, exit); + + LLVMPositionBuilderAtEnd(b, body); + let ctx = scoped + .sub_lowerer(inner) + .with_ctx(ctx) + .with_loop(BBLoop { body_entry: body, loop_exit: exit }) + .lower(); + + // Drop what was + LLVMBuildBr(b, body_exit); + LLVMPositionBuilderAtEnd(b, body_exit); + DropLowerer::new(c, func, &scoped.ctx.get_values_to_drop(), body_exit, &ctx).lower(); + LLVMBuildBr(b, cond); + ctx + }); + + LLVMPositionBuilderAtEnd(b, exit); + self.ctx + }, + + // For loop + ASTInstrVariant::ForLoop { var, lower: l, upper: u, step, body: inner } => unsafe { + let (cond, exit, body, body_exit) = ( + LLVMAppendBasicBlockInContext(c, self.func, c".forloop.cond".as_ptr()), + LLVMAppendBasicBlockInContext(c, self.func, c".forloop.exit".as_ptr()), + LLVMAppendBasicBlockInContext(c, self.func, c".forloop.body".as_ptr()), + LLVMAppendBasicBlockInContext(c, self.func, c".forloop.body.exit".as_ptr()), + ); + + let (ctx, lower) = self.expr(l).into_type(&ASTType::Integer).lower(); + let (mut ctx, upper) = self.expr(u).with_ctx(&ctx).into_type(&ASTType::Integer).lower(); + let (lower, upper) = (lower.loaded(c, b), upper.loaded(c, b)); + + // Setup the index + let t_i32 = LLVMInt32TypeInContext(c); + let step = step.unwrap_or(1) as i64; + assert!(step > 0, "the for-loop step must be strictly positive"); + let step = LLVMConstInt(t_i32, std::mem::transmute_copy(&step), 0); + + let index = LLVMBuildAlloca(b, t_i32, cstr!(".index.{}", var)); + ctx.register(var.name(), Value::Alloca(ASTType::Integer, t_i32, index)); + LLVMBuildStore(b, lower, index); + + // Build the condition check + LLVMBuildBr(b, cond); + LLVMPositionBuilderAtEnd(b, cond); + const PREDICATE: LLVMIntPredicate = LLVMIntPredicate::LLVMIntSLT; + let loaded = LLVMBuildLoad2(b, t_i32, index, cstr!(".index.{}.loaded", var)); + let cont = LLVMBuildICmp(b, PREDICATE, loaded, upper, cstr!(".index.{}.flag", var)); + LLVMBuildCondBr(b, cont, body, exit); + + // Lower the body, we need a scope for that. + self.scoped_lowerer(body_exit, |scoped| { + LLVMPositionBuilderAtEnd(b, body); + let ctx = scoped + .sub_lowerer(inner) + .with_loop(BBLoop { body_entry: body, loop_exit: exit }) + .lower(); + let loaded = LLVMBuildLoad2(b, t_i32, index, cstr!(".index.{}.loaded", var)); + let loaded = LLVMBuildAdd(b, loaded, step, cstr!(".index.{}.incremented", var)); + LLVMBuildStore(b, loaded, index); + LLVMBuildBr(b, body_exit); + LLVMPositionBuilderAtEnd(b, body_exit); + LLVMBuildBr(b, cond); + ctx + }); + + // End of loop + LLVMPositionBuilderAtEnd(b, exit); + ctx + }, + ASTInstrVariant::ForInto { .. } => unsafe { + let (_cond, _exit, _body, _body_exit) = ( + LLVMAppendBasicBlockInContext(c, self.func, c".foreach.cond".as_ptr()), + LLVMAppendBasicBlockInContext(c, self.func, c".foreach.exit".as_ptr()), + LLVMAppendBasicBlockInContext(c, self.func, c".foreach.body".as_ptr()), + LLVMAppendBasicBlockInContext(c, self.func, c".foreach.body.exit".as_ptr()), + ); + todo!() + }, + } + } + + /// Store the content of a value into a location in memory. + /// + /// TODO: Do that in the Value enum + fn store_into(c: LLVMContextRef, b: LLVMBuilderRef, dest: LLVMValueRef, src: &Value) { + match src { + Value::Function(_, _, _) => panic!("we don't handle function pointers for now"), + Value::Const(_, v) => unsafe { LLVMBuildStore(b, *v, dest) }, + Value::Nil => match ConstantLowerer::new(c, &ASTConst::Nil).lower() { + Value::Const(_, v) => unsafe { LLVMBuildStore(b, v, dest) }, + _ => unreachable!(), + }, + Value::Alloca(_, ty, v) => unsafe { + let v = LLVMBuildLoad2(b, *ty, *v, cstr!()); + LLVMBuildStore(b, v, dest) + }, + }; + } + + /// Get the address and the type of a variable to store into it. + fn compute_dest_location<'b>( + _c: LLVMContextRef, + _b: LLVMBuilderRef, + _ctx: &'b ValueContext, + _expr: &'b ASTExpr, + ) -> (LLVMValueRef, &'b ASTType) { + todo!() + } + + /// Lower the condition. Returns the new context with the added binded values if needed. If the + /// condition is not checked we don't need to drop anything from the returned value context. + /// This means that we must drop the returned context only on the then condition path. + /// + /// If things where allocated to check the condition, then we add them to the current context, + /// but not to the returned context! This means that may the condition succeed or not, you must + /// drop the context of the calling lowerer at the end of the `then` and `else` paths. + /// + /// Most of the time the context is already scopped, so it shouldn't be too difficult trop + /// things at the right moment. + fn lower_condition( + &mut self, + condition: &ASTCondition, + bb_then: LLVMBasicBlockRef, + bb_else: LLVMBasicBlockRef, + ) -> ValueContext { + let Self { llvm: llvm @ (_, c, b), .. } = *self; + match condition { + ASTCondition::BooleanTrue(cond) => unsafe { + let (mut ctx, cond) = self.expr(cond).into_type(&ASTType::Boolean).lower(); + LLVMBuildCondBr(b, cond.loaded(c, b), bb_then, bb_else); + + let ret_ctx = self.ctx.clone(); + self.ctx.add_values_to_drop(ctx.get_values_to_drop()); + ret_ctx + }, + + ASTCondition::CoercibleInto { new, as_type, source: src } + if src + .get_specified_type() + .expect("should be setted") + .coercible_to(as_type) => + unsafe { + let llvm_true = LLVMConstInt(LLVMInt1TypeInContext(c), 1, 0); + let (register, flag, src) = match CastLowerer::from_ast(llvm, src, as_type, &self.ctx).lower_dynamic() { + CastedValue::Dynamic { flag, value } => (true, flag, value), + CastedValue::Static { value } => (true, llvm_true, value), + CastedValue::Unchanged { value } => (false, llvm_true, value), + }; + LLVMBuildCondBr(b, flag, bb_then, bb_else); + + LLVMPositionBuilderAtEnd(b, bb_then); + let ty = TypeLowerer::new(c, as_type).lower(); + let dest = LLVMBuildAlloca(b, ty, cstr!(".{}.alloca", new)); + LLVMBuildStore(b, src.loaded(c, b), dest); + + either!(!register => self.ctx.clone(); + self.ctx.to_register(new.name(), Value::Alloca(as_type.clone(), ty, dest)) + ) + }, + + ASTCondition::CoercibleInto { .. } => unsafe { + LLVMBuildBr(b, bb_else); + self.ctx.clone() + }, + + ASTCondition::BindVariant { .. } => todo!(), + } + } +} diff --git a/src/Rust/vvs_codegen/src/lowerer/mod.rs b/src/Rust/vvs_codegen/src/lowerer/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..2de616388b6d914b890880d722894bf06374af8f --- /dev/null +++ b/src/Rust/vvs_codegen/src/lowerer/mod.rs @@ -0,0 +1,221 @@ +mod calls; +mod cast; +mod constant; +mod drops; +mod expression; +mod function; +mod instruction; +mod types; + +use crate::{ + cstr, + lowerer::{calls::*, cast::*, drops::*, expression::*, function::*, instruction::*, types::*}, + value::Value, + LLVMLowerContext, ValueContext, +}; +use hashbrown::HashMap; +use std::ffi::{CStr, CString}; +use vvs_lang::ast::*; +use vvs_llvm::*; +use vvs_runtime_types::{VVRTSymbol, VVRTSymbolType}; + +// Re-export the constant lowerer because it can be usefull in other parts of the codegen. +pub(crate) use self::constant::ConstantLowerer; + +pub struct Lowerer<'a> { + llvm: LLVMLowerContext, + + functions: Vec<(ASTString, ASTString, &'a ASTFunction)>, + globals: HashMap<(ASTString, ASTString), &'a ASTConst>, + + ctx: ValueContext, +} + +pub struct LowererBuilder<'a> { + name: CString, + c: LLVMContextRef, + m: Option<LLVMModuleRef>, + b: LLVMBuilderRef, + programs: Option<&'a ASTProgram>, + modules: Vec<&'a ASTModule>, +} + +impl<'a> LowererBuilder<'a> { + /// Create a new lowerer builder. We need a name and the context from the JIT thing. + /// + /// # Safety + /// This function is unsafe because we use the LLVM context pointer passed from anywhere. This + /// pointer must be not null and be a valid LLVM context. + pub unsafe fn new(name: impl AsRef<str>, c: LLVMContextRef) -> Self { + Self { + c, + name: CString::new(name.as_ref()).expect("invalid module name"), + b: LLVMCreateBuilderInContext(c), + m: Default::default(), + modules: Default::default(), + programs: Default::default(), + } + } + + /// Add a complete program to lower. If any other program was present, overwrite it. + pub fn program(mut self, program: &'a ASTProgram) -> Self { + self.programs = Some(program); + self + } + + /// Add a module to lower to the list of things to lower. + pub fn module(mut self, module: &'a ASTModule) -> Self { + self.modules.push(module); + self + } + + /// Build the lowerer from this builder. + pub fn build(self) -> Lowerer<'a> { + let Self { c, m, b, programs, modules, name } = self; + + // Get all the modules that will be lowered inside the final LLVM module. By doing this we + // have a similar thing to LTO for Vivy Script. + + let init = HashMap::<ASTString, &'a ASTModule>::default(); + let modules = modules + .into_iter() + .chain(programs.iter().flat_map(|prog| prog.modules())) + .fold(init, |mut map, module| match map.entry(module.name()) { + hashbrown::hash_map::Entry::Occupied(_) => map, + hashbrown::hash_map::Entry::Vacant(entry) => { + entry.insert(module); + map + } + }); + + // Get the globals that needs to be lowered / needs to be known by the lowerer. We first + // collect the setted options from the program as those will overwrite values from the + // modules, then we get what is defined as default in the module. To ensure we doesn't + // overwrite things, we only insert in the final hashmap if the thing was not already + // defined in the hashmap. Other than setted overwriting defaults, there should not be any + // other collisions. + + let init: HashMap<(ASTString, ASTString), &'a ASTConst> = programs + .iter() + .flat_map(|prog| { + prog.setted_options() + .iter() + .map(|((m, n), v)| ((m.clone(), n.clone()), v)) + }) + .collect(); + let globals = modules.iter().flat_map(|(mname, m)| { + let hdl = |(var, val): (&'a ASTVar, &'a _)| (mname.clone(), var.name(), val); + m.consts(ASTVisibilityRule::any()).map(hdl).chain(m.options().map(hdl)) + }); + let globals = globals.fold(init, |mut globals, (mn, n, val)| match globals.entry((mn, n)) { + hashbrown::hash_map::Entry::Occupied(_) => globals, + hashbrown::hash_map::Entry::Vacant(entry) => { + entry.insert(val); + globals + } + }); + + // Get the functions that are available in all the module to lower them. Should not be any + // collision. + + let functions = modules.iter().flat_map(|(mname, m)| { + m.functions(ASTVisibilityRule::any()) + .map(|(fname, f)| (mname.clone(), fname, f)) + }); + let functions = functions.collect(); + + // Now we can create the lowerer with the specified LLVM module or by creating a new one. + + let m = m.unwrap_or_else(|| unsafe { LLVMModuleCreateWithNameInContext(name.as_ptr(), c) }); + let mut ctx = ValueContext::default(); + ctx.register_all( + unsafe { vvs_runtime_types::vvll::LLVMRegisterExportedIntoModule(c, m) } + .into_iter() + .map(|(name, asttype, val, ty)| (name, Value::Function(asttype, ty, val))), + ); + + Lowerer { llvm: (m, c, b), functions, globals, ctx } + } +} + +impl<'a> Lowerer<'a> { + /// Lower the content of the programs and modules, then returns the LLVM module containing + /// everything... + pub fn lower(self) -> LLVMModuleRef { + let Self { llvm: llvm @ (m, c, b), functions, globals, mut ctx } = self; + + // Register all the globals in the context, they will be directly inlined in the lowering + // process. + + ctx.register_all( + globals + .into_iter() + .map(|((m, n), cnst)| (format!("{m}.{n}"), ConstantLowerer::new(c, cnst).lower())), + ); + + // Lower all the functions. First declare the things and register them with the mangled + // name and the unmagnled name. As we collect the iterator we ensure that all the functions + // are declared before we generate them. Doing so allows us to use recursion and we don't + // need to find a good order to define-use the functions like in C. When we latter lower + // the content of the functions we try to find the first error and return it. + + functions.into_iter().for_each(|(module, name, function)| { + // Declare the thing + let mangled = VVRTSymbol::new(VVRTSymbolType::Function, &module, &name) + .expect("invalid function names") + .mangle(); + let ast_function_type = function.function_type(); + let ty = TypeLowerer::new(c, &ast_function_type).lower(); + let value = unsafe { LLVMAddFunction(m, mangled.as_ptr(), ty) }; + + // Register it. When we collect the iterator. + let to_register = Value::Function(ast_function_type, ty, value); + ctx.register(mangled.to_str().expect("invalid function names"), to_register.clone()); + ctx.register(format!("{module}.{name}"), to_register); + + // We will generate it latter + FunctionLowerer::new(llvm, &ctx, value, function).lower(); + }); + + // Cleanup and optimize the code. + + unsafe { + LLVMDisposeBuilder(b); + Self::verify_and_apply_optimizations(m, 3) + } + } + + /// Run the optimization passes on a module. + unsafe fn verify_and_apply_optimizations(m: LLVMModuleRef, lvl: u8) -> LLVMModuleRef { + let mut cmsg = std::ptr::null_mut(); + if 0 != LLVMVerifyModule(m, LLVMVerifierFailureAction::LLVMPrintMessageAction, &mut cmsg) { + let msg = CStr::from_ptr(cmsg).to_string_lossy().to_string(); + LLVMDisposeMessage(cmsg); + panic!("invalid module: {msg}"); + } + + let pbo = LLVMCreatePassBuilderOptions(); + let pm = LLVMCreatePassManager(); + let tm = LLVMCreateTargetMachine( + LLVMGetTargetFromName(LLVMGetTarget(m)), + LLVMGetDefaultTargetTriple(), + LLVMGetHostCPUName(), + LLVMGetHostCPUFeatures(), + LLVMCodeGenOptLevel::LLVMCodeGenLevelAggressive, + LLVMRelocMode::LLVMRelocPIC, + LLVMCodeModel::LLVMCodeModelDefault, + ); + + let err = LLVMRunPasses(m, cstr!("default<O{}>", lvl), tm, pbo); + if !err.is_null() { + let msg = CStr::from_ptr(LLVMGetErrorMessage(err)).to_string_lossy().to_string(); + LLVMConsumeError(err); + panic!("failed to run optimizer with level O{lvl} on module: {msg}") + } + + LLVMDisposePassBuilderOptions(pbo); + LLVMDisposePassManager(pm); + LLVMDisposeTargetMachine(tm); + m + } +} diff --git a/src/Rust/vvs_codegen/src/lowerer/types.rs b/src/Rust/vvs_codegen/src/lowerer/types.rs new file mode 100644 index 0000000000000000000000000000000000000000..5e1b47482002da089da0d8642da96c37c3db8a73 --- /dev/null +++ b/src/Rust/vvs_codegen/src/lowerer/types.rs @@ -0,0 +1,57 @@ +use vvs_lang::ast::*; +use vvs_llvm::*; +use vvs_runtime_types::{types::*, vvll::LLVMExported}; + +pub(super) struct TypeLowerer<'a> { + c: LLVMContextRef, + vivy_type: &'a ASTType, +} + +impl<'a> TypeLowerer<'a> { + pub(super) fn new(c: LLVMContextRef, vivy_type: &'a ASTType) -> Self { + Self { c, vivy_type } + } + + fn sub_lowerer(&self, ty: &'a ASTType) -> Self { + Self { c: self.c, vivy_type: ty } + } + + pub(super) fn lower(self) -> LLVMTypeRef { + let Self { c, vivy_type } = self; + match vivy_type { + // Easy stuff... + ASTType::Nil => unsafe { LLVMVoidTypeInContext(c) }, + ASTType::Integer => unsafe { LLVMInt32TypeInContext(c) }, + ASTType::Floating => unsafe { LLVMFloatTypeInContext(c) }, + ASTType::Boolean => unsafe { LLVMInt1TypeInContext(c) }, + + // Functions + ASTType::Function(args, returns) => unsafe { + let mut args = args.iter().map(|ty| self.sub_lowerer(ty).lower()).collect::<Vec<_>>(); + LLVMFunctionType( + self.sub_lowerer(returns).lower(), + args.as_mut_ptr(), + args.len().try_into().expect("too many arguments"), + 0, + ) + }, + + // The tuple + ASTType::Tuple(inner) => unsafe { + let mut inner = inner.iter().map(|ty| self.sub_lowerer(ty).lower()).collect::<Vec<_>>(); + LLVMStructType(inner.as_mut_ptr(), inner.len().try_into().expect("too many elements"), 0) + }, + + // Special structs, query the runtime for that... + ASTType::Any => unsafe { VVRTAny::llvm_type(c) }, + ASTType::String => unsafe { VVRTString::llvm_type(c) }, + ASTType::Syllabe => unsafe { VVRTSyllabe::llvm_type(c) }, + ASTType::Line => unsafe { VVRTLine::llvm_type(c) }, + ty if ty.is_table() => unsafe { VVRTTable::llvm_type(c) }, + ty if ty.is_variant() => unsafe { VVRTVariant::llvm_type(c) }, + ty if ty.is_sequence() => unsafe { VVRTSeq::llvm_type(c) }, + + _ => unreachable!(), + } + } +} diff --git a/src/Rust/vvs_codegen/src/value.rs b/src/Rust/vvs_codegen/src/value.rs new file mode 100644 index 0000000000000000000000000000000000000000..d7302af027e5b6fb25eef3e78172f50d8d64ee30 --- /dev/null +++ b/src/Rust/vvs_codegen/src/value.rs @@ -0,0 +1,100 @@ +use crate::{cstr, lowerer}; +use vvs_lang::ast::{ASTConst, ASTType, Typed}; +use vvs_llvm::*; + +#[derive(Debug, Default, Clone, PartialEq, Eq)] +pub(crate) enum Value { + /// Just the Nil/Null/None/nullptr value. + #[default] + Nil, + + /// A constant. + Const(ASTType, LLVMValueRef), + + /// A pointer to the stack plus the underlying type. + Alloca(ASTType, LLVMTypeRef, LLVMValueRef), + + /// A function with its function type. + Function(ASTType, LLVMTypeRef, LLVMValueRef), +} + +impl Value { + /// Try to get the name of the value. Only [Value::Nil] have no name. + pub fn as_str(&self) -> Option<&str> { + use Value::*; + match *self { + Nil => None, + Function(.., val) | Const(_, val) | Alloca(.., val) => unsafe { + let mut len = 0; + let str = LLVMGetValueName2(val, &mut len) as *const _; + Some(std::str::from_utf8_unchecked(std::slice::from_raw_parts(str, len))) + }, + } + } + + pub fn llvm_type(&self) -> Option<LLVMTypeRef> { + match self { + Value::Const(..) | Value::Nil => None, + Value::Alloca(_, t, _) | Value::Function(_, t, _) => Some(*t), + } + } + + pub fn llvm_value(&self) -> Option<LLVMValueRef> { + match self { + Value::Nil => None, + Value::Const(_, v) | Value::Alloca(_, _, v) | Value::Function(_, _, v) => Some(*v), + } + } + + pub fn loaded(&self, c: LLVMContextRef, b: LLVMBuilderRef) -> LLVMValueRef { + match self { + Value::Nil => lowerer::ConstantLowerer::new(c, &ASTConst::Nil).lower().loaded(c, b), + Value::Const(_, val) => *val, + Value::Alloca(_, ty, ptr) => unsafe { LLVMBuildLoad2(b, *ty, *ptr, cstr!()) }, + Value::Function(_, _, func_ptr) => *func_ptr, + } + } + + /// Get the name of the dropper function, if any! + pub fn get_dropper_name(&self) -> Option<&'static str> { + match self.get_ast_type() { + ty if ty.is_variant() => Some("VVRTVariant_drop"), + ty if ty.is_table() => Some("VVRTTable_drop"), + ty if ty.is_sequence() => Some("VVRTSeq_drop"), + ASTType::Syllabe => Some("VVRTSyllabe_drop"), + ASTType::String => Some("VVRTString_drop"), + ASTType::Line => Some("VVRTLine_drop"), + ASTType::Any => Some("VVRTAny_drop"), + + ASTType::Function(_, _) => todo!("handle functions and clozures..."), + _ => None, + } + } + + /// Call a function with some values. Note that this function won't create memory manage points + /// for the passed values (see types that are managed and the ones that are not.) + pub fn call<const N: usize>(&self, b: LLVMBuilderRef, mut args: [LLVMValueRef; N]) -> LLVMValueRef { + match self { + Value::Function(_, func_ty, func_val) => unsafe { + let args_ptr = args.as_mut_ptr(); + let args_len = args.len().try_into().expect("too much arguments"); + LLVMBuildCall2(b, *func_ty, *func_val, args_ptr, args_len, c"".as_ptr()) + }, + val => panic!("can't call a non-function value: {val:?}"), + } + } + + pub fn get_ast_type(&self) -> &ASTType { + const NIL: ASTType = ASTType::Nil; + match self { + Value::Nil => &NIL, + Value::Const(ty, _) | Value::Alloca(ty, _, _) | Value::Function(ty, _, _) => ty, + } + } +} + +impl Typed for Value { + fn get_type(&self, _: &vvs_lang::ast::ASTTypeContext) -> ASTType { + self.get_ast_type().clone() + } +} diff --git a/src/Rust/vvs_font/Cargo.toml b/src/Rust/vvs_font/Cargo.toml index 838aa4cfe8f2a0c17b03ec1372ebe818ccbc9cf3..48c9c5faee6ab81c047c1ef89946fdedf0ba9ec2 100644 --- a/src/Rust/vvs_font/Cargo.toml +++ b/src/Rust/vvs_font/Cargo.toml @@ -1,14 +1,13 @@ [package] -name = "vvs_font" +name = "vvs_font" +description = "The font crate for VVS" version.workspace = true authors.workspace = true edition.workspace = true license.workspace = true -description = "The font crate for VVS" [dependencies] -thiserror.workspace = true -log.workspace = true - -ttf-parser = { version = "^0.19" } -ab_glyph = { version = "^0.2.20" } +thiserror.workspace = true +log.workspace = true +ttf-parser.workspace = true +ab_glyph.workspace = true diff --git a/src/Rust/vvs_font/build.rs b/src/Rust/vvs_font/build.rs index 8d38f76b5b5bd644f9b79d60d19c0b02a80c25ac..1ae4223882b997536452dc1c3b7bcc5d8d6d2b6a 100644 --- a/src/Rust/vvs_font/build.rs +++ b/src/Rust/vvs_font/build.rs @@ -10,6 +10,8 @@ fn rerun_directory<T: AsRef<Path> + ?Sized>(dir: &T) { } } +static EXCLUDED_FONTS: &[&str] = &["FiraCode"]; + fn main() { let out_dir = Path::new(&env::var_os("OUT_DIR").expect("no OUT_DIR env variable...")) .canonicalize() @@ -23,8 +25,13 @@ fn main() { .expect("failed to read the font folder") .filter_map(Result::ok) .filter(|file| { - file.file_type().map(|ft| ft.is_file()).unwrap_or_default() - && file.path().extension().map(|e| e == "ttf").unwrap_or(false) + file.file_type().map(|ft| ft.is_file()).unwrap_or_default() && { + let path = file.path(); + path.file_name() + .map(|f| !EXCLUDED_FONTS.iter().any(|pat| f.to_string_lossy().starts_with(pat))) + .unwrap_or_default() + && path.extension().map(|e| e == "ttf").unwrap_or_default() + } }) .map(|file| { let (path, file_name) = (file.path(), file.file_name()); diff --git a/src/Rust/vvs_font/src/font.rs b/src/Rust/vvs_font/src/font.rs index 5fc71f228ac230895c6240235bd83a53f671dae2..cf17c758dd91022db52f7a117ecc897b4b34a92a 100644 --- a/src/Rust/vvs_font/src/font.rs +++ b/src/Rust/vvs_font/src/font.rs @@ -24,6 +24,7 @@ pub struct Font<'a> { impl<'a> TryFrom<&'a [u8]> for Font<'a> { type Error = FontCreationError; + #[inline] fn try_from(data: &'a [u8]) -> Result<Self, Self::Error> { Ok(Self { face: ttf_parser::Face::parse(data, 0).map_err(FontCreationError::TTFParserError)?, @@ -79,6 +80,7 @@ impl<'a> Font<'a> { } /// Get the number of glyphs in the font. + #[inline] pub fn number_of_glyphs(&self) -> i64 { self.face.number_of_glyphs() as i64 } diff --git a/src/Rust/vvs_font/src/rect.rs b/src/Rust/vvs_font/src/rect.rs index 86454e17cb599bf0cf843fe1f1517a907c94b661..c52bb5b5b65b7abb71dbba0d89003fa4a8080b57 100644 --- a/src/Rust/vvs_font/src/rect.rs +++ b/src/Rust/vvs_font/src/rect.rs @@ -16,14 +16,13 @@ pub struct Rect { impl Rect { /// Create a correctly formed [Rect] that includes the passed [Point]. + #[inline] pub fn new(p1: Point, p2: Point) -> Self { - Self { - top_left_corner: Point::min(p1, p2), - bottom_right_corner: Point::max(p1, p2), - } + Self { top_left_corner: Point::min(p1, p2), bottom_right_corner: Point::max(p1, p2) } } /// Returns a new [Rect] that includes the passed rectangles. + #[inline] pub fn merge(self, other: Self) -> Self { Self { top_left_corner: Point::min(self.top_left_corner, other.top_left_corner), @@ -32,11 +31,13 @@ impl Rect { } /// Get the Top Left corner, the min coordinates. + #[inline] pub fn tl_corner(&self) -> Point { self.top_left_corner } /// Get the Bottom Right corner, the max coordinates. + #[inline] pub fn br_corner(&self) -> Point { self.bottom_right_corner } @@ -44,11 +45,13 @@ impl Rect { impl Point { /// Returns the min components of the two [Point]. + #[inline] pub fn min(p1: Point, p2: Point) -> Point { Point { x: min(p1.x, p2.x), y: min(p1.y, p2.y) } } /// Returns the max components of the two [Point]. + #[inline] pub fn max(p1: Point, p2: Point) -> Point { Point { x: max(p1.x, p2.x), y: max(p1.y, p2.y) } } diff --git a/src/Rust/vvs_lang/Cargo.toml b/src/Rust/vvs_lang/Cargo.toml index 0f83afca939061c62ded0bdd6306a3013c96c280..538d8c5fb0c85c4d578fc6a6e4bd676914c20b32 100644 --- a/src/Rust/vvs_lang/Cargo.toml +++ b/src/Rust/vvs_lang/Cargo.toml @@ -1,19 +1,21 @@ [package] -name = "vvs_lang" +name = "vvs_lang" +description = "Vivy Script Language" version.workspace = true authors.workspace = true edition.workspace = true license.workspace = true -description = "Vivy Script Language" [dependencies] -thiserror.workspace = true -serde.workspace = true -hashbrown.workspace = true -log.workspace = true -regex.workspace = true -nom.workspace = true -nom_locate.workspace = true -anyhow.workspace = true +thiserror.workspace = true +paste.workspace = true +serde.workspace = true +hashbrown.workspace = true +log.workspace = true +regex.workspace = true +anyhow.workspace = true +toml.workspace = true +derive_more.workspace = true -vvs_utils = { path = "../vvs_utils" } +vvs_utils.workspace = true +vvs_parser.workspace = true diff --git a/src/Rust/vvs_lang/VVL.g4 b/src/Rust/vvs_lang/VVL.g4 deleted file mode 100644 index b64d20b2b0dcc18061a71fc46e390d3e5232b42f..0000000000000000000000000000000000000000 --- a/src/Rust/vvs_lang/VVL.g4 +++ /dev/null @@ -1,177 +0,0 @@ -/* -BSD License - -Copyright (c) 2013, Kazunori Sakamoto -Copyright (c) 2016, Alexander Alexeev -Copyright (c) 2023, Maël Martin -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. -3. Neither the NAME of Rainer Schuster nor the NAMEs of its contributors may be - used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -grammar VVL; - -chunk: topblock* EOF; -visibility: ('pub')?; -block: stat* laststat?; - -topblock: visibility 'function' NAME (':' NAME)? funcbody - | visibility 'job' NAME funcbody - | visibility 'const' NAME opttypespec '=' exp - | visibility 'option' NAME opttypespec '=' exp - | ('import' | 'requires') string - ; - -stat: ';' - | varlist '=' explist - | functioncall - | 'do' block 'end' - | 'while' exp 'do' block 'end' - | 'repeat' block 'until' exp - | 'if' exp 'then' block ('elseif' exp 'then' block)* ('else' block)? 'end' - | 'for' NAME '=' exp ',' exp (',' exp)? 'do' block 'end' - | 'for' namelist 'in' explist 'do' block 'end' - | 'let' attnamelist ('=' explist)? - ; - -attnamelist: NAME opttypespec (',' NAME opttypespec)*; -opttypespec: (':' NAME)?; -laststat: 'return' explist? | 'break' | 'continue' ';'?; -varlist: var (',' var)*; -namelist: NAME (',' NAME)*; -explist: (exp ',')* exp; - -exp: 'nil' | 'false' | 'true' - | number - | color - | string - | prefixexp - | tableconstructor - | <assoc=right> exp operatorPower exp - | operatorUnary exp - | exp operatorMulDivMod exp - | exp operatorAddSub exp - | <assoc=right> exp operatorStrcat exp - | exp operatorComparison exp - | exp operatorAnd exp - | exp operatorOr exp - | exp operatorBitwise exp - | '(' exp (',' exp)+ (',')? ')' - ; - -prefixexp: varOrExp nameAndArgs*; -functioncall: varOrExp nameAndArgs+; -varOrExp: var | '(' exp ')'; -var: (NAME | '(' exp ')' varSuffix) varSuffix*; -varSuffix: nameAndArgs* ('[' exp ']' | '.' NAME); -nameAndArgs: (':' NAME)? args; -args: '(' explist? ')' | tableconstructor | string; -funcbody: '(' parlist? ')' '->' NAME 'begin' block 'end'; -parlist: namelist (',')?; -tableconstructor: '{' fieldlist? '}'; -fieldlist: field (fieldsep field)* fieldsep?; -field: '[' exp ']' '=' exp | NAME '=' exp | exp; -fieldsep: ',' | ';'; - -operatorOr: 'or'; -operatorAnd: 'and'; -operatorComparison: '<' | '>' | '<=' | '>=' | '~=' | '==' | '!='; -operatorStrcat: '..'; -operatorAddSub: '+' | '-'; -operatorMulDivMod: '*' | '/' | '%' | '//' | 'mod'; -operatorBitwise: '&' | '^' | '|' | '~' | '<<' | '>>'; -operatorUnary: 'not' | '#' | '-' | '~'; -operatorPower: '^'; - -color: '#(' ... ')'; -number: INT | HEX | FLOAT | HEX_FLOAT; -string: NORMALSTRING | CHARSTRING | LONGSTRING; - -// LEXER - -NAME: [a-zA-Z_][a-zA-Z_0-9]*; -NORMALSTRING: '"' ( EscapeSequence | ~('\\'|'"') )* '"'; -CHARSTRING: '\'' ( EscapeSequence | ~('\''|'\\') )* '\''; -LONGSTRING: '[' NESTED_STR ']'; - -fragment -NESTED_STR: '=' NESTED_STR '=' - | '[' .*? ']' - ; - -INT: Digit+; -HEX: '0' [xX] HexDigit+; - -FLOAT: Digit+ '.' Digit* ExponentPart? - | '.' Digit+ ExponentPart? - | Digit+ ExponentPart - ; - -HEX_FLOAT - : '0' [xX] HexDigit+ '.' HexDigit* HexExponentPart? - | '0' [xX] '.' HexDigit+ HexExponentPart? - | '0' [xX] HexDigit+ HexExponentPart - ; - -fragment -ExponentPart - : [eE] [+-]? Digit+ - ; - -fragment -HexExponentPart - : [pP] [+-]? Digit+ - ; - -fragment -EscapeSequence - : '\\' '\r'? '\n' - ; - -fragment -Digit - : [0-9] - ; - -fragment -HexDigit - : [0-9a-fA-F] - ; - -fragment -SingleLineInputCharacter - : ~[\r\n\u0085\u2028\u2029] - ; - -COMMENT - : '--[' NESTED_STR ']' -> channel(HIDDEN) - ; - -LINE_COMMENT - : '--' SingleLineInputCharacter* -> channel(HIDDEN) - ; - -WS - : [ \t\u000C\r\n]+ -> skip - ; diff --git a/src/Rust/vvs_lang/VVS.g4 b/src/Rust/vvs_lang/VVS.g4 deleted file mode 100644 index 4b82087b3cb3b37d35406813ee426dba2923883a..0000000000000000000000000000000000000000 --- a/src/Rust/vvs_lang/VVS.g4 +++ /dev/null @@ -1,117 +0,0 @@ -// MIT License -// -// Copyright 2023 Maël MARTIN -// -// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -// associated documentation files (the "Software"), to deal in the Software without restriction, -// including without limitation the rights to use, copy, modify, merge, publish, distribute, -// sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all copies or -// substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -// NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -grammar VVS; - -chunk: topblock* mainblock EOF; - -topblock: 'import' string - : 'set' NAME '.' NAME '=' exp - ; - -mainblock: - 'main' NAME '{' - (NAME '=' NAME '.' NAME NAME ';')* - - 'write' '{' (NAME (',' NAME)* (,)?)? '}' - '}' -; - -exp: 'nil' | 'false' | 'true' - | number - | color - | string - ; - -color: '#(' ... ')'; -number: INT | HEX | FLOAT | HEX_FLOAT; -string: NORMALSTRING | CHARSTRING | LONGSTRING; - -// LEXER - -NAME: [a-zA-Z_][a-zA-Z_0-9]*; -NORMALSTRING: '"' ( EscapeSequence | ~('\\'|'"') )* '"'; -CHARSTRING: '\'' ( EscapeSequence | ~('\''|'\\') )* '\''; -LONGSTRING: '[' NESTED_STR ']'; - -fragment -NESTED_STR: '=' NESTED_STR '=' - | '[' .*? ']' - ; - -INT: Digit+; -HEX: '0' [xX] HexDigit+; - -FLOAT: Digit+ '.' Digit* ExponentPart? - | '.' Digit+ ExponentPart? - | Digit+ ExponentPart - ; - -HEX_FLOAT - : '0' [xX] HexDigit+ '.' HexDigit* HexExponentPart? - | '0' [xX] '.' HexDigit+ HexExponentPart? - | '0' [xX] HexDigit+ HexExponentPart - ; - -fragment -ExponentPart - : [eE] [+-]? Digit+ - ; - -fragment -HexExponentPart - : [pP] [+-]? Digit+ - ; - -fragment -EscapeSequence - : '\\' '\r'? '\n' - ; - -fragment -Digit - : [0-9] - ; - -fragment -HexDigit - : [0-9a-fA-F] - ; - -fragment -SingleLineInputCharacter - : ~[\r\n\u0085\u2028\u2029] - ; - -COMMENT - : '--[' NESTED_STR ']' -> channel(HIDDEN) - ; - -LINE_COMMENT - : '--' SingleLineInputCharacter* -> channel(HIDDEN) - ; - -WS - : [ \t\u000C\r\n]+ -> skip - ; - -SHEBANG - : '#' '!' SingleLineInputCharacter* -> channel(HIDDEN) - ; - diff --git a/src/Rust/vvs_lang/samples/retime.vvl b/src/Rust/vvs_lang/samples/retime.vvl deleted file mode 100644 index 3599efdf772e8c6ab925d44238a8831fc4129b1b..0000000000000000000000000000000000000000 --- a/src/Rust/vvs_lang/samples/retime.vvl +++ /dev/null @@ -1,28 +0,0 @@ --- Contains utilities to retime lines from an ASS file. - - -import "math" - - -option before : int = 900 -- Retime time in millisecond for the aparition of the line. -option after : int = 300 -- Retime time in millisecond for the disaparition of the line. - - -pub job start(l: line) -> line --- Here we set the begin of the syllabes at the begin of the line, each --- syllabes will end when it should in fact begin. -begin - for s in l do - s.begin = l.start - before - end -end - - -pub job finish(l: line) -> line --- Here we set the end of the syllabes at the end of the line, each --- syllabes will begin when it should in fact end. -begin - for s in l do - s.finish = l.finish - after - end -end diff --git a/src/Rust/vvs_lang/samples/test.vvs b/src/Rust/vvs_lang/samples/test.vvs deleted file mode 100644 index 3b3c9a603a4114aed37b25b23746bab7c2b71f70..0000000000000000000000000000000000000000 --- a/src/Rust/vvs_lang/samples/test.vvs +++ /dev/null @@ -1,24 +0,0 @@ -import "retime" -import "utils" -import "tag" - - --- Set some options. -set retime.before = 900 -set retime.after = 400 - -set outline.border = 4 -set outline.color = #(rgb: 0, 0, 0) - - --- What we want to do for this script, and how we name the initial value. -main INIT { - BEFORE = retime.start INIT; - AFTER = retime.finish INIT; - - OUTLINED = utils.outline BEFORE, INIT, AFTER; - TAGGED = tag.syl_modulo<3> OUTLINED; -- Here we tag some objects... - - -- What we want to write in the file, in order. - write { OUTLINED } -} diff --git a/src/Rust/vvs_lang/src/ast/constant.rs b/src/Rust/vvs_lang/src/ast/constant.rs new file mode 100644 index 0000000000000000000000000000000000000000..22af5e6bfa46372c1d9fc13ab260789f709885ad --- /dev/null +++ b/src/Rust/vvs_lang/src/ast/constant.rs @@ -0,0 +1,134 @@ +use crate::ast::*; +use anyhow::{anyhow, ensure, Context}; + +/// A constant expr. +#[derive(Debug, PartialEq, Clone)] +pub enum ASTConst { + Nil, + False, + True, + Tuple(Vec<ASTConst>), + Color(ASTVariant<ASTConst>), + String(ASTString), + Integer(ASTInteger), + Floating(ASTFloating), + Table(ASTTable<ASTConst>), +} + +/// Get the type for a const table, returns the more specialized type ([ASTType::UniformTable], etc) +fn get_const_table_type(table: &ASTTable<ASTConst>) -> ASTType { + let integer_keys = table.keys().all(|key| key.parse::<i64>().is_ok()); + let mut uniform_values = table.values().map(|val| val.get_const_type()).collect::<Vec<_>>(); + let uniform_values = uniform_values + .pop() + .map(|ty| uniform_values.into_iter().all(|a| ty.eq(&a)).then_some(ty)); + match (integer_keys, uniform_values) { + (true, Some(Some(ty))) => ASTType::Sequence(Box::new(ty)), + _ => ASTType::Table( + table + .iter() + .map(|(key, value)| (key.clone(), value.get_const_type())) + .collect(), + ), + } +} + +impl Typed for ASTConst { + #[inline] + fn get_type(&self, _: &ASTTypeContext) -> ASTType { + self.get_const_type() + } +} + +impl std::fmt::Display for ASTConst { + #[inline] + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ASTConst::Nil => f.write_str("nil"), + ASTConst::False => f.write_str("false"), + ASTConst::True => f.write_str("true"), + ASTConst::Color(ASTVariant { variant, args }) => write!(f, "color#{variant}{args:?}"), + ASTConst::String(str) => write!(f, "{str:?}"), + ASTConst::Integer(int) => write!(f, "{int}"), + ASTConst::Floating(flt) => write!(f, "{flt}"), + ASTConst::Table(table) => write_ast_table(f, table), + ASTConst::Tuple(tuple) => write_ast_tuple(f, tuple), + } + } +} + +impl MaybeConstExpr for ASTConst { + #[inline] + fn is_const_expr(&self) -> bool { + true + } + + #[inline] + fn eval_const_expr(&self) -> Option<ASTConst> { + Some(self.clone()) + } +} + +impl ASTConst { + #[inline] + pub fn get_const_type(&self) -> ASTType { + match self { + ASTConst::Nil => ASTType::Nil, + ASTConst::True | ASTConst::False => ASTType::Boolean, + ASTConst::Color(..) => ASTType::Color, + ASTConst::String(_) => ASTType::String, + ASTConst::Integer(_) => ASTType::Integer, + ASTConst::Floating(_) => ASTType::Floating, + ASTConst::Tuple(inner) => ASTType::Tuple(inner.iter().map(|expr| expr.get_const_type()).collect()), + ASTConst::Table(content) => get_const_table_type(content), + } + } + + /// Try to create an [ASTConst] from a [toml::Value]. We verify that the value is valid, i.e. + /// we don't have nested tables and such. + /// + /// NOTE: For now we can't construct colors and/or movements from toml values... + pub fn from_toml_value(cache: &ASTStringCacheHandle, value: toml::Value) -> anyhow::Result<Self> { + use toml::Value as TomlValue; + + fn table_from_toml_value( + cache: &ASTStringCacheHandle, + mut values: impl Iterator<Item = (ASTString, TomlValue)>, + ) -> anyhow::Result<ASTConst> { + let (lower, upper) = values.size_hint(); + let table = ASTTable::with_capacity(upper.unwrap_or(lower)); + let table = values.try_fold(table, |mut table, (key, value)| { + let value = ASTConst::from_toml_value(cache, value)?; + ensure!(!matches!(value, ASTConst::Table(_)), "forbiden nested tables"); + table + .insert(key, value) + .map(|_| Err(anyhow!("redefinition of a value in the table"))) + .unwrap_or(Ok(table)) + })?; + Ok(ASTConst::Table(table)) + } + + match value { + TomlValue::Datetime(date) => Ok(ASTConst::String(cache.get(date.to_string()))), + TomlValue::String(str) => Ok(ASTConst::String(cache.get(str))), + + TomlValue::Float(num) => Ok(ASTConst::Floating(num as f32)), + TomlValue::Integer(num) => Ok(ASTConst::Integer(num.try_into().context("integer overflow")?)), + TomlValue::Boolean(true) => Ok(ASTConst::True), + TomlValue::Boolean(false) => Ok(ASTConst::False), + + TomlValue::Array(values) => { + ensure!(values.len() < i32::MAX as usize, "too many elements in array"); + let values = values + .into_iter() + .enumerate() + .map(|(k, v)| (cache.get(k.to_string()), v)); + table_from_toml_value(cache, values) + } + TomlValue::Table(values) => { + ensure!(values.len() < i32::MAX as usize, "too many elements in table"); + table_from_toml_value(cache, values.into_iter().map(|(k, v)| (cache.get(k), v))) + } + } + } +} diff --git a/src/Rust/vvs_lang/src/ast/expression.rs b/src/Rust/vvs_lang/src/ast/expression.rs new file mode 100644 index 0000000000000000000000000000000000000000..79d482fb3a9666a1454171fd7cc2805acfb3e8e5 --- /dev/null +++ b/src/Rust/vvs_lang/src/ast/expression.rs @@ -0,0 +1,441 @@ +use crate::ast::*; +use std::ops::{Deref, DerefMut}; + +#[macro_export] +macro_rules! anon_expression { + (const $variant: ident $($args: tt)?) => { $crate::anon_expression!(Const (ASTConst::$variant $($args)?)) }; + (box const $variant: ident $($args: tt)?) => { Box::new($crate::anon_expression!(Const (ASTConst::$variant $($args)?))) }; + (box $variant: ident $($args: tt)?) => { Box::new($crate::anon_expression!($variant $($args)?)) }; + + ($variant: ident $($args: tt)?) => { + ASTExpr { + span: Default::default(), + content: ASTExprVariant::$variant $($args)?, + } + }; +} + +#[macro_export] +macro_rules! expression { + ($span: expr, $variant: ident $($args: tt)?) => { + ASTExpr { + span: $span.into(), + content: ASTExprVariant::$variant $($args)?, + } + }; +} + +/// Binops, sorted by precedence. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ASTBinop { + /// Assoc: right + Power, + + Mul, + Div, + Mod, + Add, + Sub, + + /// Assoc: right + StrCat, + + CmpLE, + CmpLT, + CmpGE, + CmpGT, + CmpEQ, + CmpNE, + + LogicAnd, + LogicXor, + LogicOr, + + BitAnd, + BitXor, + BitOr, + BitShiftLeft, + BitShiftRight, +} + +/// Unops. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ASTUnop { + LogicNot, + BitNot, + Len, + Neg, +} + +/// Expressions. For the partial equality we skip the span field to be able to test efficiently the +/// parsing. +#[derive(Debug, Clone, Default)] +pub struct ASTExpr { + pub content: ASTExprVariant, + pub span: ASTSpan, +} + +/// Expressions. +#[derive(Debug, PartialEq, Clone)] +pub enum ASTExprVariant { + /// A table, like in Lua + Table(ASTTable<ASTExpr>), + + /// A binary operation, like in most of languages. + Binop(Box<ASTExpr>, ASTBinop, Box<ASTExpr>), + + /// A unary operation, like in most of languages. + Unop(ASTUnop, Box<ASTExpr>), + + /// A call to a function. + FuncCall(Box<ASTExpr>, Vec<ASTExpr>), + + /// A function where the first arguments are binded. + FuncBind(Box<ASTExpr>, Vec<ASTExpr>), + + /// Invocation of a method. To call a function from a table, we don't use the + /// [ASTExprVariant::MethodInvok] thing, but a [ASTExprVariant::FuncCall] where the first + /// element is the dereferencing of the table. Here the name of the method must be known and be + /// like: `{ty}::{method}`. + MethodInvok(Box<ASTExpr>, ASTString, Vec<ASTExpr>), + + /// We access fields from an expression. + Suffixed(Box<ASTExpr>, Vec<ASTField>), + + /// A non-constant expression color. + Color(ASTVariant<ASTExpr>), + + /// Represents a movement for a line or syllabe. We don't have a constant variant for this + /// representation because movements are very dynamic (it depends on the resolution of the + /// video...) and thus doesn't make much sense to have a constant movement. + /// + /// NOTE: See if other people agree to that, there can be some arguments for having a constant + /// movement or an optional one. + Movement(ASTVariant<ASTExpr>), + + /// A tuple, Lua don't have ones but because we won't be stack based we can't do the multiple + /// return thing without a tuple... + Tuple(Vec<ASTExpr>), + + /// A variable load. + Var(ASTVar), + + /// A constant expression. + Const(ASTConst), + + /// The default value for a type. + Default(ASTType), +} + +/// Fields indexes can be expressions or identifiers +#[derive(Debug, PartialEq, Clone)] +pub enum ASTField { + /// We index by a string or an integer... + Expr(ASTSpan, ASTExprVariant), + + /// A name field. + Identifier(ASTSpan, ASTString), +} + +impl PartialEq for ASTExpr { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.content == other.content + } +} + +/// Get the type for a table, returns the more specialized type ([ASTType::UniformTable], etc) +fn get_table_type<T: Typed>(table: &ASTTable<T>, ctx: &ASTTypeContext) -> ASTType { + let integer_keys = table.keys().all(|key| key.parse::<i64>().is_ok()); + let mut uniform_values = table.values().map(|val| val.get_type(ctx)).collect::<Vec<_>>(); + let uniform_values = uniform_values + .pop() + .map(|ty| uniform_values.into_iter().all(|a| ty.eq(&a)).then_some(ty)); + match (integer_keys, uniform_values) { + (true, Some(Some(ty))) => ASTType::Sequence(Box::new(ty)), + _ => ASTType::Table( + table + .iter() + .map(|(key, value)| (key.clone(), value.get_type(ctx))) + .collect(), + ), + } +} + +fn get_table_deref_type(ctx: &ASTTypeContext, table: ASTType, fields: &[ASTField]) -> ASTType { + let (first, tail) = match fields { + [] => return table, + [first, tail @ ..] => (first, tail), + }; + + match table { + ASTType::Tuple(_) => todo!(), + + ASTType::AnyTable => ASTType::Any, + ASTType::Table(_) => todo!(), + ASTType::UniformTable(_) => todo!(), + + ty @ ASTType::Syllabe | ty @ ASTType::Line => match first { + ASTField::Expr(..) => ASTType::Nil, + ASTField::Identifier(_, field) => { + let ty = crate::ast::get_field_extensions(ctx, ty) + .find_map(|(key, ty)| key.eq(&field.as_ref()).then_some(ty.clone())) + .unwrap_or(ASTType::Nil); + get_table_deref_type(ctx, ty, tail) + } + }, + + _ => ASTType::Nil, + } +} + +impl Typed for ASTExprVariant { + fn get_type(&self, ctx: &ASTTypeContext) -> ASTType { + use crate::ast::{ASTBinop::*, ASTUnop::*}; + match self { + ASTExprVariant::FuncBind(_, _) => todo!(), + + ASTExprVariant::MethodInvok(_, _, _) => todo!(), + + ASTExprVariant::FuncCall(_, _) => todo!(), + + ASTExprVariant::Default(ty) => ty.clone(), + ASTExprVariant::Color(_) => ASTType::Color, + ASTExprVariant::Movement(_) => ASTType::Movement, + ASTExprVariant::Const(r#const) => r#const.get_type(ctx), + + ASTExprVariant::Var(var) => match var.get_specified_type() { + Some(ty) => ty.clone(), + None => ctx.get(var), + }, + + ASTExprVariant::Tuple(tuple) => ASTType::Tuple(tuple.iter().map(|expr| expr.get_type(ctx)).collect()), + ASTExprVariant::Table(table) => get_table_type(table, ctx), + ASTExprVariant::Suffixed(expr, fields) => get_table_deref_type(ctx, expr.get_type(ctx), fields), + + ASTExprVariant::Unop(op, inner) => { + use ASTType::*; + match (op, inner.get_type(ctx)) { + (BitNot | LogicNot, ty @ Integer | ty @ Boolean) => ty, + (Neg, ty @ Floating | ty @ Integer | ty @ Boolean) => ty, + ( + Len, + String | Tuple(_) | Syllabe | Line | AnyTable | UniformTable(_) | AnySequence | Table(_) + | Sequence(_), + ) => Integer, + _ => Nil, + } + } + + ASTExprVariant::Binop(left, op, right) => { + use ASTType::*; + let (left, right) = (left.get_type(ctx), right.get_type(ctx)); + match op { + Power => match (left, right) { + (ty @ Integer | ty @ Floating, Integer) => ty, + _ => Nil, + }, + + Mul | Div | Add | Sub => match (left, right) { + (ty @ Integer, Integer) | (ty @ Floating, Floating) => ty, + _ => Nil, + }, + + Mod => match (left, right) { + (Integer, Integer) => Integer, + _ => Nil, + }, + + StrCat => match (left, right) { + (String, String) => String, + _ => Nil, + }, + + CmpLE | CmpLT | CmpGE | CmpGT => match (left, right) { + (Integer, Integer) | (Floating, Floating) => Boolean, + _ => Nil, + }, + + CmpEQ | CmpNE => match right.coercible_to(&left) { + true => Boolean, + false => Nil, + }, + + LogicAnd | LogicXor | LogicOr => match (left, right) { + (Boolean, Boolean) => Boolean, + _ => Nil, + }, + + BitAnd | BitXor | BitOr => match (left, right) { + (Integer, Integer) => Integer, + (Boolean, Boolean) => Boolean, + _ => Nil, + }, + + BitShiftLeft | BitShiftRight => match (left, right) { + (Integer, Integer) => Integer, + _ => Nil, + }, + } + } + } + } +} + +impl Deref for ASTExpr { + type Target = ASTExprVariant; + #[inline] + fn deref(&self) -> &Self::Target { + &self.content + } +} + +impl DerefMut for ASTExpr { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.content + } +} + +impl VariantName for ASTExpr { + #[inline] + fn variant_name(&self) -> &'static str { + self.content.variant_name() + } +} + +impl VariantName for ASTExprVariant { + #[inline] + fn variant_name(&self) -> &'static str { + match self { + ASTExprVariant::Movement(_) => "movement", + ASTExprVariant::Color(_) => "color", + ASTExprVariant::Table(_) => "table", + ASTExprVariant::Binop(_, _, _) => "binary operation", + ASTExprVariant::Unop(_, _) => "unary operation", + ASTExprVariant::FuncCall(_, _) => "function call", + ASTExprVariant::FuncBind(_, _) => "function bind", + ASTExprVariant::MethodInvok(_, _, _) => "method invokation", + ASTExprVariant::Suffixed(_, _) => "prefixed expression", + ASTExprVariant::Tuple(_) => "tuple", + ASTExprVariant::Var(_) => "variable", + ASTExprVariant::Const(_) => "constant", + ASTExprVariant::Default(_) => "default", + } + } +} + +impl ASTField { + #[inline] + pub fn span(&self) -> ASTSpan { + match self { + ASTField::Expr(span, _) | ASTField::Identifier(span, _) => *span, + } + } +} + +impl MaybeConstExpr for ASTExprVariant { + fn is_const_expr(&self) -> bool { + use ASTExprVariant::*; + match self { + // We don't do constant method invokation for now. + FuncCall(_, _) | MethodInvok(_, _, _) | FuncBind(_, _) => false, + + // Depends on the content. + Binop(l, _, r) => l.is_const_expr() && r.is_const_expr(), + Unop(_, inner) => inner.is_const_expr(), + Tuple(inner) => inner.iter().all(|expr| expr.is_const_expr()), + Color(variant) | Movement(variant) => variant.is_const_expr(), + Suffixed(table, suffixes) => table.is_const_expr() && suffixes.iter().all(|field| field.is_const_expr()), + Default(ty) => ty.is_const_constructible(), + + // Well, it depend, for now we will say that it's not compile time evaluable. + Table(_) => false, + Var(_) => false, + + // Obviously + Const(_) => true, + } + } + + fn eval_const_expr(&self) -> Option<ASTConst> { + use ASTExprVariant::*; + match self { + Const(r#const) => Some(r#const.clone()), + + Binop(_, _, _) => todo!(), + Unop(_, _) => todo!(), + + Default(ty) if ty.is_const_constructible() => Some(match ty { + ASTType::Nil | ASTType::Any => ASTConst::Nil, + ASTType::Integer => ASTConst::Integer(0), + ASTType::Floating => ASTConst::Floating(0.), + ASTType::Boolean => ASTConst::False, + _ => unreachable!(), + }), + + Color(ASTVariant { variant, args }) => Some(ASTConst::Color(ASTVariant { + variant: variant.clone(), + args: args + .iter() + .map(|expr| expr.eval_const_expr().ok_or(())) + .collect::<Result<Vec<_>, _>>() + .ok()?, + })), + + Tuple(inner) => Some(ASTConst::Tuple( + inner + .iter() + .map(|expr| expr.eval_const_expr().ok_or(())) + .collect::<Result<Vec<_>, _>>() + .ok()?, + )), + + Suffixed(_, _) + | FuncCall(_, _) + | FuncBind(_, _) + | MethodInvok(_, _, _) + | Table(_) + | Movement(_) + | Default(_) + | Var(_) => None, + } + } +} + +impl Typed for ASTField { + #[inline] + fn get_type(&self, ctx: &ASTTypeContext) -> ASTType { + match self { + ASTField::Expr(_, expr) => expr.get_type(ctx), + ASTField::Identifier(sp, name) => { + let var = ASTVar::new(ctx.strings()).span(sp).name(name.clone()).build(); + ctx.get(&var) + } + } + } +} + +impl MaybeConstExpr for ASTField { + #[inline] + fn is_const_expr(&self) -> bool { + match self { + ASTField::Expr(_, expr) => expr.is_const_expr(), + ASTField::Identifier(_, _) => false, + } + } + + #[inline] + fn eval_const_expr(&self) -> Option<ASTConst> { + match self { + ASTField::Identifier(..) => None, + ASTField::Expr(_, expr) => expr.eval_const_expr(), + } + } +} + +impl Default for ASTExprVariant { + fn default() -> Self { + ASTExprVariant::Const(ASTConst::Nil) + } +} diff --git a/src/Rust/vvs_lang/src/ast/extension.rs b/src/Rust/vvs_lang/src/ast/extension.rs new file mode 100644 index 0000000000000000000000000000000000000000..3cf13f382f70bb48eca12107a8f0a5f4d6292e57 --- /dev/null +++ b/src/Rust/vvs_lang/src/ast/extension.rs @@ -0,0 +1,11 @@ +use crate::ast::{ASTType, ASTTypeContext}; + +#[inline] +pub fn get_field_extensions(_: &ASTTypeContext, ass_type: ASTType) -> impl Iterator<Item = &(&'static str, ASTType)> { + log::error!("todo: add user options for each item"); + match ass_type { + ASTType::Syllabe => [("start", ASTType::Integer), ("finish", ASTType::Integer)].iter(), + ASTType::Line => [("start", ASTType::Integer), ("finish", ASTType::Integer)].iter(), + _ => unreachable!(), + } +} diff --git a/src/Rust/vvs_lang/src/ast/function.rs b/src/Rust/vvs_lang/src/ast/function.rs new file mode 100644 index 0000000000000000000000000000000000000000..6c20bc5b3d2ee5a59c60962931562b2751b64693 --- /dev/null +++ b/src/Rust/vvs_lang/src/ast/function.rs @@ -0,0 +1,36 @@ +use crate::ast::*; + +/// A function. Can also represent a job. +#[derive(Debug, Clone)] +pub struct ASTFunction { + pub name: ASTString, + pub returns: ASTType, + pub arguments: Vec<ASTVar>, + pub content: ASTInstr, + + pub span: ASTSpan, +} + +/// The signature of a callable thing in Vivy Script. +pub type ASTFunctionSignature = (Vec<ASTType>, ASTType); + +impl ASTFunction { + /// Get the signature of a function. + #[inline] + pub fn signature(&self) -> ASTFunctionSignature { + let args = self + .arguments + .iter() + .flat_map(ASTVar::get_specified_type) + .cloned() + .collect(); + (args, self.returns.clone()) + } + + /// Get the type of this function, as a function tpe. + #[inline] + pub fn function_type(&self) -> ASTType { + let (args, returns) = self.signature(); + ASTType::Function(args, Box::new(returns)) + } +} diff --git a/src/Rust/vvs_lang/src/ast/identifier.rs b/src/Rust/vvs_lang/src/ast/identifier.rs new file mode 100644 index 0000000000000000000000000000000000000000..4cc9e14457433e11ea9b0620f7df5a781fbe77ea --- /dev/null +++ b/src/Rust/vvs_lang/src/ast/identifier.rs @@ -0,0 +1,57 @@ +use crate::ast::*; + +#[derive(Debug, Default, PartialEq, Eq, Clone)] +pub enum ASTIdentifier { + /// We ignore the value, like in ocaml and rust, this is the '_'. + #[default] + Joker, + + /// A normal identifier, one that can be used by the user. + String(ASTString), + + /// If an identifier begins by '_' and is followed other things then it is reserved by the + /// parser, the generator, and other things. Those identifiers can't be used by a user and they + /// should never see one. + Reserved(ASTString), +} + +impl std::fmt::Display for ASTIdentifier { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(self.as_ref()) + } +} + +impl AsRef<str> for ASTIdentifier { + fn as_ref(&self) -> &str { + use ASTIdentifier::*; + match self { + Joker => "_", + String(str) | Reserved(str) => str.as_ref(), + } + } +} + +impl ASTIdentifier { + /// Create a new identifier. The passed string will be trimed. If the string is empty or + /// contains non ascii-alphanumeric-underscored characters then an error will be raised. + pub fn new(cache: ASTStringCacheHandle, identifier: impl AsRef<str>) -> Result<Self, String> { + let identifier = identifier.as_ref().trim(); + match identifier + .char_indices() + .find(|(_, c)| '_'.ne(c) && !c.is_ascii_alphanumeric()) + { + Some((idx, char)) => Err(format!("found invalid character '{char}' in identifier at index {idx}")), + None => { + if identifier.is_empty() { + Err("an identifier can't be empty".to_string()) + } else if identifier.starts_with('_') && identifier.len() == 1 { + Ok(Self::Joker) + } else if identifier.starts_with('_') { + Ok(Self::Reserved(cache.get(identifier.trim_start_matches('_')))) + } else { + Ok(Self::Reserved(cache.get(identifier))) + } + } + } + } +} diff --git a/src/Rust/vvs_lang/src/ast/import.rs b/src/Rust/vvs_lang/src/ast/import.rs new file mode 100644 index 0000000000000000000000000000000000000000..f538506dc768ea17185b396dba7d1fc8d79eb676 --- /dev/null +++ b/src/Rust/vvs_lang/src/ast/import.rs @@ -0,0 +1,77 @@ +use crate::ast::{ASTModule, ASTModulePtr, ASTString}; +use hashbrown::HashMap; +use std::{ + cell::RefCell, + path::{Path, PathBuf}, + rc::Rc, +}; + +/// Structure used to resolve module imports. +/// +/// By default, includes the current working dir. +#[derive(Debug)] +pub struct ImportResolver { + path: Vec<PathBuf>, + cache: Rc<RefCell<HashMap<ASTString, ASTModulePtr>>>, +} + +pub(crate) enum ResolveResult { + Path(PathBuf), + Module(ASTModulePtr), +} + +impl FromIterator<PathBuf> for ImportResolver { + #[inline] + fn from_iter<T: IntoIterator<Item = PathBuf>>(iter: T) -> Self { + Self { path: iter.into_iter().collect(), cache: Default::default() } + } +} + +impl Default for ImportResolver { + /// Get the default import resolver, always includes the current working dir... + #[inline] + fn default() -> Self { + Self { path: vec![std::env::current_dir().expect("failed to get the CWD")], cache: Default::default() } + } +} + +impl ImportResolver { + /// Create a new empty resolver. Note that it's different from the default resolver that uses + /// the current working directory (CWD, PWD, etc...) + #[inline] + pub fn empty() -> Self { + Self { path: vec![], cache: Default::default() } + } + + pub(crate) fn resolve(&self, module: impl AsRef<str>) -> Option<ResolveResult> { + let find = |prefix| Self::get_file_path(prefix, module.as_ref()).map(ResolveResult::Path); + self.cache + .borrow() + .get(module.as_ref()) + .cloned() + .map(ResolveResult::Module) + .or_else(|| self.path.iter().find_map(find)) + } + + #[inline] + pub(crate) fn cache_module(&self, name: ASTString, module: ASTModulePtr) { + if let Some(module) = self.cache.borrow_mut().insert(name, module) { + log::error!("re-cache module `{}`", ASTModule::get(&module).name()) + } + } + + fn get_file_path(prefix: impl AsRef<Path>, module: impl AsRef<str>) -> Option<PathBuf> { + let mut file = prefix.as_ref().join(module.as_ref()); + file.set_extension("vvl"); + file.canonicalize() + .map_err(|err| match err.kind() { + std::io::ErrorKind::NotFound => (), + err => log::error!( + "failed to lookup for `{}` in `{}`: {err}", + module.as_ref(), + prefix.as_ref().to_string_lossy() + ), + }) + .ok() + } +} diff --git a/src/Rust/vvs_lang/src/ast/instruction.rs b/src/Rust/vvs_lang/src/ast/instruction.rs new file mode 100644 index 0000000000000000000000000000000000000000..57e64ffa2f497b3fae66521c4e5453a0b73b01fc --- /dev/null +++ b/src/Rust/vvs_lang/src/ast/instruction.rs @@ -0,0 +1,187 @@ +use crate::ast::*; +use std::ops::{Deref, DerefMut}; + +#[macro_export] +macro_rules! anon_instruction { + ($variant: ident $($args: tt)?) => { + ASTInstr { + span: Default::default(), + content: ASTInstrVariant::$variant $($args)?, + } + }; +} + +#[macro_export] +macro_rules! instruction { + ($span: expr, $variant: ident $($args: tt)?) => { + ASTInstr { + span: $span.into(), + content: ASTInstrVariant::$variant $($args)?, + } + }; +} + +/// Instructions. +#[derive(Debug, Clone)] +pub struct ASTInstr { + pub content: ASTInstrVariant, + pub span: ASTSpan, +} + +/// Instructions. +#[derive(Debug, PartialEq, Clone)] +pub enum ASTInstrVariant { + /// Declare variables with something inside. + Decl(Vec<ASTVar>, Vec<ASTExpr>), + + /// Assign into variables. + Assign(Vec<ASTExpr>, Vec<ASTExpr>), + + /// A function call. + FuncCall(Box<ASTExpr>, Vec<ASTExpr>), + + /// A method invokation. + MethodInvok(Box<ASTExpr>, ASTString, Vec<ASTExpr>), + + /// Begin a block. + Block(Vec<ASTInstr>), + + /// A WhileDo instruction. + WhileDo(ASTCondition, Box<ASTInstr>), + + /// Conditionals, contract the elseid blocks. + Cond { if_blocks: Vec<(ASTCondition, ASTInstr)>, else_block: Option<Box<ASTInstr>> }, + + /// For loop, the classic one: + /// ```vvs + /// for elem = 1, 3, 1 do print(elem) end + /// ``` + ForLoop { var: ASTVar, lower: ASTExpr, upper: ASTExpr, step: Option<ASTInteger>, body: Box<ASTInstr> }, + + /// For loop with an iterable expression (table): + /// ```vvs + /// for elem in { 1, 2, 3 } do print(elem) end + /// for elem in ( 1, 2, 3 ) do print(elem) end + /// for elem in my_table do print(elem) end + /// ``` + ForInto { var: ASTVar, list: ASTExpr, body: Box<ASTInstr> }, + + /// Just a noop. + Noop, + + /// Final thing: break from block. + Break, + + /// Final thing: continue to next iteration. + Continue, + + /// Final thing: return something. + Return(ASTExpr), +} + +impl PartialEq for ASTInstr { + fn eq(&self, other: &Self) -> bool { + self.content == other.content + } +} + +fn get_instruction_slice_type(ctx: &ASTTypeContext, block: &[ASTInstr]) -> ASTType { + let Some((last, instructions)) = block.split_last() else { + return ASTType::Nil; + }; + let coerce_type = |from: ASTType, var: &ASTVar| { + let (span, ty, name) = (var.span(), var.get_specified_type().unwrap_or(&from), var.name()); + let strings = ctx.strings(); + let var = ASTVar::new(strings).span(span).name(name.clone()); + if from.coercible_to(ty) { + var.with_type(from).build() + } else { + log::error!(target: "cc", "{span}; try to assign value of type `{from}` into `{name}: {ty}`"); + var.with_type(ASTType::Nil).build() + } + }; + let fold_declaration = |mut ctx, (var, from): (&ASTVar, &ASTExpr)| { + let var = coerce_type(from.get_type(&ctx), var); + let (_, var_ty) = (var.span(), var.get_type(&ctx)); + ctx.declare(var, var_ty); + ctx + }; + let fold_on_declaration = |ctx, instruction: &ASTInstr| match &instruction.content { + ASTInstrVariant::Decl(vars, froms) => vars.iter().zip(froms.iter()).fold(ctx, fold_declaration), + _ => ctx, + }; + last.get_type(&instructions.iter().fold(ctx.for_scope(), fold_on_declaration)) +} + +impl Typed for ASTInstrVariant { + fn get_type(&self, ctx: &ASTTypeContext) -> ASTType { + match self { + ASTInstrVariant::Decl(_, _) + | ASTInstrVariant::Noop + | ASTInstrVariant::Assign(_, _) + | ASTInstrVariant::Break + | ASTInstrVariant::Continue => ASTType::Nil, + + ASTInstrVariant::WhileDo(_, _) | ASTInstrVariant::ForLoop { .. } | ASTInstrVariant::ForInto { .. } => { + ASTType::Nil + } + + ASTInstrVariant::Return(expr) => expr.get_type(ctx), + ASTInstrVariant::Block(block) => get_instruction_slice_type(ctx, block), + ASTInstrVariant::Cond { if_blocks, else_block } => { + let mut types = else_block + .as_ref() + .map(|i| i.get_type(ctx)) + .into_iter() + .chain(if_blocks.iter().map(|(_, i)| i.get_type(ctx))); + types + .next() + .and_then(|ty| types.all(|other| ty.eq(&other)).then_some(ty)) + .unwrap_or_default() + } + + ASTInstrVariant::MethodInvok(_, _, _) | ASTInstrVariant::FuncCall(_, _) => todo!("implement clozures"), + } + } +} + +impl Deref for ASTInstr { + type Target = ASTInstrVariant; + + fn deref(&self) -> &Self::Target { + &self.content + } +} + +impl DerefMut for ASTInstr { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.content + } +} + +impl VariantName for ASTInstr { + fn variant_name(&self) -> &'static str { + self.content.variant_name() + } +} + +impl VariantName for ASTInstrVariant { + fn variant_name(&self) -> &'static str { + match self { + ASTInstrVariant::Decl(_, _) => "variable declaration", + ASTInstrVariant::Assign(_, _) => "variable assignation", + ASTInstrVariant::FuncCall(_, _) => "function call", + ASTInstrVariant::MethodInvok(_, _, _) => "method invokation", + ASTInstrVariant::Block(_) => "instruction block", + ASTInstrVariant::WhileDo(_, _) => "while loop", + ASTInstrVariant::Cond { .. } => "conditionals", + ASTInstrVariant::ForLoop { step: Some(_), .. } => "for loop with step", + ASTInstrVariant::ForLoop { step: None, .. } => "for loop", + ASTInstrVariant::ForInto { .. } => "for into loop", + ASTInstrVariant::Noop => "noop", + ASTInstrVariant::Break => "break statement", + ASTInstrVariant::Continue => "continue statement", + ASTInstrVariant::Return(_) => "return statement", + } + } +} diff --git a/src/Rust/vvs_lang/src/ast/maybe_const_expr.rs b/src/Rust/vvs_lang/src/ast/maybe_const_expr.rs new file mode 100644 index 0000000000000000000000000000000000000000..d0e05e45bda905e3204437f52119bb33c5fd4a7e --- /dev/null +++ b/src/Rust/vvs_lang/src/ast/maybe_const_expr.rs @@ -0,0 +1,26 @@ +use crate::ast::*; +use std::ops::Deref; + +/// Trait for objects that are typed and may be values known at compile time. +/// +/// As long a a type can be dereferenced into a [MaybeConstExpr] thing, it is [MaybeConstExpr]. +pub trait MaybeConstExpr: Typed { + /// Tells whether the thing is a constant expression or not. + fn is_const_expr(&self) -> bool; + + /// Evaluate the expression, if it is indeed a constant expression then returns the result, + /// otherwise return [None]. + fn eval_const_expr(&self) -> Option<ASTConst>; +} + +impl<S: MaybeConstExpr, T: Deref<Target = S>> MaybeConstExpr for T { + #[inline] + fn is_const_expr(&self) -> bool { + self.deref().is_const_expr() + } + + #[inline] + fn eval_const_expr(&self) -> Option<ASTConst> { + self.deref().eval_const_expr() + } +} diff --git a/src/Rust/vvs_lang/src/ast/mod.rs b/src/Rust/vvs_lang/src/ast/mod.rs index 99fe75f81773539ae067e481bc9e23fd5f7e82f4..8da5d32a697e4af2817e09246c41e5b127c1b000 100644 --- a/src/Rust/vvs_lang/src/ast/mod.rs +++ b/src/Rust/vvs_lang/src/ast/mod.rs @@ -1,7 +1,64 @@ +//! Module used to store all the definition of the AST used for parsing VVS/VVL files. + +mod constant; +mod expression; +mod extension; +mod function; +mod identifier; +mod import; +mod instruction; +mod maybe_const_expr; mod module; +mod options; +mod pattern; mod program; mod span; mod string; -mod tree; +mod type_context; +mod typed; +mod types; +mod variable; +mod variant; +mod visibility; + +use hashbrown::HashMap; +use std::rc::Rc; + +pub use self::{ + constant::*, expression::*, extension::*, function::*, identifier::*, import::*, instruction::*, + maybe_const_expr::*, module::*, options::*, pattern::*, program::*, span::*, string::*, type_context::*, typed::*, + types::*, variable::*, variant::*, visibility::*, +}; + +pub type ASTString = Rc<str>; +pub type ASTFloating = f32; +pub type ASTInteger = i32; +pub type ASTTable<T> = HashMap<ASTString, T>; + +pub fn write_ast_table<T: std::fmt::Display>(f: &mut std::fmt::Formatter<'_>, table: &ASTTable<T>) -> std::fmt::Result { + f.write_str("{")?; + if let Some((key, value)) = table.iter().next() { + write!(f, " {key} = {value}")?; + } + for (key, value) in table.iter().skip(1) { + write!(f, ", {key} = {value}")?; + } + f.write_str(" }") +} + +pub fn write_ast_tuple<T: std::fmt::Display>(f: &mut std::fmt::Formatter<'_>, tuple: &[T]) -> std::fmt::Result { + f.write_str("(")?; + if let Some(value) = tuple.iter().next() { + write!(f, " {value}")?; + } + for value in tuple.iter().skip(1) { + write!(f, ", {value}")?; + } + f.write_str(" )") +} -pub use self::{module::*, program::*, span::*, string::*, tree::*}; +/// Trait that allows to get a variant name out of an enum or a struct containing an enum. +pub(crate) trait VariantName { + /// Get the name out of the value. + fn variant_name(&self) -> &'static str; +} diff --git a/src/Rust/vvs_lang/src/ast/module.rs b/src/Rust/vvs_lang/src/ast/module.rs index 335c8b9aad07a0f33f0a122856e83ee80d203eb8..d7eba73a8221a7e8f2fd41f580a6b49f12a58232 100644 --- a/src/Rust/vvs_lang/src/ast/module.rs +++ b/src/Rust/vvs_lang/src/ast/module.rs @@ -1,82 +1,201 @@ -use super::{tree::*, ASTStringCacheHandle}; +use crate::ast::*; use hashbrown::{HashMap, HashSet}; -use std::{cell::RefCell, rc::Rc}; +use std::{ + cell::UnsafeCell, + rc::{Rc, Weak}, +}; /// A VVL module of a Vivy Script -pub struct Module { - functions: HashMap<ASTString, ASTFunction>, - jobs: HashMap<ASTString, ASTJob>, - consts: HashMap<ASTString, (ASTVar, ASTConst)>, +#[derive(Debug, Clone)] +pub struct ASTModule { + /// The name of the module, should be a valid identifier. + name: ASTString, + + /// Checks if we want to put it into the type context or not... + variants: HashMap<ASTString, ASTVariantRules>, + + functions: HashMap<ASTString, (ASTVisibility, ASTFunction)>, + jobs: HashMap<ASTString, (ASTVisibility, ASTFunction)>, + consts: HashMap<ASTString, (ASTVisibility, ASTVar, ASTConst)>, options: HashMap<ASTString, (ASTVar, ASTConst)>, - imports: HashSet<ASTString>, + imports: HashMap<ASTString, (ASTSpan, ASTModulePtr)>, + + /// Contains all the symbols available in the module, to be sure that options, constants, + /// functions and jobs doesn't enter in collision. + symbols: HashSet<ASTString>, - /// Caching for strings, identified by theyr hash and reuse the same memory location to reduce + /// Caching for strings, identified by their hash and reuse the same memory location to reduce /// memory footprint. Use the .finish function from the hasher to get the key. - strings: Rc<RefCell<HashMap<u64, ASTString>>>, + strings: ASTStringCacheHandle, + + /// Type context intern to the module. This is self-referencing. Under the hood we use a weak + /// pointer and a lazy initialize thingy for the type context. + tyctx: ASTTypeContext, } -/// Here, all the getters... -impl Module { +pub type ASTModulePtr = Rc<UnsafeCell<ASTModule>>; +pub type ASTModuleWeakPtr = Weak<UnsafeCell<ASTModule>>; + +impl ASTModule { + /// Create a new empty module. + #[inline] + pub fn new(name: ASTString, strings: ASTStringCacheHandle) -> ASTModulePtr { + Rc::new_cyclic(|ptr| { + let colors_rules = ASTVariantRules::new_colors(strings.clone()); + let movement_rules = ASTVariantRules::new_movements(strings.clone()); + UnsafeCell::new(Self { + name, + strings, + tyctx: ASTTypeContext::new(ptr.clone()), + variants: HashMap::from_iter([ + (colors_rules.name(), colors_rules), + (movement_rules.name(), movement_rules), + ]), + symbols: Default::default(), + functions: Default::default(), + jobs: Default::default(), + consts: Default::default(), + options: Default::default(), + imports: Default::default(), + }) + }) + } + + /// Get all the variant rules. + #[inline] + pub fn all_variant_rules(&self) -> &HashMap<ASTString, ASTVariantRules> { + &self.variants + } + + /// Get a set of rule for a specified variant if it exists in a mutable way. We only expose + /// this function to this crate because it's the only place where we want to be able to mutate + /// the module. + #[inline] + pub(crate) fn variant_rules_mut(&mut self, rule: impl AsRef<str>) -> Option<&mut ASTVariantRules> { + self.variants.get_mut(rule.as_ref()) + } + + /// Get the type context in a constant way. + #[inline] + pub fn tyctx(&self) -> &ASTTypeContext { + &self.tyctx + } + + /// Get the type context in a mutable way. Only possible if we have a mutable reference to the + /// module anyway. If there are multiple strong references to the module it won't be correct... + #[inline] + pub fn tyctx_mut(&mut self) -> &mut ASTTypeContext { + &mut self.tyctx + } + + /// Get the name of the module. + #[inline] + pub fn name(&self) -> ASTString { + self.name.clone() + } + + /// Get a specific option if it exists. + #[inline] + pub fn option(&self, option: impl AsRef<str>) -> Option<&(ASTVar, ASTConst)> { + self.options.get(option.as_ref()) + } + + /// Get a job by its name, returns [None] if the job was not defined. + #[inline] + pub fn job(&self, name: impl AsRef<str>) -> Option<&ASTFunction> { + self.jobs.get(name.as_ref()).map(|(_, job)| job) + } + + /// Get a function by its name, returns [None] if the function was not defined. + #[inline] + pub fn function(&self, name: impl AsRef<str>) -> Option<&ASTFunction> { + self.functions.get(name.as_ref()).map(|(_, function)| function) + } + + /// Get all the options... All the options are public by design so no visibility rule is + /// necessary to query them. + #[inline] + pub fn options(&self) -> impl Iterator<Item = (&ASTVar, &ASTConst)> { + self.options.values().map(|(a, b): &(_, _)| (a, b)) + } + + /// Get all the constants with the specified visibility rule. + #[inline] + pub fn consts(&self, rule: ASTVisibilityRule) -> impl Iterator<Item = (&ASTVar, &ASTConst)> { + self.consts + .values() + .filter_map(move |(v, var, value)| (rule.allows(*v)).then_some((var, value))) + } + + /// Get all the functions from the module with the specified visibility rule. + #[inline] + pub fn functions(&self, rule: ASTVisibilityRule) -> impl Iterator<Item = (ASTString, &ASTFunction)> { + self.functions + .values() + .filter_map(move |(v, f)| rule.allows(*v).then_some((f.name.clone(), f))) + } + + /// Get all the jobs from the module with the specified visibility rule. + #[inline] + pub fn jobs(&self, rule: ASTVisibilityRule) -> impl Iterator<Item = (ASTString, &ASTFunction)> { + self.jobs + .values() + .filter_map(move |(v, f)| rule.allows(*v).then_some((f.name.clone(), f))) + } + + /// Get all the callable items from the module with the specified visibility rule. This + /// includes jobs and functions. + pub(crate) fn callables(&self, rule: ASTVisibilityRule) -> impl Iterator<Item = (ASTString, &ASTFunction)> { + self.functions(rule).chain(self.jobs(rule)) + } + + /// Get all the jobs from a module in a mutable way, with the specified visibility rule. + pub(crate) fn jobs_mut(&mut self, rule: ASTVisibilityRule) -> impl Iterator<Item = (ASTString, &mut ASTFunction)> { + self.jobs + .values_mut() + .filter_map(move |(v, f)| rule.allows(*v).then_some((f.name.clone(), f))) + } + + /// Get all the fonctions from a module in a mutable way, with the specified visibility rule. + pub(crate) fn functions_mut( + &mut self, + rule: ASTVisibilityRule, + ) -> impl Iterator<Item = (ASTString, &mut ASTFunction)> { + self.functions + .values_mut() + .filter_map(move |(v, f)| rule.allows(*v).then_some((f.name.clone(), f))) + } + + /// Get the imported modules, required by the current module. + #[inline] + pub fn imports(&self) -> impl Iterator<Item = &ASTModule> + '_ { + self.imports.iter().map(|(_, (_, module))| ASTModule::get(module)) + } + + /// Get the import location of a module, for debug purpose. + #[inline] + pub fn get_import_location(&self, import: &ASTString) -> Option<ASTSpan> { + self.imports + .iter() + .find_map(|(module, (span, _))| import.eq(module).then_some(*span)) + } + /// Get a handle to the string cache. - pub fn strings(&mut self) -> ASTStringCacheHandle { - ASTStringCacheHandle::new(self.strings.borrow_mut()) + #[inline] + pub fn strings(&self) -> &ASTStringCacheHandle { + &self.strings } -} -/// Here all the setters, we try to have pure functions. -impl Module { - /// Declare a new function. - /// - /// TODO: Use the entry thingy which should be better... - pub fn declare_function(mut self, name: ASTString, function: ASTFunction) -> Self { - if self.functions.contains_key(&name) { - log::warn!(target: "cc", ";re-definition of function {name} at {}", function.span); - } - self.functions.insert(name, function); - self - } - - /// Declare a new job. - /// - /// TODO: Use the entry thingy which should be better... - pub fn declare_job(mut self, name: ASTString, job: ASTJob) -> Self { - if self.jobs.contains_key(&name) { - log::warn!(target: "cc", ";re-definition of job {name} at {}", job.span); - } - self.jobs.insert(name, job); - self - } - - /// Declare a new option. - /// - /// TODO: Use the entry thingy which should be better... - pub fn declare_option(self, var: ASTVar, value: ASTConst) -> Self { - todo!() - } - - /// Declare a new constant. - /// - /// TODO: Use the entry thingy which should be better... - pub fn declare_const(self, var: ASTVar, value: ASTConst) -> Self { - todo!() - } - - /// Declare a new import. - /// - /// TODO: Use the entry thingy which should be better... - pub fn declare_import(self, import: ASTString) -> Self { - todo!() + /// Get a const reference to the module. As long as you don't use the [ASTModule::get_mut] + /// function, this one should be Ok. + #[inline] + pub(crate) fn get(this: &ASTModulePtr) -> &ASTModule { + unsafe { &*this.as_ref().get() } } -} -impl std::fmt::Debug for Module { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("Module") - .field("functions", &self.functions) - .field("jobs", &self.jobs) - .field("consts", &self.consts) - .field("options", &self.options) - .field("imports", &self.imports) - .finish() + /// Get a mutable reference to the module... Unsafe! + #[inline] + pub(crate) fn get_mut(this: &ASTModulePtr) -> *mut ASTModule { + this.as_ref().get() } } diff --git a/src/Rust/vvs_lang/src/ast/options.rs b/src/Rust/vvs_lang/src/ast/options.rs new file mode 100644 index 0000000000000000000000000000000000000000..13d45a6fe8671464b11b6113932f7e6c50c60daa --- /dev/null +++ b/src/Rust/vvs_lang/src/ast/options.rs @@ -0,0 +1,64 @@ +use crate::ast::*; +use anyhow::{bail, Context}; +use hashbrown::HashMap; + +/// Options for a program, represent the thing that is red from a file. +pub struct OptionTable { + modules: HashMap<ASTString, ASTTable<ASTConst>>, +} + +impl OptionTable { + pub fn new(cache: &ASTStringCacheHandle, values: toml::Table) -> anyhow::Result<Self> { + let modules = HashMap::with_capacity(values.len()); + let modules = values.into_iter().try_fold(modules, |mut modules, (name, values)| { + use hashbrown::hash_map::EntryRef::*; + let toml::Value::Table(values) = values else { + bail!("expected a table for `{name}`") + }; + let table = modules + .entry(cache.get(&name)) + .or_insert(ASTTable::with_capacity(values.len())); + values + .into_iter() + .try_for_each(|(option, value)| match table.entry_ref(option.as_str()) { + Occupied(_) => bail!("redefinition of option `{option}` in module `{name}`"), + Vacant(entry) => { + entry.insert(ASTConst::from_toml_value(cache, value)?); + Ok(()) + } + })?; + if table.is_empty() { + modules.remove(name.as_str()); + } + Ok(modules) + }); + Ok(Self { modules: modules.context("invalid toml file")? }) + } +} + +impl Iterator for OptionTable { + type Item = ((ASTString, ASTString), ASTConst); + + fn next(&mut self) -> Option<Self::Item> { + let Self { modules } = self; + let module = modules.keys().next()?.clone(); + + let values = match modules.get_mut(&module) { + Some(values) => values, + None => { + modules.remove(&module); + return None; + } + }; + + let (option, value) = match values.keys().next().cloned() { + Some(option) => values.remove_entry(&option)?, + None => { + modules.remove(&module); + return None; + } + }; + + Some(((module, option), value)) + } +} diff --git a/src/Rust/vvs_lang/src/ast/pattern.rs b/src/Rust/vvs_lang/src/ast/pattern.rs new file mode 100644 index 0000000000000000000000000000000000000000..5b3707d425486bd8dc5e8aa8ae3ed285fc331d2c --- /dev/null +++ b/src/Rust/vvs_lang/src/ast/pattern.rs @@ -0,0 +1,39 @@ +//! In this file we declare things needed to do the pattern matching or boolean check for +//! conditionals. +//! +//! Note that we can only pattern match variants. + +use crate::ast::*; + +/// A condition, two expression must be equal, or should we try to match a thing. +#[derive(Debug, PartialEq, Clone)] +pub enum ASTCondition { + /// Usual if check. + BooleanTrue(ASTExpr), + + /// Does the expression can be pattern-matched or not. This is only for variants. + BindVariant { as_type: ASTType, variant: ASTString, pattern: Vec<ASTPatternElement>, source: ASTVar }, + + /// Tells whever a variable is coercible into a type or not. + CoercibleInto { new: ASTVar, as_type: ASTType, source: ASTVar }, +} + +/// When we match a pattern, we can do conditionals on the value of elements, or we can bind +/// variables that will be visible in the if/elseif/if-let statement. +#[derive(Debug, PartialEq, Clone)] +pub enum ASTPatternElement { + /// Must be equal to this thing. + Const(ASTConst), + + /// Expose this field of the struct in the block if the struct matched. + Var(ASTVar), +} + +impl ASTPatternElement { + pub fn span(&self) -> Option<ASTSpan> { + match self { + ASTPatternElement::Const(_) => None, + ASTPatternElement::Var(var) => Some(var.span()), + } + } +} diff --git a/src/Rust/vvs_lang/src/ast/program.rs b/src/Rust/vvs_lang/src/ast/program.rs index c0691a0cdb1c4b6c9df71815acebe52a93c9a5ed..67088e1efc1f6c3351b22041462517c24290efdf 100644 --- a/src/Rust/vvs_lang/src/ast/program.rs +++ b/src/Rust/vvs_lang/src/ast/program.rs @@ -1,19 +1,15 @@ -use crate::{ast::*, parser::*}; -use hashbrown::{HashMap, HashSet}; -use std::{cell::RefCell, rc::Rc}; +use crate::ast::*; +use hashbrown::HashMap; /// The first element of the tuple is the destination variable, the second is the tuple to describe /// the job picked from a module, the last is the list of variables to use as input for this job. -pub type ProgramOperation = (ASTString, (ASTString, ASTString), Vec<ASTString>); +pub type ProgramOperation = (ASTSpan, ASTString, (ASTString, ASTString), Option<Vec<ASTConst>>, Vec<ASTString>); /// The main VVS file/program. -pub struct Program { - modules: HashMap<ASTString, Module>, - - /// Options specified in the VVL module. All options must be constants. - /// - /// TODO: Remove that, use the options from the modules directly... - options: Vec<((ASTString, ASTVar), ASTConst)>, +#[derive(Debug)] +pub struct ASTProgram { + /// The list of all the modules used in the program, with their import location. + modules: HashMap<ASTString, (ASTSpan, ASTModulePtr)>, /// The setted options, from the VVS file. setted: Vec<((ASTString, ASTString), ASTConst)>, @@ -29,104 +25,116 @@ pub struct Program { /// Caching for strings, identified by theyr hash and reuse the same memory location to reduce /// memory footprint. Use the .finish function from the hasher to get the key. - strings: Rc<RefCell<HashMap<u64, ASTString>>>, + strings: ASTStringCacheHandle, } -/// Here we have all the getters... -impl Program { +impl ASTProgram { + pub fn new(strings: ASTStringCacheHandle) -> Self { + Self { + initial_var: strings.get("INIT"), + setted: Default::default(), + writes: Default::default(), + modules: Default::default(), + operations: Default::default(), + strings, + } + } + + /// Iterate over all the modules in the program. + #[inline] + pub fn modules(&self) -> impl Iterator<Item = &ASTModule> + '_ { + self.modules.values().map(|(_, module)| ASTModule::get(module)) + } + /// Get a handle to the string cache. - pub fn strings(&mut self) -> ASTStringCacheHandle { - ASTStringCacheHandle::new(self.strings.borrow_mut()) + #[inline] + pub fn strings(&self) -> &ASTStringCacheHandle { + &self.strings } /// Get a const reference to a module. - pub fn module(&self, name: impl AsRef<str>) -> Option<&Module> { - self.modules.get(name.as_ref()) + pub fn module(&self, name: impl AsRef<str>) -> Option<&ASTModule> { + self.modules + .get(name.as_ref()) + .map(|(_, module)| ASTModule::get(module)) + } + + /// Get the pointer to a module. Returns [None] if the module was not present in the program. + /// + /// # Safety + /// With this function we create the possibility to make multiple mutable references to the + /// same module down the line, so we mark it as an unsafe operation for now... + pub(crate) unsafe fn module_ptr(&self, name: impl AsRef<str>) -> Option<ASTModulePtr> { + self.modules.get(name.as_ref()).map(|(_, ptr)| ptr.clone()) + } + + /// Get all the available options for this program, with their default value. + pub fn available_options(&self) -> impl Iterator<Item = (ASTString, &ASTVar, &ASTConst)> { + self.modules() + .flat_map(|module| module.options().map(|(var, def)| (module.name(), var, def))) } - /// Get a mutable reference to a module. - pub fn module_mut(&mut self, name: impl AsRef<str>) -> Option<&mut Module> { - self.modules.get_mut(name.as_ref()) + /// Get all the setted options from the program. + #[inline] + pub fn setted_options(&self) -> &[((ASTString, ASTString), ASTConst)] { + self.setted.as_ref() } /// Get the value for an option. For the resolution: we first take the value from the setted /// list before the default value. Note that if we set an option that was never declared we /// don't return it here, it should have raised a warning and should not be used in the code /// anyway. - pub fn options(&self, module: &ASTString, name: &ASTString) -> Option<&ASTConst> { + pub fn option(&self, module: &ASTString, name: &ASTString) -> Option<ASTConst> { let default = self - .options - .iter() - .find_map(|((mm, var), val)| (*module == *mm && *name == *var.name()).then_some(val))?; + .module(module)? + .options() + .find_map(|(var, val)| var.name().eq(name).then_some(val))? + .clone(); let setted = self .setted .iter() .find_map(|((mm, var), val)| (*module == *mm && *name == *var).then_some(val)); - Some(setted.unwrap_or(default)) + Some(setted.cloned().unwrap_or(default)) } -} -/// Here we have all the setters... We always take the [Program] and return a new one for the -/// functions to be pure. -impl Program { - /// Get the operations and the variables to write. Can return an error if a variable was - /// assigned multiple times or if a variable to write was never assigned. - pub fn into_operations(self) -> VVResult<(ASTString, Vec<ProgramOperation>, Vec<ASTString>)> { - let assigned = HashSet::<ASTString>::from_iter( - self.operations - .iter() - .map(|(dest, ..)| dest.clone()) - .chain([self.initial_var.clone()]), - ); - if let Some(unwritten) = self.writes.1.iter().find(|var| !assigned.contains(*var)) { - return Err(VVError::ErrorMsg( - self.writes.0, - format!("variable `{unwritten}` can't be saved because it was never assigned"), - )); - } - let res = (self.initial_var, self.writes); - todo!("add the verified operations to {res:?}") + /// Get the operations and the variables to write. Note that no check is done here. + pub fn as_operations(&self) -> (ASTString, Vec<ProgramOperation>, Vec<ASTString>) { + (self.initial_var.clone(), self.operations.clone(), self.writes.1.clone()) + } + + #[inline] + pub(crate) fn writes_span(&self) -> ASTSpan { + self.writes.0 } /// Set an option in the [Program], if the option was already set or was not declared in a /// [Module] we raise a warning. pub fn set_option(mut self, module: ASTString, name: ASTString, value: ASTConst) -> Self { if self - .options - .iter() - .any(|((mm, nn), _)| *mm == module && name == *nn.name()) + .module(&module) + .map(|module| module.options().any(|(var, _)| var.name().eq(&name))) + .unwrap_or_default() { log::warn!(target: "cc", ";set option {module}.{name} which was not declared"); - } - if self.setted.iter().any(|((mm, nn), _)| *mm == module && name == *nn) { + } else if self.setted.iter().any(|((mm, nn), _)| *mm == module && name == *nn) { log::warn!(target: "cc", ";re-set option {module}.{name}"); } self.setted.push(((module, name), value)); self } - /// Add an option to the module. We try to expose a functional semantic for the usage of the - /// [Program] struct to help the parsing implementation. - pub fn declare_option(mut self, module: ASTString, var: ASTVar, value: ASTConst) -> VVResult<Self> { - let key = (module, var); - if let Some(old) = self.options.iter().find_map(|(k, _)| key.eq(k).then_some(k.1 .0)) { - Err(VVError::OptionRedefined(old, key.0, key.1)) - } else { - self.options.push((key, value)); - Ok(self) + /// Import a module into the program. + #[inline] + pub(crate) fn import_module(mut self, name: ASTString, span: ASTSpan, module: ASTModulePtr) -> Self { + if let Some((_, module)) = self.modules.insert(name, (span, module)) { + log::warn!(target: "cc", ";re-import of module `{}`", ASTModule::get(&module).name()) } + self } -} -impl std::fmt::Debug for Program { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("Program") - .field("modules", &self.modules) - .field("options", &self.options) - .field("setted", &self.setted) - .field("operations", &self.operations) - .field("writes", &self.writes) - .field("initial_var", &self.initial_var) - .finish() + /// Use options from a toml file to set things in the program and simplify a bit said + /// program... + pub fn with_options(self, _options: OptionTable) -> Self { + self } } diff --git a/src/Rust/vvs_lang/src/ast/span.rs b/src/Rust/vvs_lang/src/ast/span.rs index 25c56237168a3258213033a1ed94ab6c1ca48400..512ad50d1b63f85a037387efc47b173e98d07d36 100644 --- a/src/Rust/vvs_lang/src/ast/span.rs +++ b/src/Rust/vvs_lang/src/ast/span.rs @@ -16,6 +16,7 @@ impl std::fmt::Display for ASTSpan { impl ASTSpan { /// Create the span out of a line and column and an offset. The lines and /// columns begeins at 1. The offset begins at 0. + #[inline] pub fn new(line: u64, column: u64, offset: u64) -> Self { assert!(line >= 1); assert!(column >= 1); @@ -23,16 +24,19 @@ impl ASTSpan { } /// Get the column of the span. The column starts at 1 + #[inline] pub fn line(&self) -> u64 { self.line } /// Get the column of the span. The column starts at 1 + #[inline] pub fn column(&self) -> u64 { self.column } /// Get the offset of the span. + #[inline] pub fn offset(&self) -> u64 { self.offset } @@ -40,6 +44,7 @@ impl ASTSpan { /// Merge two spans. For now we just take the first one (the one with the /// lesser offset, i.e. the minimal one). In the future we will update the /// length field (when it's added to the structure...) + #[inline] pub fn merge(s1: Self, s2: Self) -> Self { if PartialOrd::gt(&s1, &s2) { s2 @@ -49,17 +54,22 @@ impl ASTSpan { } } -impl From<nom_locate::LocatedSpan<&str>> for ASTSpan { - fn from(span: nom_locate::LocatedSpan<&str>) -> Self { - Self { - line: span.location_line() as u64, - column: span.naive_get_utf8_column() as u64, - offset: span.location_offset() as u64, - } +impl From<&ASTSpan> for ASTSpan { + #[inline] + fn from(value: &ASTSpan) -> Self { + *value + } +} + +impl From<&mut ASTSpan> for ASTSpan { + #[inline] + fn from(value: &mut ASTSpan) -> Self { + *value } } impl PartialOrd for ASTSpan { + #[inline] fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { PartialOrd::partial_cmp(&self.offset, &other.offset) } diff --git a/src/Rust/vvs_lang/src/ast/string.rs b/src/Rust/vvs_lang/src/ast/string.rs index acd94e432b06376b03a6c0ee281f1d1d3faa8917..acec81a784300f4259745f7fe51efa0f40d9bef4 100644 --- a/src/Rust/vvs_lang/src/ast/string.rs +++ b/src/Rust/vvs_lang/src/ast/string.rs @@ -1,19 +1,15 @@ use super::ASTString; use hashbrown::HashMap; -use std::{cell::RefMut, collections::hash_map::DefaultHasher, hash::Hasher}; +use std::{cell::RefCell, collections::hash_map::DefaultHasher, hash::Hasher, rc::Rc}; /// Used when iterating into the module with mut access, we might need to access the string /// cache... -#[derive(Debug)] -pub struct ASTStringCacheHandle<'a> { - strings: RefMut<'a, HashMap<u64, ASTString>>, +#[derive(Debug, Clone, Default)] +pub struct ASTStringCacheHandle { + strings: Rc<RefCell<HashMap<u64, ASTString>>>, } -impl<'a> ASTStringCacheHandle<'a> { - pub(crate) fn new(strings: RefMut<'a, HashMap<u64, ASTString>>) -> Self { - Self { strings } - } - +impl ASTStringCacheHandle { /// Get the id of a string. fn get_id(str: impl AsRef<str>) -> u64 { let mut hasher = DefaultHasher::new(); @@ -21,21 +17,12 @@ impl<'a> ASTStringCacheHandle<'a> { hasher.finish() } - /// Get a string from the cache, fail if not present. - pub fn get(&mut self, str: impl AsRef<str>) -> Option<ASTString> { - self.strings.get(&Self::get_id(str.as_ref())).cloned() - } - /// Get or create a string in the cache. - pub fn get_or_insert(&mut self, str: impl AsRef<str>) -> ASTString { - let id = Self::get_id(str.as_ref()); - match self.strings.get(&id) { - Some(str) => str.clone(), - None => { - let str = ASTString::from(str.as_ref()); - self.strings.insert(id, str.clone()); - str - } - } + pub fn get(&self, str: impl AsRef<str>) -> ASTString { + self.strings + .borrow_mut() + .entry(Self::get_id(str.as_ref())) + .or_insert_with(|| ASTString::from(str.as_ref())) + .clone() } } diff --git a/src/Rust/vvs_lang/src/ast/tree.rs b/src/Rust/vvs_lang/src/ast/tree.rs deleted file mode 100644 index e9934ae32003928b248c66a51af17b7279c256c2..0000000000000000000000000000000000000000 --- a/src/Rust/vvs_lang/src/ast/tree.rs +++ /dev/null @@ -1,266 +0,0 @@ -use super::ASTSpan; -use hashbrown::HashMap; -use std::rc::Rc; - -pub type ASTString = Rc<str>; -pub type ASTFloating = f32; -pub type ASTInteger = i32; -pub type ASTTable<T> = HashMap<ASTString, T>; - -#[macro_export] -macro_rules! anon_expression { - ($variant: ident $($args: tt)?) => { - ASTExpr { - span: Default::default(), - content: ASTExprVariant::$variant $($args)?, - } - }; -} - -#[macro_export] -macro_rules! expression { - ($span: expr, $variant: ident $($args: tt)?) => { - ASTExpr { - span: $span.into(), - content: ASTExprVariant::$variant $($args)?, - } - }; -} - -#[macro_export] -macro_rules! anon_instruction { - ($variant: ident $($args: tt)?) => { - ASTInstr { - span: Default::default(), - content: ASTInstrVariant::$variant $($args)?, - } - }; -} - -#[macro_export] -macro_rules! instruction { - ($span: expr, $variant: ident $($args: tt)?) => { - ASTInstr { - span: $span.into(), - content: ASTInstrVariant::$variant $($args)?, - } - }; -} - -/// Job to execute on a line, syllabe, list of lines, etc. -#[derive(Debug)] -pub struct ASTJob { - pub name: ASTString, - pub returns: ASTType, - pub arguments: Vec<ASTVar>, - pub content: Vec<ASTInstr>, - - pub span: ASTSpan, -} - -/// A function. -#[derive(Debug)] -pub struct ASTFunction { - pub name: ASTString, - pub arguments: Vec<ASTVar>, - pub content: Vec<ASTInstr>, - - pub span: ASTSpan, -} - -/// Instructions. -#[derive(Debug)] -pub struct ASTInstr { - pub content: ASTInstrVariant, - pub span: ASTSpan, -} - -/// Instructions. -#[derive(Debug, PartialEq)] -pub enum ASTInstrVariant { - /// Declare variables. - Decl(Vec<ASTVar>, Vec<ASTExpr>), - - /// Assign into variables. - Assign(Vec<ASTExpr>, Vec<ASTExpr>), - - /// FunctionCall. - FuncCall(ASTString, Vec<ASTExpr>), - - /// Begin a block. - Block(Vec<ASTInstr>), - - /// A WhileDo instruction. - WhileDo(ASTExpr, Vec<ASTInstr>), - - /// A DoWhile instruction. - RepeatUntil(ASTExpr, Vec<ASTInstr>), - - /// Conditionals, contract the elseid blocks. - Cond { - cond: ASTExpr, - then_block: Vec<ASTInstr>, - elseif_blocks: Vec<(ASTExpr, Vec<ASTInstr>)>, - else_block: Option<Vec<ASTInstr>>, - }, - - /// For loop, the classic one: - /// ```vvs - /// for elem = 1, 3, 1 do print(elem) end - /// ``` - ForLoop { - var: ASTVar, - lower: ASTInteger, - upper: ASTInteger, - step: Option<ASTInteger>, - }, - - /// For loop with an iterable expression (table): - /// ```vvs - /// for elem in { 1, 2, 3 } do print(elem) end - /// for elem in ( 1, 2, 3 ) do print(elem) end - /// for elem in my_table do print(elem) end - /// ``` - ForInto { var: ASTVar, list: ASTExpr }, - - /// Final thing: break from block. - Break, - - /// Final thing: continue to next iteration. - Continue, - - /// Final thing: return something. - Return(ASTExpr), -} - -/// Binops, sorted by precedence. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum ASTBinop { - /// Assoc: right - Power, - - Mul, - Div, - Mod, - Add, - Sub, - - /// Assoc: right - StrCat, - - CmpLE, - CmpLT, - CmpGE, - CmpGT, - CmpEQ, - CmpNE, - - LogicAnd, - LogicXor, - LogicOr, - - BitAnd, - BitXor, - BitOr, - BitShiftLeft, - BitShiftRight, -} - -/// Unops. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum ASTUnop { - LogicNot, - BitNot, - Len, - Neg, -} - -/// Expressions. For the partial equality we skip the span field to be able to test efficiently the -/// parsing. -#[derive(Debug)] -pub struct ASTExpr { - pub content: ASTExprVariant, - pub span: ASTSpan, -} - -/// Expressions. -#[derive(Debug, PartialEq)] -pub enum ASTExprVariant { - Nil, - False, - True, - Integer(ASTInteger), - Floating(ASTFloating), - String(ASTString), - Table(ASTTable<ASTExpr>), - Binop(Box<ASTExpr>, ASTBinop, Box<ASTExpr>), - Unop(ASTUnop, Box<ASTExpr>), - FuncCall(Box<ASTExpr>, Vec<ASTExpr>), - MethodInvok(Box<ASTExpr>, ASTString, Vec<ASTExpr>), - PrefixExpr(Box<ASTExpr>, Vec<ASTField>), - Tuple(Vec<ASTExpr>), - Var(ASTVar), - Const(ASTConst), -} - -/// Fields indexes can be expressions or identifiers -#[derive(Debug, PartialEq)] -pub enum ASTField { - Expr(ASTSpan, ASTExprVariant), - Identifier(ASTSpan, ASTString), -} - -/// Variable thing. Have a name, a where-it-is-defined span and optionally a type. Having to no -/// type means that the type was not already found. -#[derive(Debug, PartialEq, Eq)] -pub struct ASTVar(pub ASTSpan, pub ASTString, pub Option<ASTType>); - -/// A constant expr. -#[derive(Debug, PartialEq)] -pub enum ASTConst { - Color(ASTInteger), - String(ASTString), - Integer(ASTInteger), - Floating(ASTFloating), - Table(ASTTable<ASTConst>), -} - -/// Types. -#[derive(Debug, PartialEq, Eq)] -pub enum ASTType { - Integer, - Floating, - String, - Color, - Line, - Syllabe, - Table(ASTTable<ASTType>), -} - -impl PartialEq for ASTExpr { - fn eq(&self, other: &Self) -> bool { - self.content == other.content - } -} - -impl PartialEq for ASTInstr { - fn eq(&self, other: &Self) -> bool { - self.content == other.content - } -} - -impl ASTVar { - pub fn span(&self) -> ASTSpan { - self.0 - } - - pub fn name(&self) -> &ASTString { - &self.1 - } -} - -impl std::fmt::Display for ASTVar { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(self.1.as_ref()) - } -} diff --git a/src/Rust/vvs_lang/src/ast/type_context.rs b/src/Rust/vvs_lang/src/ast/type_context.rs new file mode 100644 index 0000000000000000000000000000000000000000..829dcc0b799957ea34ee46aa5bd8cc595ce048c4 --- /dev/null +++ b/src/Rust/vvs_lang/src/ast/type_context.rs @@ -0,0 +1,180 @@ +use crate::ast::*; +use core::cell::OnceCell; + +/// Match any item, private or public. +const RULE_ANY: ASTVisibilityRule = ASTVisibilityRule::AtLeast(ASTVisibility::Private); +const RULE_PUB: ASTVisibilityRule = ASTVisibilityRule::Only(ASTVisibility::Public); + +/// The ast context for storing types. Any use of the module must be delayed because when we create +/// the type context for a module, we do it with a cyclic thingy, so the [Rc] is not already +/// constructed (no strong reference), so all we have is a [std::rc::Weak]. +#[derive(Debug, Clone)] +pub struct ASTTypeContext { + module: ASTModuleWeakPtr, + content: OnceCell<ASTTypeContextContent>, +} + +/// The content of the [ASTTypeContext] must be lazyly initialized because of cyclic references +/// with the module and it's type context. +type ASTTypeContextContent = ( + HashMap<ASTString, ASTType>, // Variables + HashMap<ASTString, ASTVariantRules>, // Variants + ASTStringCacheHandle, // String cache + Vec<ASTString>, // Name of imported modules +); + +impl ASTTypeContext { + fn init_content(&self) -> ASTTypeContextContent { + let ptr = self.module.upgrade().expect("no more strong references to module..."); + let module = ASTModule::get(&ptr); + + // We need to import things from the current module and from the imported modules. But for + // imported modules we must prepend the constant/option/callable name by the module name + // with a dot, to call those things like in lua. + let modules = [(None, module)] + .into_iter() + .chain(module.imports().map(|module| (Some(module.name()), module))); + + let scope = modules.flat_map(|(mname, module)| { + let rule = if mname.is_some() { RULE_PUB } else { RULE_ANY }; + let (mname1, mname2, mname3) = (mname.clone(), mname.clone(), mname); + + let options = module.options().map(move |(var, _)| { + let name = mname1 + .as_ref() + .map(|n| module.strings().get(format!("{n}.{}", var.name()))) + .unwrap_or_else(|| var.name()); + (name, var.get_specified_type_or_nil()) + }); + + let consts = module.consts(rule).map(move |(var, _)| { + let name = mname2 + .as_ref() + .map(|n| module.strings().get(format!("{n}.{}", var.name()))) + .unwrap_or_else(|| var.name()); + (name, var.get_specified_type_or_nil()) + }); + + let funcs = module.callables(rule).map(move |(name, func)| { + let name = mname3 + .as_ref() + .map(|n| module.strings().get(format!("{n}.{name}"))) + .unwrap_or(name); + + let arguments = func.arguments.iter().map(|arg| arg.get_specified_type_or_nil()); + let func_type = ASTType::Function(arguments.collect(), Box::new(func.returns.clone())); + + (name, func_type) + }); + + options.chain(consts).chain(funcs) + }); + + let strings = module.strings().clone(); + let variants = module.all_variant_rules().clone(); + let imports = module.imports().map(|module| module.name()).collect(); + (scope.collect(), variants, strings, imports) + } + + fn content(&self) -> &ASTTypeContextContent { + self.content.get_or_init(|| self.init_content()) + } + + fn content_mut(&mut self) -> &mut ASTTypeContextContent { + self.content(); + self.content.get_mut().expect("should be initialized") + } + + #[inline] + pub fn new(module: ASTModuleWeakPtr) -> Self { + Self { module, content: OnceCell::new() } + } + + /// Try to map rules to a pattern. Returns the matching [Some] variables with their destination + /// types or [None] if the matching is not possible to do. Because all rules must be kown at + /// compile time we can now statically if a variant mapping is correct or not! + pub fn variant_try_map_rule( + &self, + rule: impl AsRef<str>, + to: &[ASTPatternElement], + ) -> Option<Vec<(ASTVar, ASTType)>> { + // Get the rule-set. + let rule = self.content().1.get(rule.as_ref())?; + + // The first thing must be a constant string or identifier with the name of the sub-rule. + use ASTPatternElement::*; + let (rule, content) = match to { + [Const(ASTConst::String(sub_rule)), content @ ..] => (rule.rule(sub_rule)?, content), + [Var(var), content @ ..] => { + debug_assert!( + var.get_specified_type().is_none(), + "got a specified type for `{var}`, expected just an identifier" + ); + (rule.rule(var.name())?, content) + } + _ => return None, + }; + + // Be sure that we capture everything in that rule. We don't have the `..` like in rust... + if rule.len() != content.len() { + return None; + } + + Some( + // Do the matching for the sub-rule. + rule.iter().zip(content).map(|(rule, pat)| match pat { + // If a constant is provided we must ensure that the types are compatible! + Const(pat) => rule.coercible_to(&pat.get_const_type()).then_some(None).ok_or(()), + // If a variable is declared then we will return it. If the variable has a + // specified type, we must ensure that the element in the variant can be coerced + // into this specified type. + Var(var) => match var.get_specified_type() { + Some(ty) => rule.coercible_to(ty).then(|| Some((var.clone(), rule.clone()))).ok_or(()), + None => Ok(Some((var.clone(), rule.clone()))), + }, + }) + // Get ride of any errors because of impossible mappings. + .collect::<Result<Vec<Option<(ASTVar, ASTType)>>, ()>>().ok()? + // We collect the successful bindings into a vector, we don't care when a constant + // mapped with an element of the variant. + .into_iter().flatten().collect(), + ) + } + + /// Get a set of rule for a specified variant if it exists. + pub fn variant_complies_with_rule<T: Typed>(&self, rule: impl AsRef<str>, variant: &ASTVariant<T>) -> bool { + let rules = self.content().1.get(rule.as_ref()); + rules.map_or(false, |rules| rules.complies(self, variant)) + } + + /// Create a new context, don't clone as we want to do other things... + #[inline] + pub fn for_scope(&self) -> Self { + self.clone() + } + + /// Get the type of a variable by its name. + pub fn get(&self, name: &ASTVar) -> ASTType { + let (scope, ..) = self.content(); + scope.get(name.name().as_ref()).unwrap().clone() + } + + /// Declare a new variable. Returns an error on redefinition. + pub fn declare(&mut self, var: ASTVar, ty: ASTType) { + if var.is_joker() { + log::debug!("can't declare the joker as a variable at {}", var.span()); + } else if self.content_mut().0.insert(var.name(), ty).is_some() { + panic!() + } + } + + pub fn has_import(&self, import: impl AsRef<str>) -> bool { + self.content().3.iter().any(|scoped| scoped.as_ref() == import.as_ref()) + } + + /// Get the string cache out of the module pointer stored in the context. + #[inline] + pub fn strings(&self) -> &ASTStringCacheHandle { + &self.content().2 + } +} diff --git a/src/Rust/vvs_lang/src/ast/typed.rs b/src/Rust/vvs_lang/src/ast/typed.rs new file mode 100644 index 0000000000000000000000000000000000000000..d2f8b537ae890a37771fc8ac1f6e5f24aa6e1fac --- /dev/null +++ b/src/Rust/vvs_lang/src/ast/typed.rs @@ -0,0 +1,17 @@ +use crate::ast::*; +use std::ops::Deref; + +/// Trait for objects that are types. +/// +/// As long a a type can be dereferenced into a [Typed] thing, it is [Typed]. +pub trait Typed { + /// Get the type of the object. + fn get_type(&self, ctx: &ASTTypeContext) -> ASTType; +} + +impl<S: Typed, T: Deref<Target = S>> Typed for T { + #[inline] + fn get_type(&self, ctx: &ASTTypeContext) -> ASTType { + self.deref().get_type(ctx) + } +} diff --git a/src/Rust/vvs_lang/src/ast/types.rs b/src/Rust/vvs_lang/src/ast/types.rs new file mode 100644 index 0000000000000000000000000000000000000000..cb2315319feb0e68271166e0b2b97fb59a5f31eb --- /dev/null +++ b/src/Rust/vvs_lang/src/ast/types.rs @@ -0,0 +1,226 @@ +use crate::ast::*; + +/// Types. Every object that can be manipulated by the user has a type. We have base types and +/// collection types and special ASS types. +/// +/// Some coercion is possible between collection types... +#[derive(Debug, PartialEq, Eq, Clone, Default)] +pub enum ASTType { + /// Null, unit, nullptr, etc. This is the default type + #[default] + Nil, + + /// An integer + Integer, + + /// A floating point number + Floating, + + /// A string. + String, + + /// A boolean, true/false. + Boolean, + + /// A color + Color, + + /// A movement of a syllabe or line. + Movement, + + /// A variant, can be a color or a movement. + Variant, + + /// A tuple + Tuple(Vec<ASTType>), + + /// Special ASS type, a syllabe. A simple syllabe. + Syllabe, + + /// Special ASS type, a line. It's a collection of [ASTType::Syllabe] with extra steps, can + /// iterate over it. + Line, + + /// A table where the content is not really defined. Because we don't know the keys we can't + /// iterate over it. + AnyTable, + + /// A table where everything inside is defined, a struct. We can't iterate over it but we + /// statically know the keys of the table. + Table(ASTTable<ASTType>), + + /// A uniform table, where all the values has the same types, like a sequence but which string + /// keys. + UniformTable(Box<ASTType>), + + /// A sequence where the content is not really defined, like the any table but with sequences. + AnySequence, + + /// A sequence where every value has the same type. We can iterate over it, like a uniform + /// table, but with integer and continuous keys. + Sequence(Box<ASTType>), + + /// A function type, needs the arguments and the return value. + Function(Vec<ASTType>, Box<ASTType>), + + /// A type that is not known at compile time, the user must check its type with a switch case. + Any, +} + +impl ASTType { + /// Try to see if a type can be pattern matched and if it's the case, returns [Some] bindings + /// to add them to the type context, otherwise return [None]. + pub fn try_match(&self, mctx: &ASTTypeContext, to: &[ASTPatternElement]) -> Option<Vec<(ASTVar, ASTType)>> { + self.get_variant_rule() + .and_then(|rule| mctx.variant_try_map_rule(rule, to)) + } + + /// Tells wether the type is buildable in a const context or not. + #[inline] + pub fn is_const_constructible(&self) -> bool { + matches!(self, ASTType::Nil | ASTType::Tuple(_) | ASTType::Any) + || self.is_numeric() + || self.is_table() + || self.is_sequence() + } + + /// Tells wether the type is numeric or not. + #[inline] + pub fn is_numeric(&self) -> bool { + matches!(self, ASTType::Boolean | ASTType::Integer | ASTType::Floating) + } + + /// Tells whether the type is any sort of sequence or not. + #[inline] + pub fn is_sequence(&self) -> bool { + matches!(self, ASTType::Sequence(_) | ASTType::AnySequence) + } + + /// Tells whether the type is any sort of table or not. + #[inline] + pub fn is_table(&self) -> bool { + matches!(self, ASTType::UniformTable(_) | ASTType::Table(_) | ASTType::AnyTable) + } + + /// Tells whether the type is any sort of variant or not. + #[inline] + pub fn is_variant(&self) -> bool { + matches!(self, ASTType::Variant | ASTType::Color | ASTType::Movement) + } + + /// Get the name of the rules to follow for this variant if it's really a variant. + #[inline] + pub fn get_variant_rule(&self) -> Option<&'static str> { + match self { + ASTType::Color => Some("color"), + ASTType::Movement => Some("movement"), + _ => None, + } + } + + /// Tells whether a type is trivially copiable, i.e. this type won't be managed. + #[inline] + pub fn is_trivialy_copiable(&self) -> bool { + use ASTType::*; + matches!(self, Nil | Integer | Floating | Boolean | Tuple(_)) + } + + pub fn coercible_to(&self, to: &ASTType) -> bool { + use ASTType::*; + match (self, to) { + // Equals... + (x, y) + if (x == y) + || (x.is_table() && matches!(y, AnyTable)) + || (x.is_sequence() && matches!(y, AnySequence)) + || (x.is_variant() && y.is_variant()) => + { + true + } + + // Nil things + (_, Nil) | (Nil, Integer | Floating | Boolean) => true, + (Nil, to) => to.is_table() || to.is_sequence(), + + // Integer things + (Integer, Floating | Boolean) | (Boolean, Integer | Floating) | (Floating, Integer) => true, + + // Sequence / ASS things + (String, Sequence(ty)) | (Sequence(ty), String) => matches!(&**ty, String), + (Sequence(x), Line) | (Line, Sequence(x)) => matches!(&**x, Syllabe), + (Syllabe, Sequence(x)) => matches!(&**x, String), + + // Table / Sequence things + (from, AnyTable) => from.is_sequence() || from.is_table() || from.is_variant(), + (Sequence(to), UniformTable(from)) | (UniformTable(from), Sequence(to)) => from.coercible_to(to), + (Table(table), Sequence(ty)) => { + let integer_keys = table.keys().all(|key| key.parse::<i64>().is_ok()); + let mut uniform_values = table.values().collect::<Vec<_>>(); + let uniform_values = uniform_values + .pop() + .map(|ty| uniform_values.into_iter().all(|a| ty.eq(a)).then_some(ty)); + integer_keys && matches!(uniform_values, Some(Some(table_ty)) if table_ty.eq(ty)) + } + + _ => false, + } + } +} + +impl Typed for ASTType { + #[inline] + fn get_type(&self, _: &ASTTypeContext) -> ASTType { + self.clone() + } +} + +impl std::fmt::Display for ASTType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ASTType::Nil => f.write_str("nil"), + ASTType::Any => f.write_str("any"), + + ASTType::Integer => f.write_str("integer"), + ASTType::Floating => f.write_str("float"), + ASTType::String => f.write_str("string"), + ASTType::Boolean => f.write_str("boolean"), + ASTType::Color => f.write_str("color"), + ASTType::Variant => f.write_str("variant"), + ASTType::Movement => f.write_str("movement"), + + ASTType::Function(args, ret) => { + f.write_str("function (")?; + if let Some(ty) = args.iter().next() { + write!(f, " {ty}")?; + } + for ty in args.iter().skip(1) { + write!(f, ", {ty}")?; + } + write!(f, " ) -> {ret}") + } + + ASTType::Tuple(tuple) => { + f.write_str("(")?; + if let Some(ty) = tuple.iter().next() { + write!(f, " {ty}")?; + } + for ty in tuple.iter().skip(1) { + write!(f, ", {ty}")?; + } + f.write_str(" )") + } + + ASTType::Line => f.write_str("line"), + ASTType::Syllabe => f.write_str("syllabe"), + ASTType::AnySequence => f.write_str("sequence { any }"), + ASTType::Sequence(ty) => write!(f, "sequence {{ {ty} }}"), + + ASTType::AnyTable => f.write_str("table { any }"), + ASTType::UniformTable(inner) => write!(f, "table {{ {inner} }}"), + ASTType::Table(table) => { + f.write_str("table ")?; + write_ast_table(f, table) + } + } + } +} diff --git a/src/Rust/vvs_lang/src/ast/variable.rs b/src/Rust/vvs_lang/src/ast/variable.rs new file mode 100644 index 0000000000000000000000000000000000000000..3cb5383396dbc1865d59ea4a0f4f54887ba95a96 --- /dev/null +++ b/src/Rust/vvs_lang/src/ast/variable.rs @@ -0,0 +1,119 @@ +use crate::ast::*; +use std::sync::atomic::{AtomicU64, Ordering}; + +/// Variable thing. Have a name, a where-it-is-defined span and optionally a type. Having to no +/// type means that the type was not already found. +/// +/// To get the type of a variable, it is either present in the context type hashmap, then we check +/// the specified type, if all failed we return the [ASTType::Nil] type. +#[derive(Debug, Clone)] +pub struct ASTVar(ASTSpan, ASTString, Option<ASTType>); + +#[derive(Debug, Clone)] +pub struct ASTVarBuilder<'a> { + span: ASTSpan, + cache: &'a ASTStringCacheHandle, + name: Option<ASTString>, + specified_ty: Option<ASTType>, +} + +impl<'a> ASTVarBuilder<'a> { + pub fn build(self) -> ASTVar { + let name = self.name.unwrap_or_else(|| { + static ANON: AtomicU64 = AtomicU64::new(0); + self.cache.get(format!("_{}", ANON.fetch_add(1, Ordering::SeqCst))) + }); + ASTVar(self.span, name, self.specified_ty) + } + + pub fn span(mut self, span: impl Into<ASTSpan>) -> Self { + self.span = span.into(); + self + } + + pub fn with_type(mut self, ty: ASTType) -> Self { + self.specified_ty = Some(ty); + self + } + + pub fn name_from(mut self, name: impl AsRef<str>) -> Self { + self.name = Some(self.cache.get(name.as_ref())); + self + } + + pub fn name(mut self, name: ASTString) -> Self { + self.name = Some(name); + self + } +} + +impl PartialEq for ASTVar { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.1 == other.1 && self.2 == other.2 + } +} + +impl ASTVar { + #[inline] + #[allow(clippy::new_ret_no_self)] + pub fn new(cache: &ASTStringCacheHandle) -> ASTVarBuilder { + ASTVarBuilder { span: Default::default(), cache, name: None, specified_ty: None } + } + + #[inline] + pub fn span(&self) -> ASTSpan { + self.0 + } + + /// Get the specified type if any. + #[inline] + pub fn get_specified_type(&self) -> Option<&ASTType> { + self.2.as_ref() + } + + /// Get the specified type. If no type is specified then we say that we return [ASTType::Nil]. + #[inline] + pub fn get_specified_type_or_nil(&self) -> ASTType { + self.get_specified_type().cloned().unwrap_or_default() + } + + /// Set the specified type. + #[inline] + pub fn set_specified_type(&mut self, ty: ASTType) { + self.2 = Some(ty); + } + + /// Get the name. + #[inline] + pub fn name(&self) -> ASTString { + self.1.clone() + } + + /// Tells wether the variable is the joker or not. We can assign into the joker, in this case + /// we yeet the result, but we can never read it. + pub fn is_joker(&self) -> bool { + self.1.as_ref().eq("_") + } +} + +impl From<&ASTVar> for ASTSpan { + #[inline] + fn from(value: &ASTVar) -> Self { + value.span() + } +} + +impl std::fmt::Display for ASTVar { + #[inline] + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(self.1.as_ref()) + } +} + +impl Typed for ASTVar { + #[inline] + fn get_type(&self, ctx: &ASTTypeContext) -> ASTType { + ctx.get(self) + } +} diff --git a/src/Rust/vvs_lang/src/ast/variant.rs b/src/Rust/vvs_lang/src/ast/variant.rs new file mode 100644 index 0000000000000000000000000000000000000000..d6e6da7f70d69c34a97f56c1bca847f2bc83ee65 --- /dev/null +++ b/src/Rust/vvs_lang/src/ast/variant.rs @@ -0,0 +1,192 @@ +use crate::ast::*; + +/// A trait to describes types that are variants. Can be used to handle colors and movements in a +/// generic way. +/// +/// Represents a color in the AST. A color can be: +/// - `#(rgb 0, 0, 0)` for black +/// - `#(green)` for green +/// - etc... +/// +/// Represents a movement in the AST, a movement can be: +/// - `#[pos 500, 500]` +/// - `#[cmove 0, 0, 100, 50, 30]` +/// - etc... +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ASTVariant<T: Typed> { + pub(crate) variant: ASTString, + pub(crate) args: Vec<T>, +} + +pub(crate) struct ASTFmtColor<'a, T: Typed>(&'a ASTVariant<T>, &'a ASTTypeContext); +pub(crate) struct ASTFmtMovement<'a, T: Typed>(&'a ASTVariant<T>, &'a ASTTypeContext); + +impl<T: Typed> ASTVariant<T> { + #[inline] + pub fn variant(&self) -> ASTString { + self.variant.clone() + } + + #[inline] + pub fn args(&self) -> &[T] { + &self.args + } + + #[inline] + pub fn args_mut(&mut self) -> &mut [T] { + &mut self.args + } + + #[inline] + pub fn args_len(&self) -> usize { + self.args.len() + } +} + +impl ASTVariant<ASTExpr> { + #[inline] + pub fn is_const_expr(&self) -> bool { + self.args.iter().all(|expr| expr.is_const_expr()) + } +} + +impl ASTVariant<ASTConst> { + #[inline] + pub fn is_const_expr(&self) -> bool { + true + } +} + +impl<'a, T: Typed> ASTFmtColor<'a, T> { + pub(crate) fn new(variant: &'a ASTVariant<T>, ctx: &'a ASTTypeContext) -> Self { + Self(variant, ctx) + } +} + +impl<'a, T: Typed> ASTFmtMovement<'a, T> { + pub(crate) fn new(variant: &'a ASTVariant<T>, ctx: &'a ASTTypeContext) -> Self { + Self(variant, ctx) + } +} + +impl<'a, T: Typed> std::fmt::Display for ASTFmtColor<'a, T> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let Self(ASTVariant { variant, args }, ctx) = self; + write!(f, "#({variant}")?; + if let Some(arg) = args.iter().next() { + write!(f, " {}", arg.get_type(ctx))?; + } + for arg in args.iter().skip(1) { + write!(f, ", {}", arg.get_type(ctx))?; + } + f.write_str(" )") + } +} + +impl<'a, T: Typed> std::fmt::Display for ASTFmtMovement<'a, T> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let Self(ASTVariant { variant, args }, ctx) = self; + write!(f, "#[{variant}")?; + if let Some(arg) = args.iter().next() { + write!(f, " {}", arg.get_type(ctx))?; + } + for arg in args.iter().skip(1) { + write!(f, ", {}", arg.get_type(ctx))?; + } + f.write_str(" ]") + } +} + +/// Describes a set of rules for a variant. +#[derive(Debug, Clone)] +pub struct ASTVariantRules { + family: ASTString, + rules: HashMap<ASTString, Vec<ASTType>>, +} + +macro_rules! rule { + ($cache: expr, $name: literal) => { ($cache.get($name), vec![]) }; + ($cache: expr, $name: literal -> [$($arg: ident),*]) => { ($cache.get($name), vec![$(ASTType::$arg,)*]) }; +} + +impl ASTVariantRules { + /// Default empty ruleset. + #[inline] + pub fn new(name: ASTString) -> Self { + Self { family: name, rules: Default::default() } + } + + /// Get the name of the family of variants. + #[inline] + pub fn name(&self) -> ASTString { + self.family.clone() + } + + /// Get all the rules of this family. + #[inline] + pub fn rules(&self) -> impl Iterator<Item = (&ASTString, &Vec<ASTType>)> { + self.rules.iter() + } + + /// Get a specific rule if present. + #[inline] + pub fn rule(&self, variant: impl AsRef<str>) -> Option<&[ASTType]> { + self.rules.get(variant.as_ref()).map(|vec| vec.as_ref()) + } + + /// Create a new rule set for colors, the default one. + #[inline] + pub fn new_colors(cache: ASTStringCacheHandle) -> Self { + Self { + family: cache.get("color"), + rules: HashMap::from_iter([ + rule!(cache, "rgb" -> [Integer, Integer, Integer]), + rule!(cache, "rgba" -> [Integer, Integer, Integer, Integer]), + rule!(cache, "black"), + rule!(cache, "white"), + rule!(cache, "grey"), + rule!(cache, "red"), + rule!(cache, "green"), + rule!(cache, "blue"), + ]), + } + } + + /// Create a new rule set for movements, the default one. + #[inline] + pub fn new_movements(cache: ASTStringCacheHandle) -> Self { + Self { + family: cache.get("movement"), + rules: HashMap::from_iter([ + rule![cache, "implicit"], + rule!(cache, "fixed" -> [Integer, Integer]), + rule!(cache, "linear" -> [Integer, Integer, Integer, Integer]), + rule!(cache, "accelerated" -> [Integer, Integer, Integer, Integer, Floating]), + ]), + } + } + + /// Insert a new rule in the ruleset, returns [true] if the rule was inserted successfully, + /// [false] otherwise. + #[must_use] + #[inline] + pub fn insert_rule(&mut self, name: ASTString, types: Vec<ASTType>) -> bool { + self.rules.insert(name, types).is_none() + } + + /// Returns wether a variant complies with the set of allowed one. + #[must_use] + #[inline] + pub fn complies<T: Typed>(&self, ctx: &ASTTypeContext, variant: &ASTVariant<T>) -> bool { + match self.rules.get(&variant.variant) { + None => false, + Some(rule) => { + (rule.len() == variant.args.len()) + && rule + .iter() + .zip(variant.args.iter().map(|arg| arg.get_type(ctx))) + .all(|(rule, arg)| arg.coercible_to(rule)) + } + } + } +} diff --git a/src/Rust/vvs_lang/src/ast/visibility.rs b/src/Rust/vvs_lang/src/ast/visibility.rs new file mode 100644 index 0000000000000000000000000000000000000000..5d5c88f590261feef15dc9d15c1360603ffcb26c --- /dev/null +++ b/src/Rust/vvs_lang/src/ast/visibility.rs @@ -0,0 +1,77 @@ +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub enum ASTVisibility { + #[default] + Private, + Public, +} + +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum ASTVisibilityRule { + Only(ASTVisibility), + AtLeast(ASTVisibility), +} + +impl ASTVisibilityRule { + /// Checks if the rule allows to show an item with the specified visibility [ASTVisibility]. + /// Used to factorize the functions in [crate::ast::ASTModule] and [crate::ast::ASTProgram]. + #[inline] + pub fn allows(&self, vis: ASTVisibility) -> bool { + match self { + ASTVisibilityRule::Only(this) => vis.eq(this), + ASTVisibilityRule::AtLeast(this) => PartialOrd::le(this, &vis), + } + } + + /// Allows all the visibilities. + #[inline] + pub fn any() -> Self { + Self::AtLeast(ASTVisibility::Private) + } +} + +impl Default for ASTVisibilityRule { + fn default() -> Self { + Self::Only(ASTVisibility::Private) + } +} + +impl ASTVisibility { + #[inline] + pub fn as_str(&self) -> &str { + match self { + ASTVisibility::Private => "private", + ASTVisibility::Public => "public", + } + } +} + +impl AsRef<str> for ASTVisibility { + #[inline] + fn as_ref(&self) -> &str { + self.as_str() + } +} + +#[test] +fn test_visibility() { + assert!(ASTVisibility::Private < ASTVisibility::Public); +} + +#[test] +fn test_visibility_rules() { + use ASTVisibility::*; + use ASTVisibilityRule::*; + + assert!(Only(Private).allows(Private)); + assert!(!Only(Private).allows(Public)); + assert!(Only(Public).allows(Public)); + assert!(!Only(Public).allows(Private)); + + assert!(AtLeast(Private).allows(Public)); + assert!(AtLeast(Private).allows(Private)); + assert!(AtLeast(Public).allows(Public)); + assert!(!AtLeast(Public).allows(Private)); + + assert!(ASTVisibilityRule::any().allows(Public)); + assert!(ASTVisibilityRule::any().allows(Private)); +} diff --git a/src/Rust/vvs_lang/src/lib.rs b/src/Rust/vvs_lang/src/lib.rs index a310c76d6da8c9fbfc8dd0f2598b6810a43715cd..97947b62a75617da75838c2f0c88eb6507d14a28 100644 --- a/src/Rust/vvs_lang/src/lib.rs +++ b/src/Rust/vvs_lang/src/lib.rs @@ -1,2 +1,4 @@ +#![allow(dead_code)] + +// Old code, will be purged pub mod ast; -pub mod parser; diff --git a/src/Rust/vvs_lang/src/parser/error.rs b/src/Rust/vvs_lang/src/parser/error.rs deleted file mode 100644 index c6a251764d8cd9db1c693f6126f3dd60f9723a17..0000000000000000000000000000000000000000 --- a/src/Rust/vvs_lang/src/parser/error.rs +++ /dev/null @@ -1,124 +0,0 @@ -use crate::{ast::ASTSpan, parser::*}; -pub(crate) use nom::error::{ContextError as NomContextError, ParseError as NomParseError}; -use thiserror::Error; - -#[macro_export] -macro_rules! nom_err_error { - (vvs: $code: ident $args: tt) => { - Err(nom::Err::Error($crate::parser::error::VVError::$code $args)) - }; - - (vvs bare: $code: ident $args: tt) => { - nom::Err::Error($crate::parser::error::VVError::$code $args) - }; - - (nom: $i: expr, $code: ident) => { - Err(nom::Err::Error(VVError::from_error_kind( - $i, - nom::error::ErrorKind::$code, - ))) - }; - - (nom bare: $i: expr, $code: ident) => { - VVError::from_error_kind($i, nom::error::ErrorKind::$code) - }; -} -pub(crate) use nom_err_error; - -#[macro_export] -macro_rules! nom_err_failure { - (vvs: $code: ident $args: tt) => { - Err(nom::Err::Failure($crate::parser::error::VVError::$code $args)) - }; - - (vvs bare: $code: ident $args: tt) => { - nom::Err::Failure($crate::parser::error::VVError::$code $args) - }; - - (nom: $i: expr, $code: ident) => { - Err(nom::Err::Failure(VVError::from_error_kind( - $i, - nom::error::ErrorKind::$code, - ))) - }; - - (nom bare: $i: expr, $code: ident) => { - VVError::from_error_kind($i, nom::error::ErrorKind::$code) - }; -} -pub(crate) use nom_err_failure; - -#[derive(Debug, Error, PartialEq, Eq)] -pub enum VVError { - #[error("got an error from nom at {0}: {1:?}")] - Nom(ASTSpan, nom::error::ErrorKind), - - #[error("got a nom error needed error at {0}: {1:?}")] - NomNeeded(ASTSpan, nom::Needed), - - #[error("got multiple errors:\n{0:?}")] - Multiple(Vec<VVError>), - - #[error("failed to parse an integer at {0}: {1}")] - ParseIntError(ASTSpan, std::num::ParseIntError), - - #[error("failed to parse a floating number at {0}: {1}")] - ParseFloatError(ASTSpan, std::num::ParseFloatError), - - #[error("failed to get tag `{1}` at {0}")] - FailedToGetTag(ASTSpan, &'static str), - - #[error("not an identifier at {0}")] - NotAnIdentifier(ASTSpan), - - #[error("table index `{1}` redefined at {0}")] - TableIndexRedefined(ASTSpan, ASTString), - - #[error("option `{1}.{2}` at line {} redefined, first definition at {0}", .2.span())] - OptionRedefined(ASTSpan, ASTString, ASTVar), - - #[error("error at {0}: {1}")] - ErrorMsg(ASTSpan, String), -} - -pub type VVParserError<'a, T> = IResult<PSpan<'a>, T, VVError>; -pub type VVResult<T> = Result<T, VVError>; - -impl<'a> NomContextError<PSpan<'a>> for VVError {} - -impl<'a> NomParseError<PSpan<'a>> for VVError { - fn from_error_kind(input: PSpan, kind: nom::error::ErrorKind) -> Self { - Self::Nom(input.into(), kind) - } - - fn append(input: PSpan, kind: nom::error::ErrorKind, other: Self) -> Self { - VVError::Multiple(match other { - VVError::Multiple(mut other) => { - other.push(Self::from_error_kind(input, kind)); - other - } - other => vec![other, Self::from_error_kind(input, kind)], - }) - } -} - -impl<'a> nom::error::FromExternalError<PSpan<'a>, std::num::ParseIntError> for VVError { - fn from_external_error(input: PSpan<'a>, _: nom::error::ErrorKind, e: std::num::ParseIntError) -> Self { - Self::ParseIntError(input.into(), e) - } -} - -impl<'a> nom::error::FromExternalError<PSpan<'a>, std::num::ParseFloatError> for VVError { - fn from_external_error(input: PSpan<'a>, _: nom::error::ErrorKind, e: std::num::ParseFloatError) -> Self { - Self::ParseFloatError(input.into(), e) - } -} - -impl<'a> nom::error::FromExternalError<PSpan<'a>, nom::Err<VVError>> for VVError { - fn from_external_error(i: PSpan, _: nom::error::ErrorKind, e: nom::Err<VVError>) -> Self { - match e { - nom::Err::Incomplete(e) => Self::NomNeeded(i.into(), e), - nom::Err::Error(e) | nom::Err::Failure(e) => e, - } - } -} diff --git a/src/Rust/vvs_lang/src/parser/mod.rs b/src/Rust/vvs_lang/src/parser/mod.rs deleted file mode 100644 index 89d575c3ab92f9d5095b140a59b928de39f21725..0000000000000000000000000000000000000000 --- a/src/Rust/vvs_lang/src/parser/mod.rs +++ /dev/null @@ -1,110 +0,0 @@ -//! Module responsible to parse the user's code, composed of .VVL files where the jobs are defined -//! and .VVS files where the global workflow is written explicitly. Some parsing functions are -//! common between the two parser, those things are expressed here. - -mod error; -mod string; -mod types; - -pub mod vvl; -pub mod vvs; - -use crate::ast::*; - -pub(crate) use crate::parser::{error::*, string::string, types::types}; -pub(crate) use nom::{ - branch::alt, - bytes::complete::{is_not, tag, take_while, take_while_m_n}, - character::{ - complete::{alpha1, alphanumeric1, char, digit1, multispace0, multispace1}, - is_alphanumeric, - }, - combinator::{cut, map, map_opt, map_res, opt, peek, recognize, value, verify}, - error::context, - multi::{fold_many0, many0, many0_count, separated_list0, separated_list1}, - sequence::{delimited, pair, preceded, separated_pair, terminated, tuple}, - IResult, Parser as NomParser, -}; -pub(crate) use nom_locate::LocatedSpan; -pub(crate) use std::{cell::RefCell, rc::Rc}; - -/// A parser span. Will be converted into an AST span latter. -type PSpan<'a> = LocatedSpan<&'a str>; - -pub(crate) fn with_span<'a, T>( - mut cb: impl NomParser<PSpan<'a>, T, VVError>, -) -> impl FnMut(PSpan<'a>) -> VVParserError<'a, (PSpan<'a>, T)> { - move |input: PSpan<'a>| { - let (input, _) = multispace0(input)?; - let (i, res) = cb.parse(input)?; - Ok((i, (input, res))) - } -} - -pub(crate) fn spaced_tag<'a>(str: &'static str) -> impl FnMut(PSpan<'a>) -> VVParserError<'a, ()> { - delimited(multispace0, map(tag(str), |_| ()), multispace0) -} - -pub(crate) fn keyword<'a>(kw: &'static str) -> impl FnMut(PSpan<'a>) -> VVParserError<'a, ()> { - delimited(multispace0, plain_tag(kw), multispace0) -} - -pub(crate) fn plain_tag<'a>(t: &'static str) -> impl FnMut(PSpan<'a>) -> VVParserError<'a, ()> { - move |i| { - let (input, remain) = take_while(|x| is_alphanumeric(x as u8))(tag(t)(i)?.0)?; - remain - .is_empty() - .then_some((input, ())) - .ok_or_else(|| nom_err_error!(vvs bare: FailedToGetTag (i.into(), t))) - } -} - -pub(crate) fn number(i: PSpan) -> VVParserError<ASTInteger> { - alt(( - map_res(preceded(opt(tag("+")), digit1), |digit_str: PSpan| { - digit_str.parse::<ASTInteger>() - }), - map_res(preceded(tag("-"), digit1), |digit_str: PSpan| { - digit_str.parse::<ASTInteger>().map(|x| -x) - }), - ))(i) -} - -pub(crate) fn float(i: PSpan) -> VVParserError<ASTFloating> { - map( - pair( - opt(alt((tag("+"), tag("-")))), - map_res(recognize(tuple((digit1, tag("."), digit1))), |f: PSpan| { - f.fragment().parse::<f32>() - }), - ), - |(sign, value)| { - sign.map(|s| if s.starts_with('-') { -value } else { value }) - .unwrap_or(value) - }, - )(i) -} - -pub(crate) fn identifier(input: PSpan) -> VVParserError<&str> { - let (input, _) = multispace0(input)?; - let (i, id) = match recognize(pair( - alt((alpha1::<PSpan, VVError>, tag("_"))), - many0_count(alt((alphanumeric1, tag("_")))), - ))(input) - { - Ok(ok) => ok, - Err(_) => return nom_err_error!(vvs: NotAnIdentifier (input.into())), - }; - Ok((i, *id.fragment())) -} - -#[test] -fn test_floats_and_numbers() { - assert_eq!(number("1".into()).unwrap().1, 1); - assert_eq!(number("0".into()).unwrap().1, 0); - assert_eq!(number("-1".into()).unwrap().1, -1); - assert_eq!(float("1.0".into()).unwrap().1, 1.0); - assert_eq!(float("0.0".into()).unwrap().1, 0.0); - assert_eq!(float("-1.0".into()).unwrap().1, -1.0); - assert!(float("1.".into()).is_err()); -} diff --git a/src/Rust/vvs_lang/src/parser/string.rs b/src/Rust/vvs_lang/src/parser/string.rs deleted file mode 100644 index 5adb03fffa4bbf5938b79ca681b80b970fd4e813..0000000000000000000000000000000000000000 --- a/src/Rust/vvs_lang/src/parser/string.rs +++ /dev/null @@ -1,99 +0,0 @@ -use super::*; - -/// Parse a unicode sequence, of the form u{XXXX}, where XXXX is 1 to 6 -/// hexadecimal numerals. We will combine this later with parse_escaped_char -/// to parse sequences like \u{00AC}. -fn parse_unicode(input: PSpan) -> VVParserError<char> { - let parse_hex = take_while_m_n(1, 6, |c: char| c.is_ascii_hexdigit()); - let parse_delimited_hex = preceded(char('u'), delimited(char('{'), parse_hex, char('}'))); - let parse_u32 = map_res(parse_delimited_hex, move |hex: PSpan| { - u32::from_str_radix(hex.fragment(), 16) - }); - map_opt(parse_u32, std::char::from_u32)(input) -} - -/// Parse an escaped character: \n, \t, \r, \u{00AC}, etc. -fn parse_escaped_char(input: PSpan) -> VVParserError<char> { - preceded( - char('\\'), - alt(( - parse_unicode, - value('\n', char('n')), - value('\r', char('r')), - value('\t', char('t')), - value('\u{08}', char('b')), - value('\u{0C}', char('f')), - value('\\', char('\\')), - value('/', char('/')), - value('"', char('"')), - )), - ) - .parse(input) -} - -/// Parse a backslash, followed by any amount of whitespace. This is used later -/// to discard any escaped whitespace. -fn parse_escaped_whitespace(input: PSpan) -> VVParserError<&str> { - let (i, str) = preceded(char('\\'), multispace1)(input)?; - Ok((i, str.fragment())) -} - -/// Parse a non-empty block of text that doesn't include \ or " -fn parse_literal(input: PSpan) -> VVParserError<&str> { - verify(map(is_not("\"\\"), |str: PSpan| *str.fragment()), |s: &str| { - !s.is_empty() - })(input) -} - -/// A string fragment contains a fragment of a string being parsed: either -/// a non-empty Literal (a series of non-escaped characters), a single -/// parsed escaped character, or a block of escaped whitespace. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -enum StringFragment<'a> { - Literal(&'a str), - EscapedChar(char), - EscapedWS, -} - -/// Combine parse_literal, parse_escaped_whitespace, and parse_escaped_char -/// into a StringFragment. -fn parse_fragment(input: PSpan) -> VVParserError<StringFragment> { - alt(( - map(parse_literal, StringFragment::Literal), - map(parse_escaped_char, StringFragment::EscapedChar), - value(StringFragment::EscapedWS, parse_escaped_whitespace), - )) - .parse(input) -} - -/// Parse a string. Use a loop of parse_fragment and push all of the fragments -/// into an output string. -pub(crate) fn string(input: PSpan) -> VVParserError<String> { - let build_string = fold_many0(parse_fragment, String::new, |mut string, fragment| { - match fragment { - StringFragment::Literal(s) => string.push_str(s), - StringFragment::EscapedChar(c) => string.push(c), - StringFragment::EscapedWS => {} - } - string - }); - delimited(char('"'), build_string, char('"')).parse(input) -} - -#[test] -fn test_parse_string() { - use vvs_utils::assert_err; - let data = "\"abc\""; - let result = string(data.into()); - assert_eq!(result.unwrap().1, String::from("abc")); - - let data = "\"tab:\\tafter tab, newline:\\nnew line, quote: \\\", emoji: \\u{1F602}, newline:\\nescaped whitespace: \\ abc\""; - let result = string(data.into()); - assert_eq!( - result.unwrap().1, - String::from("tab:\tafter tab, newline:\nnew line, quote: \", emoji: 😂, newline:\nescaped whitespace: abc") - ); - - // Don't do single quotes for now. - assert_err!(string("\'abc\'".into())); -} diff --git a/src/Rust/vvs_lang/src/parser/types.rs b/src/Rust/vvs_lang/src/parser/types.rs deleted file mode 100644 index dffdfff7ce32b4261f170101dcf00baec59adb78..0000000000000000000000000000000000000000 --- a/src/Rust/vvs_lang/src/parser/types.rs +++ /dev/null @@ -1,5 +0,0 @@ -use super::*; - -pub(crate) fn types(input: PSpan) -> VVParserError<ASTType> { - todo!() -} diff --git a/src/Rust/vvs_lang/src/parser/vvl.rs b/src/Rust/vvs_lang/src/parser/vvl.rs deleted file mode 100644 index 4ca6daba506d71a49f82b880439f23a51e06839e..0000000000000000000000000000000000000000 --- a/src/Rust/vvs_lang/src/parser/vvl.rs +++ /dev/null @@ -1,9 +0,0 @@ -//! Module responsible to parse .VVL files, the files where the code is defined. - -mod expr; -mod inst; -mod tabl; -mod tupl; - -use self::{expr::expr, inst::instruction, tabl::table, tupl::any_tuple}; -use crate::{ast::*, parser::*}; diff --git a/src/Rust/vvs_lang/src/parser/vvl/expr.rs b/src/Rust/vvs_lang/src/parser/vvl/expr.rs deleted file mode 100644 index cd7fbfe72f7d45092329b4a282fb093d9a71d0fa..0000000000000000000000000000000000000000 --- a/src/Rust/vvs_lang/src/parser/vvl/expr.rs +++ /dev/null @@ -1,237 +0,0 @@ -use crate::{ast::*, expression, parser::vvl::*}; -use vvs_utils::either; - -#[allow(dead_code)] -pub(crate) fn expr<'a, 'b>( - cache: Rc<RefCell<ASTStringCacheHandle<'b>>>, -) -> impl Fn(PSpan<'a>) -> VVParserError<'a, ASTExpr> + 'b -where - 'b: 'a, -{ - macro_rules! expr { - // No binary expression, parse a unary expression or something else, here we have reached - // the leaf of the tree. We are parsing some things, but we still need to handle more things: - // - tuples - // Stil need to write some tests! - () => { - |cache: Rc<RefCell<ASTStringCacheHandle<'b>>>| { move |input| -> VVParserError<'a, ASTExpr> { - let (input, _) = multispace0(input)?; - let (i, (rvalue, indices, method, args)) = context("expr leaf", tuple(( - // Final leaf for the expression tree. - alt(( - delimited(spaced_tag("("), expr(cache.clone()), spaced_tag(")")), - map(with_span(preceded(tag("$"), number)), |(sp, c)| expression! { sp, Const(ASTConst::Color(c)) }), - map(with_span(keyword("true")), |(sp, _)| expression! { sp, True }), - map(with_span(keyword("false")), |(sp, _)| expression! { sp, False }), - map(with_span(keyword("nil")), |(sp, _)| expression! { sp, Nil }), - map(with_span(preceded(keyword("not"), expr(cache.clone()))), |(sp, e)| expression! { sp, Unop(ASTUnop::LogicNot, Box::new(e)) }), - map(with_span(preceded(spaced_tag("#"), expr(cache.clone()))), |(sp, e)| expression! { sp, Unop(ASTUnop::Len, Box::new(e)) }), - map(with_span(preceded(spaced_tag("-"), expr(cache.clone()))), |(sp, e)| expression! { sp, Unop(ASTUnop::Neg, Box::new(e)) }), - map(with_span(preceded(spaced_tag("~"), expr(cache.clone()))), |(sp, e)| expression! { sp, Unop(ASTUnop::BitNot, Box::new(e)) }), - map(with_span(identifier), |(sp, n)| expression! { sp, Var(ASTVar(sp.into(), cache.borrow_mut().get_or_insert(n), None)) }), - map(with_span(string), |(sp, s)| expression! { sp, Const(ASTConst::String(cache.borrow_mut().get_or_insert(s))) }), - map(with_span(float), |(sp, f)| expression! { sp, Const(ASTConst::Floating(f)) }), - map(with_span(number), |(sp, i)| expression! { sp, Const(ASTConst::Integer(i)) }), - map(with_span(table(cache.clone())), |(sp, t)| expression! { sp, Table(t) }), - map(with_span(any_tuple(cache.clone())), |(sp, t)| expression! { sp, Tuple(t) }), - )), - // Do we need to index into the thing? - many0(alt(( - map(delimited(spaced_tag("["), expr(cache.clone()), spaced_tag("]")), |expr| ASTField::Expr(expr.span, expr.content)), - map(with_span(preceded(spaced_tag("."), identifier)), |(span, field)| ASTField::Identifier(span.into(), cache.borrow_mut().get_or_insert(field))), - ))), - // Function call and method invoking stuff - opt(preceded(spaced_tag(":"), identifier)), - opt(delimited(spaced_tag("("), separated_list0(spaced_tag(","), expr(cache.clone())), spaced_tag(")"))), - )))(input)?; - // Build an expression from the rvalue - let expr = either!(!indices.is_empty() - => expression! { input, PrefixExpr(Box::new(rvalue), indices) } - ; rvalue - ); - // Some logic to handle the call function/method thing - let expr = match (method, args) { - (Some(func), Some(args)) => expression! { input, MethodInvok(Box::new(expr), cache.borrow_mut().get_or_insert(func), args) }, - (None, Some(args)) => expression! { input, FuncCall(Box::new(expr), args) }, - (Some(_), None) => todo!("a method invokation without arguments, should return the function with the first argument bounded"), - (None, None) => expr, - }; - Ok((i, expr)) - }} - }; - - // We are in a node of a binary expression. The binary operator can be a keyword or a - // symbol list, need to handle those two cases differently. - ( $(($str: literal, $op: ident)),+ - $(; $(($strs: literal, $ops: ident)),+)* - $(;)? - ) => { - |cache: Rc<RefCell<ASTStringCacheHandle<'b>>>| { move |i| -> VVParserError<'a, ASTExpr> { - let (input, _) = multispace0(i)?; - let next_clozure = expr!($($(($strs, $ops)),+);*); - let next_clozure = next_clozure(cache.clone()); - let (i, initial) = next_clozure(input)?; - let (i, _) = multispace0(i)?; - let (i, remainder) = many0(alt(($( - |i| -> VVParserError<(ASTBinop, ASTExpr)> { - let (i, item) = either! { $str.chars().next().unwrap().is_ascii_alphabetic() - => preceded(keyword($str), preceded(multispace0, next_clozure.clone()))(i)? - ; preceded(tag($str), preceded(multispace0, next_clozure.clone()))(i)? - }; - Ok((i, (ASTBinop::$op, item))) - } - ),+,)))(i)?; - Ok((i, remainder.into_iter().fold(initial, |acc, (oper, expr)| expression! { - ASTSpan::merge(acc.span, expr.span), - Binop(Box::new(acc), oper, Box::new(expr)) - }))) - }} - }; - } - - let expr = expr! [ /* 12 */ ("|", BitOr) - ; /* 11 */ ("^", BitXor) - ; /* 10 */ ("&", BitAnd) - ; /* 09 */ ("or", LogicOr) - ; /* 08 */ ("xor", LogicXor) - ; /* 07 */ ("and", LogicAnd) - ; /* 06 */ ("==", CmpEQ), ("~=", CmpNE), ("!=", CmpNE) - ; /* 05 */ ("<=", CmpLE), ("<", CmpLT), (">=", CmpGE), (">", CmpGT) - ; /* 04 */ ("..", StrCat) - ; /* 03 */ ("<<", BitShiftLeft), (">>", BitShiftRight) - ; /* 02 */ ("+", Add), ("-", Sub) - ; /* 01 */ ("*", Mul), ("/", Div), ("%", Mod), ("mod", Mod) - ; /* 00 */ ("**", Power) - ]; - - expr(cache) -} - -#[test] -fn test_arithmetic() { - use crate::{anon_expression, ast::ASTBinop::*}; - use hashbrown::HashMap; - let strings = Rc::<RefCell<HashMap<u64, ASTString>>>::default(); - let expr = expr(Rc::new(RefCell::new(ASTStringCacheHandle::new(strings.borrow_mut())))); - let expr = move |str: &'static str| expr(str.into()); - - assert_eq!( - expr("1+2*3").unwrap().1, - anon_expression!(Binop( - Box::new(anon_expression!(Const(ASTConst::Integer(1)))), - Add, - Box::new(anon_expression!(Binop( - Box::new(anon_expression!(Const(ASTConst::Integer(2)))), - Mul, - Box::new(anon_expression!(Const(ASTConst::Integer(3)))) - ))) - )) - ); - assert_eq!( - expr("2*3+1").unwrap().1, - anon_expression!(Binop( - Box::new(anon_expression!(Binop( - Box::new(anon_expression!(Const(ASTConst::Integer(2)))), - Mul, - Box::new(anon_expression!(Const(ASTConst::Integer(3)))) - ))), - Add, - Box::new(anon_expression!(Const(ASTConst::Integer(1)))), - )) - ); -} - -#[test] -fn test_valid_table() { - use crate::{anon_expression, ast::*}; - use hashbrown::HashMap; - use vvs_utils::{assert_ok, assert_some}; - let strings = Rc::<RefCell<HashMap<u64, ASTString>>>::default(); - let table = expr(Rc::new(RefCell::new(ASTStringCacheHandle::new(strings.borrow_mut())))); - let table = move |str: &'static str| table(str.into()); - let table = assert_ok!(table( - r#"{ toto = "tata", foo = 3.14, ["bar"] = 42, titi = {}, oupsy = nil }"# - )); - - let table = match table.1.content { - ASTExprVariant::Table(table) => table, - expr => panic!("should be a table, got {expr:#?}"), - }; - - assert_eq!( - assert_some!(table.get("toto")).content, - anon_expression!(Const(ASTConst::String("tata".into()))).content - ); - - assert_eq!( - assert_some!(table.get("foo")).content, - anon_expression!(Const(ASTConst::Floating(3.14))).content - ); - - assert_eq!( - assert_some!(table.get("bar")).content, - anon_expression!(Const(ASTConst::Integer(42))).content - ); - - assert_eq!( - assert_some!(table.get("titi")).content, - anon_expression!(Table(HashMap::default())).content - ); - - assert_eq!( - assert_some!(table.get("oupsy")).content, - anon_expression!(Nil).content - ); -} - -#[test] -fn test_redefined_key_table() { - use crate::ast::*; - use hashbrown::HashMap; - use vvs_utils::assert_err; - let strings = Rc::<RefCell<HashMap<u64, ASTString>>>::default(); - let table = expr(Rc::new(RefCell::new(ASTStringCacheHandle::new(strings.borrow_mut())))); - let table = move |str: &'static str| table(str.into()); - assert_err!(table(r#"{ toto = "tata", toto = nil }"#)); -} - -#[test] -fn test_tuple_invalid() { - use crate::ast::*; - use hashbrown::HashMap; - use vvs_utils::assert_err; - let strings = Rc::<RefCell<HashMap<u64, ASTString>>>::default(); - let expr = expr(Rc::new(RefCell::new(ASTStringCacheHandle::new(strings.borrow_mut())))); - let expr = move |str: &'static str| expr(str.into()); - match expr(r#""a", "b", "c""#) { - Ok((i, expr)) if i.is_empty() => panic!("successfully parsed {expr:#?}"), - _ => {} - } - assert_err!(expr("(1,)")); -} - -#[test] -fn test_tuple() { - use crate::{anon_expression, ast::*}; - use hashbrown::HashMap; - use vvs_utils::assert_ok; - let strings = Rc::<RefCell<HashMap<u64, ASTString>>>::default(); - let expr = expr(Rc::new(RefCell::new(ASTStringCacheHandle::new(strings.borrow_mut())))); - let expr = move |str: &'static str| expr(str.into()); - assert_eq!( - assert_ok!(expr("(1, 2, 3, 4)")).1, - anon_expression!(Tuple(vec![ - anon_expression!(Const(ASTConst::Integer(1))), - anon_expression!(Const(ASTConst::Integer(2))), - anon_expression!(Const(ASTConst::Integer(3))), - anon_expression!(Const(ASTConst::Integer(4))), - ])) - ); - assert_eq!( - assert_ok!(expr("(1, 2,)")).1, - anon_expression!(Tuple(vec![ - anon_expression!(Const(ASTConst::Integer(1))), - anon_expression!(Const(ASTConst::Integer(2))), - ])) - ); -} diff --git a/src/Rust/vvs_lang/src/parser/vvl/inst.rs b/src/Rust/vvs_lang/src/parser/vvl/inst.rs deleted file mode 100644 index 4699bcaf2be78b62f998dd1acca2bb509dff1376..0000000000000000000000000000000000000000 --- a/src/Rust/vvs_lang/src/parser/vvl/inst.rs +++ /dev/null @@ -1,76 +0,0 @@ -use crate::{ast::*, instruction, parser::vvl::*}; - -pub(crate) fn do_end_block<'a, 'b>( - r#do: &'static str, - end: &'static str, - cache: Rc<RefCell<ASTStringCacheHandle<'b>>>, -) -> impl Fn(PSpan<'a>) -> VVParserError<'a, Vec<ASTInstr>> + 'b -where - 'b: 'a, -{ - move |input| { - let (input, _) = multispace0(input)?; - delimited(keyword(r#do), many0(instruction(cache.clone())), keyword(end))(input) - } -} - -#[allow(dead_code)] -pub(crate) fn instruction<'a, 'b>( - cache: Rc<RefCell<ASTStringCacheHandle<'b>>>, -) -> impl Fn(PSpan<'a>) -> VVParserError<'a, ASTInstr> + 'b -where - 'b: 'a, -{ - move |input| { - let (input, _) = multispace0(input)?; - terminated( - alt(( - // Break/Continue loops - map(with_span(keyword("break")), |(sp, _)| instruction!(sp, Break)), - map(with_span(keyword("continue")), |(sp, _)| instruction!(sp, Continue)), - // Variable assignation. Don't do the destructuring for now. - map( - with_span(separated_pair( - expr(cache.clone()), - spaced_tag("="), - expr(cache.clone()), - )), - |(sp, (dest, src))| instruction!(sp, Assign(vec![dest], vec![src])), - ), - // Variable declaration. Don't do the destructuring for now. - map( - with_span(tuple(( - keyword("let"), - identifier, - opt(types), - spaced_tag("="), - expr(cache.clone()), - ))), - |(sp, (_, name, ty, _, decl))| { - let var = ASTVar(sp.into(), cache.borrow_mut().get_or_insert(name), ty); - instruction!(sp, Decl(vec![var], vec![decl])) - }, - ), - // A do-end block with a list of instructions inside it. - map(with_span(do_end_block("do", "end", cache.clone())), |(sp, body)| { - instruction!(sp, Block(body)) - }), - // While loop. - map( - with_span(pair( - preceded(keyword("while"), expr(cache.clone())), - do_end_block("do", "end", cache.clone()), - )), - |(sp, (cond, body))| instruction!(sp, WhileDo(cond, body)), - ), - // A DoWhile block (or a reapeat until in lua...) - map( - with_span(pair(do_end_block("do", "until", cache.clone()), expr(cache.clone()))), - |(sp, (body, cond))| instruction!(sp, RepeatUntil(cond, body)), - ), - )), - // We may terminate with a semicolon - opt(spaced_tag(";")), - )(input) - } -} diff --git a/src/Rust/vvs_lang/src/parser/vvl/tabl.rs b/src/Rust/vvs_lang/src/parser/vvl/tabl.rs deleted file mode 100644 index 25f8d36df88c09b665561a1465f32353f0520cdc..0000000000000000000000000000000000000000 --- a/src/Rust/vvs_lang/src/parser/vvl/tabl.rs +++ /dev/null @@ -1,56 +0,0 @@ -use super::*; -use hashbrown::HashMap; - -/// Parses the keys in tables or returns an error. Keys can be identifiers or a string between -/// square braquets: `[`, `]`. -fn key<'a, 'b>(cache: Rc<RefCell<ASTStringCacheHandle<'b>>>) -> impl Fn(PSpan<'a>) -> VVParserError<'a, ASTString> + 'b -where - 'b: 'a, -{ - move |input: PSpan| -> VVParserError<ASTString> { - let (input, _) = multispace0(input)?; - alt(( - map(delimited(spaced_tag("["), string, spaced_tag("]")), |str| { - cache.borrow_mut().get_or_insert(str) - }), - map(identifier, |str| cache.borrow_mut().get_or_insert(str)), - ))(input) - } -} - -/// Parses a separator for key value pairs for the table parser. In Lua separators can be `,` or -/// `;` for some reasons... -fn separator(input: PSpan) -> VVParserError<()> { - alt((spaced_tag(","), spaced_tag(";")))(input) -} - -/// Parses a table or returns an error. -pub(crate) fn table<'a, 'b>( - cache: Rc<RefCell<ASTStringCacheHandle<'b>>>, -) -> impl Fn(PSpan<'a>) -> VVParserError<'a, ASTTable<ASTExpr>> + 'b -where - 'b: 'a, -{ - move |input| { - let (input, _) = multispace0(input)?; - let table_key_value_pair = separated_pair(key(cache.clone()), spaced_tag("="), expr(cache.clone())); - let (i, content) = context( - "table", - delimited( - spaced_tag("{"), - separated_list0(separator, table_key_value_pair), - preceded(opt(separator), spaced_tag("}")), - ), - )(input)?; - let hashmap = HashMap::with_capacity(content.len()); - let hashmap = content.into_iter().try_fold(hashmap, |mut hashmap, (key, value)| { - if hashmap.contains_key(&key) { - nom_err_error!(vvs: TableIndexRedefined (value.span, key)) - } else { - hashmap.insert(key, value); - Ok(hashmap) - } - })?; - Ok((i, hashmap)) - } -} diff --git a/src/Rust/vvs_lang/src/parser/vvl/tupl.rs b/src/Rust/vvs_lang/src/parser/vvl/tupl.rs deleted file mode 100644 index 9bd32b635c388e59218812fcd5b78ee5ac5e066e..0000000000000000000000000000000000000000 --- a/src/Rust/vvs_lang/src/parser/vvl/tupl.rs +++ /dev/null @@ -1,24 +0,0 @@ -use super::*; - -/// Unlike Lua, we require parens (`(` `)`) around tuples. -pub(crate) fn any_tuple<'a, 'b>( - cache: Rc<RefCell<ASTStringCacheHandle<'b>>>, -) -> impl Fn(PSpan<'a>) -> VVParserError<'a, Vec<ASTExpr>> + 'b -where - 'b: 'a, -{ - move |input| { - let (input, _) = multispace0(input)?; - let (i, (head, mut tail)) = delimited( - spaced_tag("("), - separated_pair( - expr(cache.clone()), - spaced_tag(","), - separated_list1(spaced_tag(","), expr(cache.clone())), - ), - preceded(opt(spaced_tag(",")), spaced_tag(")")), - )(input)?; - tail.insert(0, head); - Ok((i, tail)) - } -} diff --git a/src/Rust/vvs_lang/src/parser/vvs.rs b/src/Rust/vvs_lang/src/parser/vvs.rs deleted file mode 100644 index 727017478067eb2dfe2f315de931b7096af3a656..0000000000000000000000000000000000000000 --- a/src/Rust/vvs_lang/src/parser/vvs.rs +++ /dev/null @@ -1,16 +0,0 @@ -//! Module responsible to parse .VVS files, the files where jobs from .VVS files are composed and -//! where the global workflow of the script is written by the user. - -use std::path::Path; - -use crate::{ast::*, parser::*}; - -/// Parses the content of a file. -pub fn parse_vvs<'a>(_: impl AsRef<str> + 'a) -> VVParserError<'a, Program> { - todo!() -} - -/// Parses a file. -pub fn parse_vvs_file(_: impl AsRef<Path>) -> VVResult<Program> { - todo!() -} diff --git a/src/Rust/vvs_lib/Cargo.toml b/src/Rust/vvs_lib/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..0285744a772987a0dd0f8c6c621594ca38e5dab1 --- /dev/null +++ b/src/Rust/vvs_lib/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "vvs_lib" +description = "A C library to expose functionalities to C/C++" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[lib] +name = "vivy" +crate-type = ["staticlib"] + +[dependencies] +log.workspace = true +serde.workspace = true +hashbrown.workspace = true +serde_json.workspace = true + +vvs_ass.workspace = true + +[build-dependencies] +cbindgen.workspace = true diff --git a/src/Rust/vvs_lib/build.rs b/src/Rust/vvs_lib/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..66862fd632de377b606a610b88ebc7d1bf0a13f6 --- /dev/null +++ b/src/Rust/vvs_lib/build.rs @@ -0,0 +1,24 @@ +use cbindgen::{Braces, Language, Style}; + +fn main() { + cbindgen::Builder::new() + .with_crate(std::env::var("CARGO_MANIFEST_DIR").unwrap()) + .with_parse_deps(true) + .with_parse_include(&["vvs_ass"]) + .with_documentation(true) + .with_header("/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */") + .with_language(Language::C) + .with_no_includes() + .with_sys_include("inttypes.h") + .with_include_version(true) + .with_line_length(120) + .with_style(Style::Both) + .with_cpp_compat(true) + .with_pragma_once(true) + .with_namespaces(&["VVLib", "C"]) + .with_tab_width(4) + .with_braces(Braces::NextLine) + .generate() + .expect("Failed to generate config") + .write_to_file("../VVLib.h"); +} diff --git a/src/Rust/vvs_lib/src/ass_elements.rs b/src/Rust/vvs_lib/src/ass_elements.rs new file mode 100644 index 0000000000000000000000000000000000000000..aed629932be583bb28f2b0aa453d45ec4ae563a3 --- /dev/null +++ b/src/Rust/vvs_lib/src/ass_elements.rs @@ -0,0 +1,191 @@ +//! Contains wrappers for the container, the line, syllabes, etc... +#![allow(clippy::missing_safety_doc)] + +use crate::{AuxTable, StringSlice}; +use alloc::{boxed::Box, vec::Vec}; +use core::{ + ffi::{c_char, CStr}, + mem, + ptr::{self, NonNull}, +}; +use vvs_ass::{ass_container_from_file, ASSStyle}; + +/// Wraps the container that holds all the content of the ASS file / Vivy file. +pub struct ASSContainer(vvs_ass::ASSContainer<AuxTable>); + +/// Wraps a line in an ASS file. +pub struct ASSLine(vvs_ass::ASSLine<AuxTable>); + +/// Wraps syllabes, contained in lines in ASS files. +pub struct ASSSyllabe(vvs_ass::ASSSyllabe<AuxTable>); + +/// Get the number of lines in the container. +#[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn ASSContainerGetLinesCount(this: *const ASSContainer) -> i32 { (*this).0.lines.len() as i32 } + +/// Get the number of syllabes in the line. +#[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn ASSLineGetSyllabesCount(this: *const ASSLine) -> i32 { (*this).0.content.len() as i32 } + +/// Get a line by its number in the container. +#[no_mangle] +pub unsafe extern "C" fn ASSContainerGetLineAt(this: *mut ASSContainer, idx: i32) -> *mut ASSLine { + let line = (*this).0.lines.get_mut(idx as usize).map(|l| l as *mut _ as *mut _); + line.unwrap_or_else(|| { + log::error!("failed to get line n°{idx}"); + core::ptr::null_mut() + }) +} + +/// Get a syllabe in a line by its index. +#[no_mangle] +pub unsafe extern "C" fn ASSLineGetSyllabeAt(this: *mut ASSLine, idx: i32) -> *mut ASSSyllabe { + let syl = (*this).0.content.get_mut(idx as usize).map(|s| s as *mut _ as *mut _); + syl.unwrap_or_else(|| { + log::error!("failed to get syllabe n°{idx}"); + core::ptr::null_mut() + }) +} + +/// Tells whever a line is commented or not. +#[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn ASSLineIsCommented(this: *const ASSLine) -> bool { (*this).0.is_comment } + +/// Gets the style of the line, or 'Default' if it was not found/specified. +#[no_mangle] +pub unsafe extern "C" fn ASSLineGetStyle<'a>(this: *const ASSLine) -> StringSlice<'a> { + match (*this).0.aux.0.get("style") { + Some(str) => StringSlice::from(str), + _ => StringSlice::from("Default"), + } +} + +/// Get the content of a syllabe. +#[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn ASSSyllabeGetContent<'a>(this: *const ASSSyllabe) -> StringSlice<'a> { StringSlice::from(&(*this).0.content) } + +/// Get the duration of a syllabe. +#[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn ASSSyllabeGetDuration(this: *const ASSSyllabe) -> i32 { (*this).0.fini.saturating_sub((*this).0.start) } + +/// Get the start of a syllabe. +#[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn ASSSyllabeGetStartTime(this: *const ASSSyllabe) -> i32 { (*this).0.start } + +/// Get the end time of a syllabe. +#[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn ASSSyllabeGetFiniTime(this: *const ASSSyllabe) -> i32 { (*this).0.fini } + +/// Set the duration of a syllabe. +#[no_mangle] +pub unsafe extern "C" fn ASSSyllabeSetDuration(this: *mut ASSSyllabe, duration: i32) { + (*this).0.fini = (*this).0.start.saturating_add(duration); +} + +/// Set the start of a syllabe. +#[no_mangle] +pub unsafe extern "C" fn ASSSyllabeSetStartTime(this: *mut ASSSyllabe, time: i32) { + (*this).0.start = time; + (*this).0.fini = (*this).0.fini.max(time); +} + +/// Set the end of a syllabe. +#[no_mangle] +pub unsafe extern "C" fn ASSSyllabeSetFiniTime(this: *mut ASSSyllabe, time: i32) { + (*this).0.fini = time; + (*this).0.start = (*this).0.fini.min(time); +} + +/// Load the ASS from a file, returns nullptr if an error was encountred. +#[no_mangle] +pub unsafe extern "C" fn ASSContainerFromFile(path: NonNull<c_char>) -> *mut ASSContainer { + let container = CStr::from_ptr(path.as_ptr() as *const _).to_str().map(|path| { + ass_container_from_file(path) + .map(|ass: vvs_ass::ASSContainer<AuxTable>| Box::into_raw(Box::new(ass)) as *mut ASSContainer) + .map_err(|err| log::error!("failed to load file: {err}")) + }); + match container.inspect_err(|err| log::error!("invalid utf8 filename: {err}")) { + Ok(Ok(container)) => container, + _ => ptr::null_mut(), + } +} + +/// Get a style out of the container by its name. +#[no_mangle] +pub unsafe extern "C" fn ASSContainerGetStyleByName(this: *mut ASSContainer, name: StringSlice) -> *mut ASSStyle { + let style = (*this).0.styles.get_mut(name.as_str()).map(|s| s as *mut _); + style.unwrap_or_else(|| { + log::error!("no sytle `{}` in ass container", name.as_str()); + core::ptr::null_mut() + }) +} + +/// Get the name of a style by its position. +#[no_mangle] +pub unsafe extern "C" fn ASSContainerGetStyleNameAt<'a>(this: *const ASSContainer, idx: i32) -> StringSlice<'a> { + let mut keys: Vec<_> = (*this).0.styles.keys().collect(); + keys.sort(); + keys.get(idx as usize) + .map(StringSlice::from) + .unwrap_or_else(|| StringSlice::from("Default")) +} + +/// Get the number of styles in the container. +#[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn ASSContainerGetStylesCount(this: *const ASSContainer) -> i32 { (*this).0.styles.len() as i32 } + +/// Set the start time of the line. +#[no_mangle] +pub unsafe extern "C" fn ASSLineSetStartTime(this: *mut ASSLine, time: i32) { + (*this).0.start = time; + (*this).0.fini = (*this).0.fini.max(time); + for syl in &mut (*this).0.content { + syl.start = syl.start.max(time); + syl.fini = syl.fini.max(time); + } +} + +/// Set the end time of a line. +#[no_mangle] +pub unsafe extern "C" fn ASSLineSetFiniTime(this: *mut ASSLine, time: i32) { + (*this).0.fini = time; + (*this).0.start = (*this).0.start.min(time); + for syl in &mut (*this).0.content { + syl.start = syl.start.min(time); + syl.fini = syl.fini.min(time); + } +} + +/// Get the duration of a line. +#[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn ASSLineGetDuration(this: *const ASSLine) -> i32 { (*this).0.fini.saturating_sub((*this).0.start) } + +/// Set the duration of a line. +#[no_mangle] +pub unsafe extern "C" fn ASSLineSetDuration(this: *mut ASSLine, duration: i32) { + (*this).0.fini = (*this).0.start.saturating_add(duration); +} + +/// Get the start time of a line. +#[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn ASSLineGetStartTime(this: *const ASSLine) -> i32 { (*this).0.start } + +/// Get the end time of a line. +#[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn ASSLineGetFiniTime(this: *const ASSLine) -> i32 { (*this).0.fini } + +/// Drop the container. It is file to pass a null pointer to this function. +#[no_mangle] +pub unsafe extern "C" fn ASSContainerDrop(this: *mut ASSContainer) { + #[allow(dead_code)] + const ASSERT_STRUCT_SIZES: () = { + macro_rules! assert_sizes { + ($ty: ident) => { + assert!( + mem::size_of::<$ty>() == mem::size_of::<vvs_ass::$ty<AuxTable>>(), + concat!("invalid sizes for ", stringify!($ty), " wrapper") + ); + assert!( + mem::align_of::<$ty>() == mem::align_of::<vvs_ass::$ty<AuxTable>>(), + concat!("invalid alignements for ", stringify!($ty), " wrapper") + ); + }; + } + assert_sizes!(ASSContainer); + assert_sizes!(ASSLine); + assert_sizes!(ASSSyllabe); + }; + + if !this.is_null() { + drop(unsafe { Box::from_raw(this) }); + } +} diff --git a/src/Rust/vvs_lib/src/ass_style.rs b/src/Rust/vvs_lib/src/ass_style.rs new file mode 100644 index 0000000000000000000000000000000000000000..a67fbdbd471b836b45776db56b34beaa5379cdfa --- /dev/null +++ b/src/Rust/vvs_lib/src/ass_style.rs @@ -0,0 +1,13 @@ +//! Contains wrappers for the styles. + +use crate::StringSlice; +use vvs_ass::ASSStyle; + +/// Get the name of the style. +/// +/// # Safety +/// It is up to the user to ensure that the style is not dropped before the returned pointer. +#[no_mangle] +pub extern "C" fn ASSStyleGetName(this: &ASSStyle) -> StringSlice { + StringSlice::from(&this.name) +} diff --git a/src/Rust/vvs_lib/src/aux_table.rs b/src/Rust/vvs_lib/src/aux_table.rs new file mode 100644 index 0000000000000000000000000000000000000000..f5f853dcacfb9205460d5d8171a12aaba6e6b1cc --- /dev/null +++ b/src/Rust/vvs_lib/src/aux_table.rs @@ -0,0 +1,10 @@ +use alloc::string::String; + +#[derive(Debug, Clone, Default, PartialEq)] +pub struct AuxTable(pub(crate) hashbrown::HashMap<String, String>); + +impl vvs_ass::AuxTable for AuxTable { + fn deep_clone(&self) -> Self { + Self(self.0.clone()) + } +} diff --git a/src/Rust/vvs_lib/src/lib.rs b/src/Rust/vvs_lib/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..e1e35aa4bc624695f3d17915d22802110103e2e5 --- /dev/null +++ b/src/Rust/vvs_lib/src/lib.rs @@ -0,0 +1,49 @@ +//! Here we define the things that will be exported to C/C++ code. We use PascalCase as it is not +//! very common and getters must be of the form `{StructName}{Get,Set}{TheField}` and methods of +//! the form `{StructName}{FunctionName}`. For free functions we use `{TheCrate}{FunctionName}`. + +#![allow(non_snake_case)] +#![no_std] + +extern crate alloc; + +pub mod ass_elements; +pub mod ass_style; +mod aux_table; +pub mod vivy; + +use crate::aux_table::AuxTable; +use core::{ffi::c_char, marker, slice, str}; + +/// Represents a string slice, the user may not modify this slice, never! Note that the string is +/// not null terminated and may contains null bytes in it, use the len attribute to get the length +/// of this string and convert it to your linking. +/// +/// # Safety +/// Note that you must always put unicode inside a string slice! +#[repr(C)] +pub struct StringSlice<'a> { + len: usize, + str: *const c_char, + _data: marker::PhantomData<&'a c_char>, +} + +impl<'a> StringSlice<'a> { + /// # Safety + /// We expect the content of the string slice to be valid UTF6... + #[inline] + pub unsafe fn as_str(&self) -> &'a str { + str::from_utf8_unchecked(slice::from_raw_parts(self.str as *const _, self.len)) + } +} + +impl<'a, S> From<S> for StringSlice<'a> +where + S: AsRef<str>, +{ + #[inline] + fn from(value: S) -> Self { + let value = value.as_ref(); + StringSlice { len: value.len(), str: value.as_ptr() as *const _, _data: marker::PhantomData } + } +} diff --git a/src/Rust/vvs_lib/src/vivy.rs b/src/Rust/vvs_lib/src/vivy.rs new file mode 100644 index 0000000000000000000000000000000000000000..42301ab407e663fedfedd84b8beae06707891975 --- /dev/null +++ b/src/Rust/vvs_lib/src/vivy.rs @@ -0,0 +1,31 @@ +use alloc::string::String; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, PartialEq, Eq)] +pub enum VivyDocumentCapabilities { + AudioAble = (1 << 1), + VideoAble = (1 << 2), + AssAble = (1 << 3), +} + +#[derive(Debug, Deserialize, Serialize)] +#[serde(rename_all = "PascalCase")] +pub struct VivyDocument { + #[serde(default = "u64::default")] + pub capabilities: u64, + pub name: String, +} + +#[derive(Debug, Deserialize, Serialize)] +#[serde(rename_all = "PascalCase")] +#[serde(tag = "DocumentVersion", content = "SubDocuments")] +pub enum VivySubDocument { + Alpha { sub_ass: Option<String>, sub_audio: Option<String>, sub_video: Option<String> }, +} + +#[test] +fn test_deserialize() { + if let Err(err) = serde_json::from_str::<VivyDocument>(include_str!("../test/sample.vivy")) { + panic!("{err}") + } +} diff --git a/src/Rust/vvs_lib/test/sample.vivy b/src/Rust/vvs_lib/test/sample.vivy new file mode 100644 index 0000000000000000000000000000000000000000..16bd90a6d3d88e195f8cc8d76fd6672145dde2fb --- /dev/null +++ b/src/Rust/vvs_lib/test/sample.vivy @@ -0,0 +1,10 @@ +{ + "Name": "test", + "Capabilities": 12, + "DocumentVersion": "alpha", + "SubDocuments": { + "SubAss": "vivy/src/Rust/vvs_ass/utils/empty.ass", + "SubVideo": "data/4036f7f60c08bf70741f118eca95dff61facfb66199351e9e40900071cd5322d.mkv" + } +} + diff --git a/src/Rust/vvs_llvm/Cargo.toml b/src/Rust/vvs_llvm/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..98bd38c99bcee84a673907c0d280632c9c784205 --- /dev/null +++ b/src/Rust/vvs_llvm/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "vvs_llvm" +description = "Link against and re-export llvm things" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +anyhow.workspace = true +log.workspace = true +llvm-sys = { version = "181", features = [ + "strict-versioning", # Be strict about versions, we do want the lattest thing + "no-llvm-linking", # We do the linking ourself because of problems when using spack: https://github.com/spack/spack/discussions/36192 + "disable-alltargets-init", # Without linking we must rely on our own inits... +] } + +[features] +link = [] diff --git a/src/Rust/vvs_llvm/src/init.rs b/src/Rust/vvs_llvm/src/init.rs new file mode 100644 index 0000000000000000000000000000000000000000..dfff4b9a03a9461cbb29cf99485e5f46a0ff36ad --- /dev/null +++ b/src/Rust/vvs_llvm/src/init.rs @@ -0,0 +1,37 @@ +//! Initialize LLVM targets and such. This module only exports one function: +//! [self::initialize_llvm]. Depending on the target architecture we select +//! the correct function... + +use anyhow::anyhow; +use llvm_sys::target_machine::*; +use std::ffi::CStr; + +/// Be sure to init LLVM only once. We use an atomic usize because it is supported on all the +/// platforms! +fn call_once() -> bool { + use std::sync::atomic::{AtomicUsize, Ordering::*}; + static INIT_ONCE: AtomicUsize = AtomicUsize::new(0); + INIT_ONCE.compare_exchange(0, 1, SeqCst, SeqCst).is_ok() +} + +fn print_llvm_infos() { + let triple = unsafe { CStr::from_ptr(LLVMGetDefaultTargetTriple()) }.to_string_lossy(); + let cpu = unsafe { CStr::from_ptr(LLVMGetHostCPUName()) }.to_string_lossy(); + let cpu_features = unsafe { CStr::from_ptr(LLVMGetHostCPUFeatures()) }.to_string_lossy(); + + log::debug!("got default triple: `{triple}`"); + log::debug!("got cpu `{cpu}` with features: {cpu_features}"); +} + +#[cfg(target_arch = "x86_64")] +pub fn initialize_llvm() -> anyhow::Result<()> { + call_once() + .then(|| unsafe { + llvm_sys::target::LLVMInitializeX86Target(); + print_llvm_infos(); + }) + .ok_or_else(|| anyhow!("llvm was already initialized for this executable!")) +} + +#[cfg(not(target_arch = "x86_64"))] +compile_error!("this target is not supported for now"); diff --git a/src/Rust/vvs_llvm/src/iter.rs b/src/Rust/vvs_llvm/src/iter.rs new file mode 100644 index 0000000000000000000000000000000000000000..e1fae55f415325ca0488b9da15215ebca8095240 --- /dev/null +++ b/src/Rust/vvs_llvm/src/iter.rs @@ -0,0 +1,102 @@ +//! Utility functions and structures to iterate over an LLVM function and in the basic blocks. + +use crate::*; +use std::ptr; + +/// Iterate over the basic blocks in a function. +#[derive(Clone, Copy)] +pub struct LLVMFunctionIter { + curr_bb: LLVMBasicBlockRef, + last_bb: LLVMBasicBlockRef, + function: LLVMValueRef, + index: u32, +} + +#[derive(Clone, Copy)] +pub struct LLVMBasicBlockIter { + curr_instr: LLVMValueRef, + last_instr: LLVMValueRef, +} + +impl Iterator for LLVMFunctionIter { + type Item = LLVMBasicBlockRef; + + fn next(&mut self) -> Option<Self::Item> { + (!self.curr_bb.is_null() && !self.last_bb.is_null()) + .then(|| match unsafe { LLVMGetNextBasicBlock(self.curr_bb) } { + ret if ret.is_null() => None, + ret => { + self.curr_bb = if ret == self.last_bb { ptr::null_mut() } else { ret }; + self.index += 1; + Some(ret) + } + }) + .flatten() + } + + fn last(self) -> Option<Self::Item> { + (!self.last_bb.is_null()).then_some(self.last_bb) + } + + fn count(self) -> usize { + unsafe { LLVMFunctionIter::count_bbs(&self) } + } + + fn size_hint(&self) -> (usize, Option<usize>) { + let count = unsafe { LLVMFunctionIter::count_bbs(self) }; + (count, Some(count)) + } +} + +impl Iterator for LLVMBasicBlockIter { + type Item = LLVMValueRef; + + fn next(&mut self) -> Option<Self::Item> { + (!self.curr_instr.is_null() && !self.last_instr.is_null()) + .then(|| match unsafe { LLVMGetNextInstruction(self.curr_instr) } { + ret if ret.is_null() => None, + ret => { + self.curr_instr = if ret == self.last_instr { ptr::null_mut() } else { ret }; + Some(ret) + } + }) + .flatten() + } + + fn last(self) -> Option<Self::Item> { + (!self.last_instr.is_null()).then_some(self.last_instr) + } +} + +impl LLVMFunctionIter { + /// Create a new iterator over a function. If the passed value is not a function this + /// constructor will panic. + /// + /// # Safety + /// The passed value must be a valid pointer to [LLVMValue]. You may not create new basic + /// blocks while using this iterator. + pub unsafe fn new(function: LLVMValueRef) -> Self { + assert!(!LLVMIsAFunction(function).is_null(), "should pass functions..."); + Self { + curr_bb: LLVMGetFirstBasicBlock(function), + last_bb: LLVMGetLastBasicBlock(function), + index: 0, + function, + } + } + + unsafe fn count_bbs(&self) -> usize { + unsafe { LLVMCountBasicBlocks(self.function) }.saturating_sub(self.index) as usize + } +} + +impl LLVMBasicBlockIter { + /// Create a new iterator over a basic block. + /// + /// # Safety + /// The passed value must be a valid pointer to [LLVMBasicBlock]. You may not insert new values + /// into the block while using this iterator. + pub unsafe fn new(bb: LLVMBasicBlockRef) -> Self { + Self { curr_instr: LLVMGetFirstInstruction(bb), last_instr: LLVMGetBasicBlockTerminator(bb) } + } +} diff --git a/src/Rust/vvs_llvm/src/lib.rs b/src/Rust/vvs_llvm/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..92320adaf6ae9aba688c554f40bce030471f7220 --- /dev/null +++ b/src/Rust/vvs_llvm/src/lib.rs @@ -0,0 +1,80 @@ +//! Re-exports LLVM stuff + +#[cfg(feature = "link")] +pub mod build { + //! Utility functions to link against LLVM without relying to [llvm-sys]. The function + //! [llvm_link] should be run from the build.rs script of any executable or library depending + //! on [vvs_llvm]. + + use anyhow::{anyhow, bail, Context}; + use std::process::{Command, Output}; + + /// Run a command with said arguments and returns the stdout of said command. + fn run<const N: usize>(cmd: &'static str, args: [&'static str; N]) -> anyhow::Result<Vec<u8>> { + match Command::new(cmd).args(args).output()? { + Output { status, stdout, .. } if status.success() => Ok(stdout), + Output { stderr, .. } => Err(anyhow!( + "failed to run `{cmd}`: {}", + std::str::from_utf8(&stderr).with_context(|| format!("`{cmd}` failed with non-utf8 stderr"))? + )), + } + } + + /// Prints info for cargo to link against LLVM libraries + pub fn llvm_link() -> anyhow::Result<()> { + let libdir = std::str::from_utf8(&run("llvm-config", ["--libdir"])?) + .with_context(|| "`llvm-config --libdir` failed with non-utf8 stdout")? + .trim() + .to_string(); + println!("cargo:rustc-link-search={libdir}"); + + let ty = match std::str::from_utf8(&run("llvm-config", ["--shared-mode"])?)?.trim() { + // In dynamic mode, we may need to do something about the rpath... + "shared" => { + println!("cargo:rustc-link-arg=-Wl,-rpath={libdir}"); // rpath for executable + println!("cargo:rustc-env=LD_LIBRARY_PATH={libdir}"); // for tests + "dylib" + } + + // Static mode, just include all the .a files. We also need some system libs... + "static" => { + println!("cargo:rustc-link-arg=-lstdc++"); + std::str::from_utf8(&run("llvm-config", ["--system-libs"])?)? + .trim() + .split_ascii_whitespace() + .for_each(|lib| println!("cargo:rustc-link-arg={lib}")); + "static" + } + + // Err... + out => bail!("invalid returned value `{out}`"), + }; + + std::str::from_utf8(&run("llvm-config", ["--libs"])?)? + .trim() + .split_ascii_whitespace() + .flat_map(|name| name.strip_prefix("-l")) + .for_each(|name| println!("cargo:rustc-link-lib={ty}={name}")); + + println!("cargo:rerun-if-changed=build.rs"); + Ok(()) + } +} + +pub use llvm_sys::{ + analysis::*, + core::*, + error::*, + orc2::{ee::*, lljit::*, *}, + prelude::*, + target::*, + target_machine::*, + transforms::pass_builder::*, + *, +}; + +mod init; +mod iter; + +pub use init::*; +pub use iter::*; diff --git a/src/Rust/vvs_parser/Cargo.toml b/src/Rust/vvs_parser/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..f078adec87c6ec936c8723629e414aec5581d653 --- /dev/null +++ b/src/Rust/vvs_parser/Cargo.toml @@ -0,0 +1,39 @@ +[package] +name = "vvs_parser" +license = "MPL-2.0" +description = "A lossless Lua parser hacked to parse VVS" + +version.workspace = true +authors.workspace = true +edition.workspace = true + + +[dependencies] +vvs_parser_derive.workspace = true + +bytecount.workspace = true +cfg-if.workspace = true +derive_more.workspace = true +paste.workspace = true +serde.workspace = true +smol_str.workspace = true +hashbrown.workspace = true +anyhow.workspace = true +log.workspace = true +codespan.workspace = true +codespan-reporting.workspace = true +termcolor.workspace = true + +[dev-dependencies] +criterion.workspace = true +insta.workspace = true + +[[bench]] +name = "date" +path = "../benches/date.rs" +harness = false + +[[bench]] +name = "t" +path = "../benches/t.rs" +harness = false diff --git a/src/Rust/vvs_parser/LICENSE.md b/src/Rust/vvs_parser/LICENSE.md new file mode 100644 index 0000000000000000000000000000000000000000..2b8bbd4546a3f2c86fb661e735422cda8d896427 --- /dev/null +++ b/src/Rust/vvs_parser/LICENSE.md @@ -0,0 +1,347 @@ +Mozilla Public License Version 2.0 +================================== + +### 1. Definitions + +**1.1. “Contributorâ€** + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +**1.2. “Contributor Versionâ€** + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +**1.3. “Contributionâ€** + means Covered Software of a particular Contributor. + +**1.4. “Covered Softwareâ€** + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +**1.5. “Incompatible With Secondary Licensesâ€** + means + +* **(a)** that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or +* **(b)** that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +**1.6. “Executable Formâ€** + means any form of the work other than Source Code Form. + +**1.7. “Larger Workâ€** + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +**1.8. “Licenseâ€** + means this document. + +**1.9. “Licensableâ€** + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +**1.10. “Modificationsâ€** + means any of the following: + +* **(a)** any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or +* **(b)** any new file in Source Code Form that contains any Covered + Software. + +**1.11. “Patent Claims†of a Contributor** + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +**1.12. “Secondary Licenseâ€** + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +**1.13. “Source Code Formâ€** + means the form of the work preferred for making modifications. + +**1.14. “You†(or “Yourâ€)** + means an individual or a legal entity exercising rights under this + License. For legal entities, “You†includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, “control†means **(a)** the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or **(b)** ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +### 2. License Grants and Conditions + +#### 2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +* **(a)** under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and +* **(b)** under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +#### 2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +#### 2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +* **(a)** for any code that a Contributor has removed from Covered Software; + or +* **(b)** for infringements caused by: **(i)** Your and any other third party's + modifications of Covered Software, or **(ii)** the combination of its + Contributions with other software (except as part of its Contributor + Version); or +* **(c)** under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +#### 2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +#### 2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +#### 2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +#### 2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +### 3. Responsibilities + +#### 3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +#### 3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +* **(a)** such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +* **(b)** You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +#### 3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +#### 3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +#### 3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +### 4. Inability to Comply Due to Statute or Regulation + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: **(a)** comply with +the terms of this License to the maximum extent possible; and **(b)** +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +### 5. Termination + +**5.1.** The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated **(a)** provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and **(b)** on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +**5.2.** If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +**5.3.** In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +### 6. Disclaimer of Warranty + +> Covered Software is provided under this License on an “as is†+> basis, without warranty of any kind, either expressed, implied, or +> statutory, including, without limitation, warranties that the +> Covered Software is free of defects, merchantable, fit for a +> particular purpose or non-infringing. The entire risk as to the +> quality and performance of the Covered Software is with You. +> Should any Covered Software prove defective in any respect, You +> (not any Contributor) assume the cost of any necessary servicing, +> repair, or correction. This disclaimer of warranty constitutes an +> essential part of this License. No use of any Covered Software is +> authorized under this License except under this disclaimer. + +### 7. Limitation of Liability + +> Under no circumstances and under no legal theory, whether tort +> (including negligence), contract, or otherwise, shall any +> Contributor, or anyone who distributes Covered Software as +> permitted above, be liable to You for any direct, indirect, +> special, incidental, or consequential damages of any character +> including, without limitation, damages for lost profits, loss of +> goodwill, work stoppage, computer failure or malfunction, or any +> and all other commercial damages or losses, even if such party +> shall have been informed of the possibility of such damages. This +> limitation of liability shall not apply to liability for death or +> personal injury resulting from such party's negligence to the +> extent applicable law prohibits such limitation. Some +> jurisdictions do not allow the exclusion or limitation of +> incidental or consequential damages, so this exclusion and +> limitation may not apply to You. + +### 8. Litigation + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +### 9. Miscellaneous + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +### 10. Versions of the License + +#### 10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +#### 10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +#### 10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +#### 10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +## Exhibit A - Source Code Form License Notice + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +## Exhibit B - “Incompatible With Secondary Licenses†Notice + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/src/Rust/vvs_parser/README.md b/src/Rust/vvs_parser/README.md new file mode 100644 index 0000000000000000000000000000000000000000..1bc8ed395a96bb7c11a4c80de3f4beb200107ed6 --- /dev/null +++ b/src/Rust/vvs_parser/README.md @@ -0,0 +1,10 @@ +A lossless Lua 5.1 / 5.2 / 5.3 / 5.4 / [Luau](https://luau-lang.org/) parser written in Rust. + +Full Moon preserves comments, whitespace, style choices, etc. With Full Moon, you're able to convert +your Lua code into an AST and a syntax tree and convert it back to the original code exactly. + +Using Full Moon, you'll be able to modify the AST directly and re-export it back to Lua, all while +preserving the style in which you write. + +Full Moon is heavily inspired by [LPGhatguy's mab](https://github.com/LPGhatguy/mab/) and by the +possibilities brought on by [benjamn's recast](https://github.com/benjamn/recast). diff --git a/src/Rust/vvs_parser/samples/options.ini b/src/Rust/vvs_parser/samples/options.ini new file mode 100644 index 0000000000000000000000000000000000000000..ef6a2af767f4537555f798537090e17b873112dd --- /dev/null +++ b/src/Rust/vvs_parser/samples/options.ini @@ -0,0 +1,8 @@ +[retime] +before = 900 +after = 400 + +[outline] +-- Let's say we have an outline module... +border = 4 +color = color { "rgb", 0, 0, 0 } diff --git a/src/Rust/vvs_parser/samples/retime.vvs b/src/Rust/vvs_parser/samples/retime.vvs new file mode 100644 index 0000000000000000000000000000000000000000..94e930203035803f7960b63c5f6d1dfbab361704 --- /dev/null +++ b/src/Rust/vvs_parser/samples/retime.vvs @@ -0,0 +1,29 @@ +---[[ Contains utilities to retime lines from an ASS file. ]] + + +option before : number = 900 --- Retime time in millisecond for the aparition of the line. +option after : number = 300 --- Retime time in millisecond for the disaparition of the line. + + +-- We want to permit assertions to check for options, etc. They will be run before the main is +-- executed, when all the configuration is loaded. +assert(before >= 0, "offset should be positive") +assert(after >= 0, "offset should be positive") + + +--- Here we set the begin of the syllabes at the begin of the line, each +--- syllabes will end when it should in fact begin. +job start(l: line): line + for i,s in l do + s.begin = l.start - self.before + end +end + + +--- Here we set the end of the syllabes at the end of the line, each +--- syllabes will begin when it should in fact end. +job finish(l: line): line + for i,s in l do + s.finish = l.finish - self.after + end +end diff --git a/src/Rust/vvs_parser/samples/tag.vvs b/src/Rust/vvs_parser/samples/tag.vvs new file mode 100644 index 0000000000000000000000000000000000000000..cf625d30110c8dd22556f43c9d50231127317b17 --- /dev/null +++ b/src/Rust/vvs_parser/samples/tag.vvs @@ -0,0 +1,21 @@ +---[[ Contains utilities to tag some lines/syllages to filter sets of elements. ]] + + +--- Returns only syllabes with the specified displacement. +job syl_modulo(every: number, disp: number, l: line): line + for i,s in l do + if (i % every) == disp then + yield s + end + end +end + + +--- Returns only lines with the specified displacement. +job line_modulo(every: number, ls: lines): line -- Note that jobs may only returns `line` or `syllabe` + for i,l in ls do + if (i % every) == disp then + yield l + end + end +end diff --git a/src/Rust/vvs_parser/samples/test.vvs b/src/Rust/vvs_parser/samples/test.vvs new file mode 100644 index 0000000000000000000000000000000000000000..1b482111e7836bdbf498e7e4e4bdf76e966a2f96 --- /dev/null +++ b/src/Rust/vvs_parser/samples/test.vvs @@ -0,0 +1,20 @@ +import "utils" +import { "retime", "tag" } + + +-- Set some options. +retime.before = 900 +retime.after = 400 +outline.border = 4 +outline.color = color "rgb" { 10, 10, 10 } + + +-- What we want to do for this script, and how we name the initial value. +main "INIT" do + "BEFORE" = retime.start { "INIT" } + "AFTER" = retime.finish { "INIT" } + "OUTLINED" = utils.outline { "BEFORE", "INIT", "AFTER" } + "TAGGED" = tag.syl_modulo { every = 3, disp = 1, "OUTLINED" } -- Here we tag some objects... + + return "OUTLINED" -- What we want to write in the file, in order. +end diff --git a/src/Rust/vvs_parser/src/ast/mod.rs b/src/Rust/vvs_parser/src/ast/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..5ccfe1e9c22f2e7d8cf108395af195eee7d04b8a --- /dev/null +++ b/src/Rust/vvs_parser/src/ast/mod.rs @@ -0,0 +1,3117 @@ +//! Utilities for ASTs (Abstract Syntax Trees). + +use crate::{ + ast::parsers::ParserState, + node::Node, + tokenizer::{Position, Symbol, Token, TokenReference, TokenType}, + util::*, + ShortString, +}; +use crate::{traits::DefaultRef, util::display_option}; +use derive_more::{Deref, Display, IsVariant}; +use serde::{Deserialize, Serialize}; +use std::{borrow::Cow, fmt}; +use vvs_parser_derive::{Node, Visit}; + +pub use crate::ast::{punctuated::*, span::*}; + +pub(crate) use crate::ast::{ + options::OptionTable, + parsers::{AstResult, OptionTableResult}, +}; + +mod options; +mod parsers; +mod punctuated; +mod span; +mod update_positions; +mod visitors; + +/// A block of statements, such as in if/do/etc block +#[derive(Clone, Debug, Default, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[display("{}{}", + display_optional_punctuated_vec(stmts), + display_option(last_stmt.as_ref().map(display_optional_punctuated)) +)] +pub struct Block { + stmts: Vec<(Stmt, Option<TokenReference>)>, + + #[serde(skip_serializing_if = "Option::is_none")] + last_stmt: Option<(LastStmt, Option<TokenReference>)>, +} + +impl Block { + /// Creates an empty block + pub fn new() -> Self { + Default::default() + } + + /// An iterator over the statements in the block, such as `local foo = 1`. + /// + /// Note that this does not contain the final statement which can be + /// attained via [`Block::last_stmt`]. + pub fn stmts(&self) -> impl Iterator<Item = &Stmt> { + self.stmts.iter().map(|(stmt, _)| stmt) + } + + /// An iterator over the mutable statements in the block, such as `local foo = 1`. + /// + /// Note that this does not contain the final statement which can be + /// attained via [`Block::last_stmt`]. + #[allow(dead_code)] + pub(crate) fn stmts_mut(&mut self) -> impl Iterator<Item = &mut Stmt> { + self.stmts.iter_mut().map(|(stmt, _)| stmt) + } + + /// An iterator over the statements in the block, including any optional + /// semicolon token reference present + pub fn stmts_with_semicolon(&self) -> impl Iterator<Item = &(Stmt, Option<TokenReference>)> { + self.stmts.iter() + } + + /// The last statement of the block if one exists, such as `return foo` + pub fn last_stmt(&self) -> Option<&LastStmt> { + Some(&self.last_stmt.as_ref()?.0) + } + + /// The mutable last statement of the block if one exists, such as `return foo` + pub fn last_stmt_mut(&mut self) -> Option<&mut LastStmt> { + Some(&mut self.last_stmt.as_mut()?.0) + } + + /// The last statement of the block if on exists, including any optional semicolon token reference present + pub fn last_stmt_with_semicolon(&self) -> Option<&(LastStmt, Option<TokenReference>)> { + self.last_stmt.as_ref() + } + + /// Returns a new block with the given statements + /// Takes a vector of statements, followed by an optional semicolon token reference + pub fn with_stmts(self, stmts: Vec<(Stmt, Option<TokenReference>)>) -> Self { + Self { stmts, ..self } + } + + /// Returns a new block with the given last statement, if one is given + /// Takes an optional last statement, with an optional semicolon + pub fn with_last_stmt(self, last_stmt: Option<(LastStmt, Option<TokenReference>)>) -> Self { + Self { last_stmt, ..self } + } + + pub(crate) fn merge_blocks(&mut self, other: Self) { + self.stmts.extend(other.stmts); + self.last_stmt = other.last_stmt; + } +} + +/// The last statement of a [`Block`] +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[non_exhaustive] +pub enum LastStmt { + /// A `break` statement + Break(TokenReference), + + /// A continue statement + Continue(TokenReference), + + /// A `return` statement + Return(Return), +} + +/// A `return` statement +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[display("{token}{returns}")] +pub struct Return { + token: TokenReference, + returns: Punctuated<Expression>, +} + +impl Return { + /// Creates a new empty Return + /// Default return token is followed by a single space + pub fn new() -> Self { + Self { token: TokenReference::basic_symbol("return "), returns: Punctuated::new() } + } + + /// The `return` token + pub fn token(&self) -> &TokenReference { + &self.token + } + + /// The values being returned + pub fn returns(&self) -> &Punctuated<Expression> { + &self.returns + } + + /// Returns a new Return with the given `return` token + pub fn with_token(self, token: TokenReference) -> Self { + Self { token, ..self } + } + + /// Returns a new Return with the given punctuated sequence + pub fn with_returns(self, returns: Punctuated<Expression>) -> Self { + Self { returns, ..self } + } +} + +impl Default for Return { + fn default() -> Self { + Self::new() + } +} + +/// Fields of a [`TableConstructor`] +#[derive(Clone, Debug, Display, PartialEq, Node, Deserialize, Serialize)] +#[non_exhaustive] +pub enum Field { + /// A key in the format of `[expression] = value` + #[display("{}{key}{}{equal}{value}", brackets.tokens().0, brackets.tokens().1)] + ExpressionKey { + /// The `[...]` part of `[expression] = value` + brackets: ContainedSpan, + /// The `expression` part of `[expression] = value` + key: Expression, + /// The `=` part of `[expression] = value` + equal: TokenReference, + /// The `value` part of `[expression] = value` + value: Expression, + }, + + /// A key in the format of `name = value` + #[display("{key}{equal}{value}")] + NameKey { + /// The `name` part of `name = value` + key: TokenReference, + /// The `=` part of `name = value` + equal: TokenReference, + /// The `value` part of `name = value` + value: Expression, + }, + + /// A field with no key, just a value (such as `"a"` in `{ "a" }`) + #[display("{_0}")] + NoKey(Expression), +} + +/// A table being constructed, such as `{ 1, 2, 3 }` or `{ a = 1 }` +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[display("{}{fields}{}", braces.tokens().0, braces.tokens().1)] +pub struct TableConstructor { + #[node(full_range)] + #[visit(contains = "fields")] + braces: ContainedSpan, + fields: Punctuated<Field>, +} + +impl TableConstructor { + /// Creates a new empty TableConstructor + /// Brace tokens are followed by spaces, such that { `fields` } + pub fn new() -> Self { + Self { + braces: ContainedSpan::new(TokenReference::basic_symbol("{ "), TokenReference::basic_symbol(" }")), + fields: Punctuated::new(), + } + } + + /// The braces of the constructor + pub fn braces(&self) -> &ContainedSpan { + &self.braces + } + + /// Returns the [`Punctuated`] sequence of the fields used to create the table + pub fn fields(&self) -> &Punctuated<Field> { + &self.fields + } + + /// Get the number of fields in the table construct + pub fn fields_len(&self) -> usize { + self.fields().len() + } + + /// Returns a new TableConstructor with the given braces + pub fn with_braces(self, braces: ContainedSpan) -> Self { + Self { braces, ..self } + } + + /// Returns a new TableConstructor with the given fields + pub fn with_fields(self, fields: Punctuated<Field>) -> Self { + Self { fields, ..self } + } +} + +impl Default for TableConstructor { + fn default() -> Self { + Self::new() + } +} + +/// An expression, mostly useful for getting values +#[derive(Clone, Debug, Display, PartialEq, Node, Deserialize, Serialize)] +#[non_exhaustive] +pub enum Expression { + /// A binary operation, such as `1 + 3` + #[display("{lhs}{binop}{rhs}")] + BinaryOperator { + /// The left hand side of the binary operation, the `1` part of `1 + 3` + lhs: Box<Expression>, + /// The binary operation used, the `+` part of `1 + 3` + binop: BinOp, + /// The right hand side of the binary operation, the `3` part of `1 + 3` + rhs: Box<Expression>, + }, + + /// A statement in parentheses, such as `(#list)` + #[display("{}{expression}{}", contained.tokens().0, contained.tokens().1)] + Parentheses { + /// The parentheses of the expression + #[node(full_range)] + contained: ContainedSpan, + /// The expression inside the parentheses + expression: Box<Expression>, + }, + + /// A unary operation, such as `#list` + #[display("{unop}{expression}")] + UnaryOperator { + /// The unary operation, the `#` part of `#list` + unop: UnOp, + /// The expression the operation is being done on, the `list` part of `#list` + expression: Box<Expression>, + }, + + /// An anonymous function, such as `function() end)` + #[display("{}{}", _0.0, _0.1)] + Function(Box<(TokenReference, FunctionBody)>), + + /// A call of a function, such as `call()` + #[display("{_0}")] + FunctionCall(FunctionCall), + + /// An if expression, such as `if foo then true else false`. + #[display("{_0}")] + IfExpression(IfExpression), + + /// A table constructor, such as `{ 1, 2, 3 }` + #[display("{_0}")] + TableConstructor(TableConstructor), + + /// A number token, such as `3.3` + #[display("{_0}")] + Number(TokenReference), + + /// A string token, such as `"hello"` + #[display("{_0}")] + String(TokenReference), + + /// A symbol, such as `true` + #[display("{_0}")] + Symbol(TokenReference), + + /// A value that has been asserted for a particular type, for use in Luau. + #[display("{expression}{type_assertion}")] + TypeAssertion { + /// The expression being asserted + expression: Box<Expression>, + + /// The type assertion + type_assertion: TypeAssertion, + }, + + /// A more complex value, such as `call().x` + #[display("{_0}")] + Var(Var), +} + +/// A statement that stands alone +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[non_exhaustive] +pub enum Stmt { + /// An assignment, such as `x = 1` + #[display("{_0}")] + Assignment(Assignment), + + /// A do block, `do end` + #[display("{_0}")] + Do(Do), + + /// A function call on its own, such as `call()` + #[display("{_0}")] + FunctionCall(FunctionCall), + + /// A function declaration, such as `function x() end` + #[display("{_0}")] + FunctionDeclaration(FunctionDeclaration), + + /// A job declaration, such as `job x(l: lines): lines return l end` + #[display("{_0}")] + JobDeclaration(FunctionDeclaration), + + /// A generic for loop, such as `for index, value in pairs(list) do end` + #[display("{_0}")] + GenericFor(GenericFor), + + /// An if statement + #[display("{_0}")] + If(If), + + /// A local assignment, such as `local x = 1` + #[display("{_0}")] + LocalAssignment(LocalAssignment), + + /// A local function declaration, such as `local function x() end` + #[display("{_0}")] + LocalFunction(LocalFunction), + + /// An import statement, such as `import "math"` + #[display("{_0}")] + Import(Import), + + /// A numeric for loop, such as `for index = 1, 10 do end` + #[display("{_0}")] + NumericFor(NumericFor), + + /// A repeat loop + #[display("{_0}")] + Repeat(Repeat), + + /// A while loop + #[display("{_0}")] + While(While), + + /// The `option` directive, to declare an option + #[display("{_0}")] + OptionDecl(OptionDecl), + + /// The `write` directive, to write variables to the final file. + /// + /// Can be used like `write "init"` or `write { "init", "last", "etc" }` + #[display("{_0}")] + Write(Write), + + /// The `main` directive. See [Main] for more informations. + #[display("{_0}")] + Main(Main), + + /// The `yield` statement for jobs to be able to build automatically things in a job + #[display("{_0}")] + Yield(Yield), + + /// A compound assignment, such as `+=` + #[display("{_0}")] + CompoundAssignment(CompoundAssignment), + + /// A type declaration, such as `type Meters = number` + TypeDeclaration(TypeDeclaration), +} + +/// A `yield` statement +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[display("{token}{yielded}")] +pub struct Yield { + token: TokenReference, + yielded: Punctuated<Expression>, +} + +impl Yield { + /// Creates a new empty Yield + /// Default yield token is followed by a single space + pub fn new() -> Self { + Self { token: TokenReference::basic_symbol("yield "), yielded: Punctuated::new() } + } + + /// The `yield` token + pub fn token(&self) -> &TokenReference { + &self.token + } + + /// The values being returned + pub fn yields(&self) -> &Punctuated<Expression> { + &self.yielded + } + + /// Returns a new Return with the given `yield` token + pub fn with_token(self, token: TokenReference) -> Self { + Self { token, ..self } + } + + /// Returns a new Yield with the given punctuated sequence + pub fn with_yields(self, yielded: Punctuated<Expression>) -> Self { + Self { yielded, ..self } + } +} + +impl Default for Yield { + fn default() -> Self { + Self::new() + } +} + +/// A node used before another in cases such as function calling +/// The `("foo")` part of `("foo"):upper()` +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[non_exhaustive] +pub enum Prefix { + #[display("{_0}")] + /// A complicated expression, such as `("foo")` + Expression(Box<Expression>), + + #[display("{_0}")] + /// Just a name, such as `foo` + Name(TokenReference), +} + +/// The indexing of something, such as `x.y` or `x["y"]` +/// Values of variants are the keys, such as `"y"` +#[derive(Clone, Debug, Display, PartialEq, Node, Deserialize, Serialize)] +#[non_exhaustive] +pub enum Index { + /// Indexing in the form of `x["y"]` + #[display("{}{expression}{}", brackets.tokens().0, brackets.tokens().1)] + Brackets { + /// The `[...]` part of `["y"]` + brackets: ContainedSpan, + /// The `"y"` part of `["y"]` + expression: Expression, + }, + + /// Indexing in the form of `x.y` + #[display("{dot}{name}")] + Dot { + /// The `.` part of `.y` + dot: TokenReference, + /// The `y` part of `.y` + name: TokenReference, + }, +} + +/// Arguments used for a function +#[derive(Clone, Debug, Display, PartialEq, Node, Deserialize, Serialize)] +#[non_exhaustive] +pub enum FunctionArgs { + /// Used when a function is called in the form of `call(1, 2, 3)` + #[display("{}{arguments}{}", parentheses.tokens().0, parentheses.tokens().1)] + Parentheses { + /// The `(...) part of (1, 2, 3)` + #[node(full_range)] + parentheses: ContainedSpan, + /// The `1, 2, 3` part of `1, 2, 3` + arguments: Punctuated<Expression>, + }, + /// Used when a function is called in the form of `call "foobar"` + #[display("{_0}")] + String(TokenReference), + /// Used when a function is called in the form of `call { 1, 2, 3 }` + #[display("{_0}")] + TableConstructor(TableConstructor), +} + +impl FunctionArgs { + pub(crate) fn empty() -> Self { + FunctionArgs::Parentheses { + parentheses: ContainedSpan::new(TokenReference::basic_symbol("("), TokenReference::basic_symbol(")")), + + arguments: Punctuated::new(), + } + } +} + +/// A numeric for loop, such as `for index = 1, 10 do end` +#[derive(Clone, Debug, PartialEq, Display, Node, Deserialize, Serialize)] +#[display("{for_token}{index_variable}{}{equal_token}{start}{start_end_comma}{end}{}{}{do_token}{block}{end_token}", + display_option(self.type_specifier()), + display_option(self.end_step_comma()), + display_option(self.step()), +)] +pub struct NumericFor { + for_token: TokenReference, + index_variable: TokenReference, + equal_token: TokenReference, + start: Expression, + start_end_comma: TokenReference, + end: Expression, + end_step_comma: Option<TokenReference>, + step: Option<Expression>, + do_token: TokenReference, + block: Block, + end_token: TokenReference, + #[serde(skip_serializing_if = "Option::is_none")] + type_specifier: Option<TypeSpecifier>, +} + +impl NumericFor { + /// Creates a new NumericFor from the given index variable, start, and end expressions + pub fn new(index_variable: TokenReference, start: Expression, end: Expression) -> Self { + Self { + for_token: TokenReference::basic_symbol("for "), + index_variable, + equal_token: TokenReference::basic_symbol(" = "), + start, + start_end_comma: TokenReference::basic_symbol(", "), + end, + end_step_comma: None, + step: None, + do_token: TokenReference::basic_symbol(" do\n"), + block: Block::new(), + end_token: TokenReference::basic_symbol("\nend"), + type_specifier: None, + } + } + + /// The `for` token + pub fn for_token(&self) -> &TokenReference { + &self.for_token + } + + /// The index identity, `index` in the initial example + pub fn index_variable(&self) -> &TokenReference { + &self.index_variable + } + + /// The `=` token + pub fn equal_token(&self) -> &TokenReference { + &self.equal_token + } + + /// The starting point, `1` in the initial example + pub fn start(&self) -> &Expression { + &self.start + } + + /// The comma in between the starting point and end point + /// for _ = 1, 10 do + /// ^ + pub fn start_end_comma(&self) -> &TokenReference { + &self.start_end_comma + } + + /// The ending point, `10` in the initial example + pub fn end(&self) -> &Expression { + &self.end + } + + /// The comma in between the ending point and limit, if one exists + /// for _ = 0, 10, 2 do + /// ^ + pub fn end_step_comma(&self) -> Option<&TokenReference> { + self.end_step_comma.as_ref() + } + + /// The step if one exists, `2` in `for index = 0, 10, 2 do end` + pub fn step(&self) -> Option<&Expression> { + self.step.as_ref() + } + + /// The `do` token + pub fn do_token(&self) -> &TokenReference { + &self.do_token + } + + /// The code inside the for loop + pub fn block(&self) -> &Block { + &self.block + } + + /// The `end` token + pub fn end_token(&self) -> &TokenReference { + &self.end_token + } + + /// The type specifiers of the index variable + /// `for i: number = 1, 10 do` returns: + /// `Some(TypeSpecifier(number))` + pub fn type_specifier(&self) -> Option<&TypeSpecifier> { + self.type_specifier.as_ref() + } + + /// Returns a new NumericFor with the given for token + pub fn with_for_token(self, for_token: TokenReference) -> Self { + Self { for_token, ..self } + } + + /// Returns a new NumericFor with the given index variable + pub fn with_index_variable(self, index_variable: TokenReference) -> Self { + Self { index_variable, ..self } + } + + /// Returns a new NumericFor with the given `=` token + pub fn with_equal_token(self, equal_token: TokenReference) -> Self { + Self { equal_token, ..self } + } + + /// Returns a new NumericFor with the given start expression + pub fn with_start(self, start: Expression) -> Self { + Self { start, ..self } + } + + /// Returns a new NumericFor with the given comma between the start and end expressions + pub fn with_start_end_comma(self, start_end_comma: TokenReference) -> Self { + Self { start_end_comma, ..self } + } + + /// Returns a new NumericFor with the given end expression + pub fn with_end(self, end: Expression) -> Self { + Self { end, ..self } + } + + /// Returns a new NumericFor with the given comma between the end and the step expressions + pub fn with_end_step_comma(self, end_step_comma: Option<TokenReference>) -> Self { + Self { end_step_comma, ..self } + } + + /// Returns a new NumericFor with the given step expression + pub fn with_step(self, step: Option<Expression>) -> Self { + Self { step, ..self } + } + + /// Returns a new NumericFor with the given `do` token + pub fn with_do_token(self, do_token: TokenReference) -> Self { + Self { do_token, ..self } + } + + /// Returns a new NumericFor with the given block + pub fn with_block(self, block: Block) -> Self { + Self { block, ..self } + } + + /// Returns a new NumericFor with the given `end` token + pub fn with_end_token(self, end_token: TokenReference) -> Self { + Self { end_token, ..self } + } + + /// Returns a new NumericFor with the given type specifiers + pub fn with_type_specifier(self, type_specifier: Option<TypeSpecifier>) -> Self { + Self { type_specifier, ..self } + } +} + +/// A generic for loop, such as `for index, value in pairs(list) do end` +#[derive(Clone, Debug, PartialEq, Display, Node, Deserialize, Serialize)] +#[display("{for_token}{}{in_token}{expr_list}{do_token}{block}{end_token}", + join_type_specifiers(&self.names, self.type_specifiers()), +)] +pub struct GenericFor { + for_token: TokenReference, + names: Punctuated<TokenReference>, + in_token: TokenReference, + expr_list: Punctuated<Expression>, + do_token: TokenReference, + block: Block, + end_token: TokenReference, + type_specifiers: Vec<Option<TypeSpecifier>>, +} + +impl GenericFor { + /// Creates a new GenericFor from the given names and expressions + pub fn new(names: Punctuated<TokenReference>, expr_list: Punctuated<Expression>) -> Self { + Self { + for_token: TokenReference::basic_symbol("for "), + names, + in_token: TokenReference::basic_symbol(" in "), + expr_list, + do_token: TokenReference::basic_symbol(" do\n"), + block: Block::new(), + end_token: TokenReference::basic_symbol("\nend"), + type_specifiers: Vec::new(), + } + } + + /// The `for` token + pub fn for_token(&self) -> &TokenReference { + &self.for_token + } + + /// Returns the punctuated sequence of names + /// In `for index, value in pairs(list) do`, iterates over `index` and `value` + pub fn names(&self) -> &Punctuated<TokenReference> { + &self.names + } + + /// The `in` token + pub fn in_token(&self) -> &TokenReference { + &self.in_token + } + + /// Returns the punctuated sequence of the expressions looped over + /// In `for index, value in pairs(list) do`, iterates over `pairs(list)` + pub fn expressions(&self) -> &Punctuated<Expression> { + &self.expr_list + } + + /// The `do` token + pub fn do_token(&self) -> &TokenReference { + &self.do_token + } + + /// The code inside the for loop + pub fn block(&self) -> &Block { + &self.block + } + + /// The `end` token + pub fn end_token(&self) -> &TokenReference { + &self.end_token + } + + /// The type specifiers of the named variables, in the order that they were assigned. + /// `for i, v: string in pairs() do` returns an iterator containing: + /// `None, Some(TypeSpecifier(string))` + pub fn type_specifiers(&self) -> impl Iterator<Item = Option<&TypeSpecifier>> { + self.type_specifiers.iter().map(Option::as_ref) + } + + /// Returns a new GenericFor with the given `for` token + pub fn with_for_token(self, for_token: TokenReference) -> Self { + Self { for_token, ..self } + } + + /// Returns a new GenericFor with the given names + pub fn with_names(self, names: Punctuated<TokenReference>) -> Self { + Self { names, ..self } + } + + /// Returns a new GenericFor with the given `in` token + pub fn with_in_token(self, in_token: TokenReference) -> Self { + Self { in_token, ..self } + } + + /// Returns a new GenericFor with the given expression list + pub fn with_expressions(self, expr_list: Punctuated<Expression>) -> Self { + Self { expr_list, ..self } + } + + /// Returns a new GenericFor with the given `do` token + pub fn with_do_token(self, do_token: TokenReference) -> Self { + Self { do_token, ..self } + } + + /// Returns a new GenericFor with the given block + pub fn with_block(self, block: Block) -> Self { + Self { block, ..self } + } + + /// Returns a new GenericFor with the given `end` token + pub fn with_end_token(self, end_token: TokenReference) -> Self { + Self { end_token, ..self } + } + + /// Returns a new GenericFor with the given type specifiers + pub fn with_type_specifiers(self, type_specifiers: Vec<Option<TypeSpecifier>>) -> Self { + Self { type_specifiers, ..self } + } +} + +/// An if statement +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[display("{if_token}{condition}{then_token}{block}{}{}{}{end_token}", + display_option(else_if.as_ref().map(join_vec)), + display_option(else_token), + display_option(r#else), +)] +pub struct If { + if_token: TokenReference, + condition: Expression, + then_token: TokenReference, + block: Block, + else_if: Option<Vec<ElseIf>>, + else_token: Option<TokenReference>, + + #[serde(rename = "else")] + r#else: Option<Block>, + end_token: TokenReference, +} + +impl If { + /// Creates a new If from the given condition + pub fn new(condition: Expression) -> Self { + Self { + if_token: TokenReference::basic_symbol("if "), + condition, + then_token: TokenReference::basic_symbol(" then"), + block: Block::new(), + else_if: None, + else_token: None, + r#else: None, + end_token: TokenReference::basic_symbol("\nend"), + } + } + + /// The `if` token + pub fn if_token(&self) -> &TokenReference { + &self.if_token + } + + /// The condition of the if statement, `condition` in `if condition then` + pub fn condition(&self) -> &Expression { + &self.condition + } + + /// The `then` token + pub fn then_token(&self) -> &TokenReference { + &self.then_token + } + + /// The block inside the initial if statement + pub fn block(&self) -> &Block { + &self.block + } + + /// The `else` token if one exists + pub fn else_token(&self) -> Option<&TokenReference> { + self.else_token.as_ref() + } + + /// If there are `elseif` conditions, returns a vector of them + /// Expression is the condition, block is the code if the condition is true + // TODO: Make this return an iterator, and remove Option part entirely? + pub fn else_if(&self) -> Option<&Vec<ElseIf>> { + self.else_if.as_ref() + } + + /// The code inside an `else` block if one exists + pub fn else_block(&self) -> Option<&Block> { + self.r#else.as_ref() + } + + /// The `end` token + pub fn end_token(&self) -> &TokenReference { + &self.end_token + } + + /// Returns a new If with the given `if` token + pub fn with_if_token(self, if_token: TokenReference) -> Self { + Self { if_token, ..self } + } + + /// Returns a new If with the given condition + pub fn with_condition(self, condition: Expression) -> Self { + Self { condition, ..self } + } + + /// Returns a new If with the given `then` token + pub fn with_then_token(self, then_token: TokenReference) -> Self { + Self { then_token, ..self } + } + + /// Returns a new If with the given block + pub fn with_block(self, block: Block) -> Self { + Self { block, ..self } + } + + /// Returns a new If with the given list of `elseif` blocks + pub fn with_else_if(self, else_if: Option<Vec<ElseIf>>) -> Self { + Self { else_if, ..self } + } + + /// Returns a new If with the given `else` token + pub fn with_else_token(self, else_token: Option<TokenReference>) -> Self { + Self { else_token, ..self } + } + + /// Returns a new If with the given `else` body + pub fn with_else(self, r#else: Option<Block>) -> Self { + Self { r#else, ..self } + } + + /// Returns a new If with the given `end` token + pub fn with_end_token(self, end_token: TokenReference) -> Self { + Self { end_token, ..self } + } +} + +/// An elseif block in a bigger [`If`] statement +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[display("{else_if_token}{condition}{then_token}{block}")] +pub struct ElseIf { + else_if_token: TokenReference, + condition: Expression, + then_token: TokenReference, + block: Block, +} + +impl ElseIf { + /// Creates a new ElseIf from the given condition + pub fn new(condition: Expression) -> Self { + Self { + else_if_token: TokenReference::basic_symbol("elseif "), + condition, + then_token: TokenReference::basic_symbol(" then\n"), + block: Block::new(), + } + } + + /// The `elseif` token + pub fn else_if_token(&self) -> &TokenReference { + &self.else_if_token + } + + /// The condition of the `elseif`, `condition` in `elseif condition then` + pub fn condition(&self) -> &Expression { + &self.condition + } + + /// The `then` token + pub fn then_token(&self) -> &TokenReference { + &self.then_token + } + + /// The body of the `elseif` + pub fn block(&self) -> &Block { + &self.block + } + + /// Returns a new ElseIf with the given `elseif` token + pub fn with_else_if_token(self, else_if_token: TokenReference) -> Self { + Self { else_if_token, ..self } + } + + /// Returns a new ElseIf with the given condition + pub fn with_condition(self, condition: Expression) -> Self { + Self { condition, ..self } + } + + /// Returns a new ElseIf with the given `then` token + pub fn with_then_token(self, then_token: TokenReference) -> Self { + Self { then_token, ..self } + } + + /// Returns a new ElseIf with the given block + pub fn with_block(self, block: Block) -> Self { + Self { block, ..self } + } +} + +/// A while loop +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[display("{while_token}{condition}{do_token}{block}{end_token}")] +pub struct While { + while_token: TokenReference, + condition: Expression, + do_token: TokenReference, + block: Block, + end_token: TokenReference, +} + +impl While { + /// Creates a new While from the given condition + pub fn new(condition: Expression) -> Self { + Self { + while_token: TokenReference::basic_symbol("while "), + condition, + do_token: TokenReference::basic_symbol(" do\n"), + block: Block::new(), + end_token: TokenReference::basic_symbol("end\n"), + } + } + + /// The `while` token + pub fn while_token(&self) -> &TokenReference { + &self.while_token + } + + /// The `condition` part of `while condition do` + pub fn condition(&self) -> &Expression { + &self.condition + } + + /// The `do` token + pub fn do_token(&self) -> &TokenReference { + &self.do_token + } + + /// The code inside the while loop + pub fn block(&self) -> &Block { + &self.block + } + + /// The `end` token + pub fn end_token(&self) -> &TokenReference { + &self.end_token + } + + /// Returns a new While with the given `while` token + pub fn with_while_token(self, while_token: TokenReference) -> Self { + Self { while_token, ..self } + } + + /// Returns a new While with the given condition + pub fn with_condition(self, condition: Expression) -> Self { + Self { condition, ..self } + } + + /// Returns a new While with the given `do` token + pub fn with_do_token(self, do_token: TokenReference) -> Self { + Self { do_token, ..self } + } + + /// Returns a new While with the given block + pub fn with_block(self, block: Block) -> Self { + Self { block, ..self } + } + + /// Returns a new While with the given `end` token + pub fn with_end_token(self, end_token: TokenReference) -> Self { + Self { end_token, ..self } + } +} + +/// A repeat loop +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[display("{repeat_token}{block}{until_token}{until}")] +pub struct Repeat { + repeat_token: TokenReference, + block: Block, + until_token: TokenReference, + until: Expression, +} + +impl Repeat { + /// Creates a new Repeat from the given expression to repeat until + pub fn new(until: Expression) -> Self { + Self { + repeat_token: TokenReference::basic_symbol("repeat\n"), + block: Block::new(), + until_token: TokenReference::basic_symbol("\nuntil "), + until, + } + } + + /// The `repeat` token + pub fn repeat_token(&self) -> &TokenReference { + &self.repeat_token + } + + /// The code inside the `repeat` block + pub fn block(&self) -> &Block { + &self.block + } + + /// The `until` token + pub fn until_token(&self) -> &TokenReference { + &self.until_token + } + + /// The condition for the `until` part + pub fn until(&self) -> &Expression { + &self.until + } + + /// Returns a new Repeat with the given `repeat` token + pub fn with_repeat_token(self, repeat_token: TokenReference) -> Self { + Self { repeat_token, ..self } + } + + /// Returns a new Repeat with the given block + pub fn with_block(self, block: Block) -> Self { + Self { block, ..self } + } + + /// Returns a new Repeat with the given `until` token + pub fn with_until_token(self, until_token: TokenReference) -> Self { + Self { until_token, ..self } + } + + /// Returns a new Repeat with the given `until` block + pub fn with_until(self, until: Expression) -> Self { + Self { until, ..self } + } +} + +/// An attribute on a local variable, `<const>` in `local x <const>` +#[derive(Clone, Debug, Display, PartialEq, Eq, Node, Visit, Deserialize, Serialize)] +#[display("{}{name}{}", brackets.tokens().0, brackets.tokens().1)] +pub struct Attribute { + #[node(full_range)] + #[visit(contains = "name")] + pub(crate) brackets: ContainedSpan, + pub(crate) name: TokenReference, +} + +impl Attribute { + /// Creates a new Label with the given name + pub fn new(name: TokenReference) -> Self { + Self { + brackets: ContainedSpan::new(TokenReference::symbol("<").unwrap(), TokenReference::symbol(">").unwrap()), + name, + } + } + + /// The name used for the attribute, the `const` part of `<const>` + pub fn name(&self) -> &TokenReference { + &self.name + } + + /// The angle brackets (`<` and `>`) surrounding the attribute + pub fn brackets(&self) -> &ContainedSpan { + &self.brackets + } + + /// Returns a new Attribute with the given attribute name + pub fn with_name(self, name: TokenReference) -> Self { + Self { name, ..self } + } + + /// Returns a new Attribute with the given angle brackets + pub fn with_brackets(self, brackets: ContainedSpan) -> Self { + Self { brackets, ..self } + } +} + +/// A method call, such as `x:y()` +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[display("{colon_token}{name}{args}")] +pub struct MethodCall { + colon_token: TokenReference, + name: TokenReference, + args: FunctionArgs, +} + +impl MethodCall { + /// Returns a new MethodCall from the given name and args + pub fn new(name: TokenReference, args: FunctionArgs) -> Self { + Self { colon_token: TokenReference::basic_symbol(":"), name, args } + } + + /// The `:` in `x:y()` + pub fn colon_token(&self) -> &TokenReference { + &self.colon_token + } + + /// The arguments of a method call, the `x, y, z` part of `method:call(x, y, z)` + pub fn args(&self) -> &FunctionArgs { + &self.args + } + + /// The method being called, the `call` part of `method:call()` + pub fn name(&self) -> &TokenReference { + &self.name + } + + /// Returns a new MethodCall with the given `:` token + pub fn with_colon_token(self, colon_token: TokenReference) -> Self { + Self { colon_token, ..self } + } + + /// Returns a new MethodCall with the given name + pub fn with_name(self, name: TokenReference) -> Self { + Self { name, ..self } + } + + /// Returns a new MethodCall with the given args + pub fn with_args(self, args: FunctionArgs) -> Self { + Self { args, ..self } + } +} + +/// Something being called +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[non_exhaustive] +pub enum Call { + #[display("{_0}")] + /// A function being called directly, such as `x(1)` + AnonymousCall(FunctionArgs), + + #[display("{_0}")] + /// A method call, such as `x:y()` + MethodCall(MethodCall), +} + +/// A function body, everything except `function x` in `function x(a, b, c) call() end` +#[derive(Clone, Debug, PartialEq, Display, Node, Deserialize, Serialize)] +#[display("{}{}{}{}{block}{end_token}", + parameters_parentheses.tokens().0, + join_type_specifiers(parameters, self.type_specifiers()), + parameters_parentheses.tokens().1, + display_option(return_type.as_ref()), +)] +pub struct FunctionBody { + parameters_parentheses: ContainedSpan, + parameters: Punctuated<Parameter>, + + type_specifiers: Vec<Option<TypeSpecifier>>, + + #[serde(skip_serializing_if = "Option::is_none")] + return_type: Option<TypeSpecifier>, + + block: Block, + end_token: TokenReference, +} + +impl FunctionBody { + /// Returns a new empty FunctionBody + pub fn new() -> Self { + Self { + parameters_parentheses: ContainedSpan::new( + TokenReference::basic_symbol("("), + TokenReference::basic_symbol(")"), + ), + parameters: Punctuated::new(), + type_specifiers: Vec::new(), + return_type: None, + block: Block::new(), + end_token: TokenReference::basic_symbol("\nend"), + } + } + + /// The parentheses of the parameters + pub fn parameters_parentheses(&self) -> &ContainedSpan { + &self.parameters_parentheses + } + + /// Returns the [`Punctuated`] sequence of the parameters for the function declaration + pub fn parameters(&self) -> &Punctuated<Parameter> { + &self.parameters + } + + /// The code of a function body + pub fn block(&self) -> &Block { + &self.block + } + + /// The mutable code of a function body + pub fn block_mut(&mut self) -> &mut Block { + &mut self.block + } + + /// The `end` token + pub fn end_token(&self) -> &TokenReference { + &self.end_token + } + + /// The type specifiers of the variables, in the order that they were assigned. + /// `(foo: number, bar, baz: boolean)` returns an iterator containing: + /// `Some(TypeSpecifier(number)), None, Some(TypeSpecifier(boolean))` + pub fn type_specifiers(&self) -> impl Iterator<Item = Option<&TypeSpecifier>> { + self.type_specifiers.iter().map(Option::as_ref) + } + + /// The return type of the function, if one exists. + pub fn return_type(&self) -> Option<&TypeSpecifier> { + self.return_type.as_ref() + } + + /// Returns a new FunctionBody with the given parentheses for the parameters + pub fn with_parameters_parentheses(self, parameters_parentheses: ContainedSpan) -> Self { + Self { parameters_parentheses, ..self } + } + + /// Returns a new FunctionBody with the given parameters + pub fn with_parameters(self, parameters: Punctuated<Parameter>) -> Self { + Self { parameters, ..self } + } + + /// Returns a new FunctionBody with the given type specifiers + pub fn with_type_specifiers(self, type_specifiers: Vec<Option<TypeSpecifier>>) -> Self { + Self { type_specifiers, ..self } + } + + /// Returns a new FunctionBody with the given return type + pub fn with_return_type(self, return_type: Option<TypeSpecifier>) -> Self { + Self { return_type, ..self } + } + + /// Returns a new FunctionBody with the given block + pub fn with_block(self, block: Block) -> Self { + Self { block, ..self } + } + + /// Returns a new FunctionBody with the given `end` token + pub fn with_end_token(self, end_token: TokenReference) -> Self { + Self { end_token, ..self } + } +} + +impl Default for FunctionBody { + fn default() -> Self { + Self::new() + } +} + +/// A name parameter in a function declaration, such as `function x(a, b, c)` +#[derive(Clone, Debug, Display, Deref, PartialEq, Eq, Node, Visit, Deserialize, Serialize)] +#[display("{name}")] +pub struct Parameter { + name: TokenReference, +} + +/// A suffix in certain cases, such as `:y()` in `x:y()` +/// Can be stacked on top of each other, such as in `x()()()` +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[non_exhaustive] +pub enum Suffix { + #[display("{_0}")] + /// A call, including method calls and direct calls + Call(Call), + + #[display("{_0}")] + /// An index, such as `x.y` + Index(Index), +} + +/// A complex expression used by [`Var`], consisting of both a prefix and suffixes +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[display("{prefix}{}", join_vec(suffixes))] +pub struct VarExpression { + prefix: Prefix, + suffixes: Vec<Suffix>, +} + +impl VarExpression { + /// Returns a new VarExpression from the given prefix + pub fn new(prefix: Prefix) -> Self { + Self { prefix, suffixes: Vec::new() } + } + + /// The prefix of the expression, such as a name + pub fn prefix(&self) -> &Prefix { + &self.prefix + } + + /// An iter over the suffixes, such as indexing or calling + pub fn suffixes(&self) -> impl Iterator<Item = &Suffix> { + self.suffixes.iter() + } + + /// Returns a new VarExpression with the given prefix + pub fn with_prefix(self, prefix: Prefix) -> Self { + Self { prefix, ..self } + } + + /// Returns a new VarExpression with the given suffixes + pub fn with_suffixes(self, suffixes: Vec<Suffix>) -> Self { + Self { suffixes, ..self } + } +} + +/// Used in [`Assignment`s](Assignment) and [`Value`s](Value) +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[non_exhaustive] +pub enum Var { + /// An expression, such as `x.y.z` or `x()` + #[display("{_0}")] + Expression(Box<VarExpression>), + + /// A literal identifier, such as `x` + #[display("{_0}")] + Name(TokenReference), +} + +/// An assignment, such as `x = y`. Not used for [`LocalAssignment`s](LocalAssignment) +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[display("{var_list}{equal_token}{expr_list}")] +pub struct Assignment { + var_list: Punctuated<Var>, + equal_token: TokenReference, + expr_list: Punctuated<Expression>, +} + +impl Assignment { + /// Returns a new Assignment from the given variable and expression list + pub fn new(var_list: Punctuated<Var>, expr_list: Punctuated<Expression>) -> Self { + Self { var_list, equal_token: TokenReference::basic_symbol(" = "), expr_list } + } + + /// Returns the punctuated sequence over the expressions being assigned. + /// This is the the `1, 2` part of `x, y["a"] = 1, 2` + pub fn expressions(&self) -> &Punctuated<Expression> { + &self.expr_list + } + + /// The `=` token in between `x = y` + pub fn equal_token(&self) -> &TokenReference { + &self.equal_token + } + + /// Returns the punctuated sequence over the variables being assigned to. + /// This is the `x, y["a"]` part of `x, y["a"] = 1, 2` + pub fn variables(&self) -> &Punctuated<Var> { + &self.var_list + } + + /// Returns a new Assignment with the given variables + pub fn with_variables(self, var_list: Punctuated<Var>) -> Self { + Self { var_list, ..self } + } + + /// Returns a new Assignment with the given `=` token + pub fn with_equal_token(self, equal_token: TokenReference) -> Self { + Self { equal_token, ..self } + } + + /// Returns a new Assignment with the given expressions + pub fn with_expressions(self, expr_list: Punctuated<Expression>) -> Self { + Self { expr_list, ..self } + } +} + +/// An import directive, such as `import "math"` +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[display("{import_token}{name}")] +pub struct Import { + import_token: TokenReference, + name: TokenReference, +} + +impl Import { + /// Returns a new LocalFunction from the given name + pub fn new(name: TokenReference) -> Self { + Import { import_token: TokenReference::basic_symbol("import "), name } + } + + /// The `import` token + pub fn import_token(&self) -> &TokenReference { + &self.import_token + } + + /// The name of the module to import, the `x` part of `import "x"` + pub fn name(&self) -> &TokenReference { + &self.name + } + + /// Returns a new Import with the given `import` token + pub fn with_import_token(self, import_token: TokenReference) -> Self { + Self { import_token, ..self } + } + + /// Returns a new Import with the given name + pub fn with_name(self, name: TokenReference) -> Self { + Self { name, ..self } + } +} + +/// A declaration of a local function, such as `local function x() end` +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[display("{local_token}{function_token}{name}{body}")] +pub struct LocalFunction { + local_token: TokenReference, + function_token: TokenReference, + name: TokenReference, + body: FunctionBody, +} + +impl LocalFunction { + /// Returns a new LocalFunction from the given name + pub fn new(name: TokenReference) -> Self { + LocalFunction { + local_token: TokenReference::basic_symbol("local "), + function_token: TokenReference::basic_symbol("function "), + name, + body: FunctionBody::new(), + } + } + + /// The `local` token + pub fn local_token(&self) -> &TokenReference { + &self.local_token + } + + /// The `function` token + pub fn function_token(&self) -> &TokenReference { + &self.function_token + } + + /// The function body, everything except `local function x` in `local function x(a, b, c) call() end` + pub fn body(&self) -> &FunctionBody { + &self.body + } + + /// The name of the function, the `x` part of `local function x() end` + pub fn name(&self) -> &TokenReference { + &self.name + } + + /// Returns a new LocalFunction with the given `local` token + pub fn with_local_token(self, local_token: TokenReference) -> Self { + Self { local_token, ..self } + } + + /// Returns a new LocalFunction with the given `function` token + pub fn with_function_token(self, function_token: TokenReference) -> Self { + Self { function_token, ..self } + } + + /// Returns a new LocalFunction with the given name + pub fn with_name(self, name: TokenReference) -> Self { + Self { name, ..self } + } + + /// Returns a new LocalFunction with the given function body + pub fn with_body(self, body: FunctionBody) -> Self { + Self { body, ..self } + } +} + +/// An assignment to a local variable, such as `local x = 1` +#[derive(Clone, Debug, PartialEq, Display, Node, Deserialize, Serialize)] +#[display("{local_token}{}{}{expr_list}", + join_iterators(name_list, + self.attributes().chain(std::iter::repeat(None)), + self.type_specifiers().chain(std::iter::repeat(None)) + ), + display_option(equal_token), +)] +pub struct LocalAssignment { + local_token: TokenReference, + + #[serde(skip_serializing_if = "empty_optional_vector")] + type_specifiers: Vec<Option<TypeSpecifier>>, + name_list: Punctuated<TokenReference>, + + #[serde(skip_serializing_if = "empty_optional_vector")] + attributes: Vec<Option<Attribute>>, + equal_token: Option<TokenReference>, + expr_list: Punctuated<Expression>, +} + +impl LocalAssignment { + /// Returns a new LocalAssignment from the given name list + pub fn new(name_list: Punctuated<TokenReference>) -> Self { + Self { + local_token: TokenReference::basic_symbol("local "), + type_specifiers: Vec::new(), + name_list, + attributes: Vec::new(), + equal_token: None, + expr_list: Punctuated::new(), + } + } + + /// The `local` token + pub fn local_token(&self) -> &TokenReference { + &self.local_token + } + + /// The `=` token in between `local x = y`, if one exists + pub fn equal_token(&self) -> Option<&TokenReference> { + self.equal_token.as_ref() + } + + /// Returns the punctuated sequence of the expressions being assigned. + /// This is the `1, 2` part of `local x, y = 1, 2` + pub fn expressions(&self) -> &Punctuated<Expression> { + &self.expr_list + } + + /// Returns the punctuated sequence of names being assigned to. + /// This is the `x, y` part of `local x, y = 1, 2` + pub fn names(&self) -> &Punctuated<TokenReference> { + &self.name_list + } + + /// The type specifiers of the variables, in the order that they were assigned. + /// `local foo: number, bar, baz: boolean` returns an iterator containing: + /// `Some(TypeSpecifier(number)), None, Some(TypeSpecifier(boolean))` + pub fn type_specifiers(&self) -> impl Iterator<Item = Option<&TypeSpecifier>> { + self.type_specifiers.iter().map(Option::as_ref) + } + + /// The attributes specified for the variables, in the order that they were assigned. + /// `local foo <const>, bar, baz <close>` returns an iterator containing: + /// `Some(Attribute("const")), None, Some(Attribute("close"))` + pub fn attributes(&self) -> impl Iterator<Item = Option<&Attribute>> { + self.attributes.iter().map(Option::as_ref) + } + + /// Returns a new LocalAssignment with the given `local` token + pub fn with_local_token(self, local_token: TokenReference) -> Self { + Self { local_token, ..self } + } + + /// Returns a new LocalAssignment with the given type specifiers + pub fn with_type_specifiers(self, type_specifiers: Vec<Option<TypeSpecifier>>) -> Self { + Self { type_specifiers, ..self } + } + + /// Returns a new LocalAssignment with the given attributes + pub fn with_attributes(self, attributes: Vec<Option<Attribute>>) -> Self { + Self { attributes, ..self } + } + + /// Returns a new LocalAssignment with the given name list + pub fn with_names(self, name_list: Punctuated<TokenReference>) -> Self { + Self { name_list, ..self } + } + + /// Returns a new LocalAssignment with the given `=` token + pub fn with_equal_token(self, equal_token: Option<TokenReference>) -> Self { + Self { equal_token, ..self } + } + + /// Returns a new LocalAssignment with the given expression list + pub fn with_expressions(self, expr_list: Punctuated<Expression>) -> Self { + Self { expr_list, ..self } + } +} + +/// A `do` block, such as `do ... end` +/// This is not used for things like `while true do end`, only those on their own +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[display("{do_token}{block}{end_token}")] +pub struct Do { + do_token: TokenReference, + block: Block, + end_token: TokenReference, +} + +impl Do { + /// Creates an empty Do + pub fn new() -> Self { + Self { + do_token: TokenReference::basic_symbol("do\n"), + block: Block::new(), + end_token: TokenReference::basic_symbol("\nend"), + } + } + + /// The `do` token + pub fn do_token(&self) -> &TokenReference { + &self.do_token + } + + /// The code inside the `do ... end` + pub fn block(&self) -> &Block { + &self.block + } + + /// The `end` token + pub fn end_token(&self) -> &TokenReference { + &self.end_token + } + + /// Returns a new Do with the given `do` token + pub fn with_do_token(self, do_token: TokenReference) -> Self { + Self { do_token, ..self } + } + + /// Returns a new Do with the given block + pub fn with_block(self, block: Block) -> Self { + Self { block, ..self } + } + + /// Returns a new Do with the given `end` token + pub fn with_end_token(self, end_token: TokenReference) -> Self { + Self { end_token, ..self } + } +} + +impl Default for Do { + fn default() -> Self { + Self::new() + } +} + +/// A function being called, such as `call()` +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[display("{prefix}{}", join_vec(suffixes))] +pub struct FunctionCall { + prefix: Prefix, + suffixes: Vec<Suffix>, +} + +impl FunctionCall { + /// Creates a new FunctionCall from the given prefix + /// Sets the suffixes such that the return is `prefixes()` + pub fn new(prefix: Prefix) -> Self { + FunctionCall { + prefix, + suffixes: vec![Suffix::Call(Call::AnonymousCall(FunctionArgs::Parentheses { + arguments: Punctuated::new(), + parentheses: ContainedSpan::new(TokenReference::basic_symbol("("), TokenReference::basic_symbol(")")), + }))], + } + } + + /// The prefix of a function call, the `call` part of `call()` + pub fn prefix(&self) -> &Prefix { + &self.prefix + } + + /// The suffix of a function call, the `()` part of `call()` + pub fn suffixes(&self) -> impl Iterator<Item = &Suffix> { + self.suffixes.iter() + } + + /// Returns a new FunctionCall with the given prefix + pub fn with_prefix(self, prefix: Prefix) -> Self { + Self { prefix, ..self } + } + + /// Returns a new FunctionCall with the given suffixes + pub fn with_suffixes(self, suffixes: Vec<Suffix>) -> Self { + Self { suffixes, ..self } + } +} + +/// A function name when being declared as [`FunctionDeclaration`] +#[derive(Clone, Debug, Display, PartialEq, Eq, Node, Visit, Deserialize, Serialize)] +#[display("{names}{}{}", + display_option(self.method_colon()), + display_option(self.method_name()) +)] +pub struct FunctionName { + names: Punctuated<TokenReference>, + colon_name: Option<(TokenReference, TokenReference)>, +} + +impl FunctionName { + /// Creates a new FunctionName from the given list of names + pub fn new(names: Punctuated<TokenReference>) -> Self { + Self { names, colon_name: None } + } + + /// The colon between the name and the method, the `:` part of `function x:y() end` + pub fn method_colon(&self) -> Option<&TokenReference> { + Some(&self.colon_name.as_ref()?.0) + } + + /// A method name if one exists, the `y` part of `function x:y() end` + pub fn method_name(&self) -> Option<&TokenReference> { + Some(&self.colon_name.as_ref()?.1) + } + + /// Returns the punctuated sequence over the names used when defining the function. + /// This is the `x.y.z` part of `function x.y.z() end` + pub fn names(&self) -> &Punctuated<TokenReference> { + &self.names + } + + /// Returns a new FunctionName with the given names + pub fn with_names(self, names: Punctuated<TokenReference>) -> Self { + Self { names, ..self } + } + + /// Returns a new FunctionName with the given method name + /// The first token is the colon, and the second token is the method name itself + pub fn with_method(self, method: Option<(TokenReference, TokenReference)>) -> Self { + Self { colon_name: method, ..self } + } +} + +/// A normal function declaration, supports simple declarations like `function x() end` +/// as well as complicated declarations such as `function x.y.z:a() end` +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[display("{function_token}{name}{body}")] +pub struct FunctionDeclaration { + function_token: TokenReference, + name: FunctionName, + body: FunctionBody, +} + +impl FunctionDeclaration { + /// Creates a new FunctionDeclaration from the given name + pub fn new(name: FunctionName) -> Self { + Self { function_token: TokenReference::basic_symbol("function "), name, body: FunctionBody::new() } + } + + /// The `function` token + pub fn function_token(&self) -> &TokenReference { + &self.function_token + } + + /// The body of the function + pub fn body(&self) -> &FunctionBody { + &self.body + } + + /// The name of the function + pub fn name(&self) -> &FunctionName { + &self.name + } + + /// Returns a new FunctionDeclaration with the given `function` token + pub fn with_function_token(self, function_token: TokenReference) -> Self { + Self { function_token, ..self } + } + + /// Returns a new FunctionDeclaration with the given function name + pub fn with_name(self, name: FunctionName) -> Self { + Self { name, ..self } + } + + /// Returns a new FunctionDeclaration with the given function body + pub fn with_body(self, body: FunctionBody) -> Self { + Self { body, ..self } + } +} + +/// An option declaration, such as `option x : number = 1` +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[display("{option_token}{}{equal_token}{expr_list}", + join_type_specifiers(&self.name_list, self.type_specifiers()) +)] +pub struct OptionDecl { + option_token: TokenReference, + + name_list: Punctuated<TokenReference>, + + #[serde(skip_serializing_if = "empty_optional_vector")] + type_specifiers: Vec<Option<TypeSpecifier>>, + + equal_token: TokenReference, + expr_list: Punctuated<Expression>, +} + +impl OptionDecl { + /// Get the declarations of this option declaration statement. + pub fn declarations(&self) -> impl Iterator<Item = (&TokenReference, Option<&TypeSpecifier>, &Expression)> { + self.name_list + .iter() + .zip(&self.type_specifiers) + .zip(&self.expr_list) + .map(|((name, type_specifier), expression)| (name, type_specifier.as_ref(), expression)) + } +} + +/// A call list item. We need a call list to know how to a job from the... +#[derive(Clone, Debug, PartialEq, Display, Node, Visit, Deserialize, Serialize)] +pub enum CallListItem { + /// A reference to a variable, e.g. `"init"` + #[display("{_0}")] + Variable(TokenReference), + + /// Setting of a parameter for the job, e.g. `pre_line = 900` + #[display("{parameter}{equal_token}{expression}")] + SetParameter { + /// The name of the parameter to set for a given job, must be an argument of said job + parameter: TokenReference, + + /// The `=` token of the assignation + equal_token: TokenReference, + + /// The value to set for the given parameter in the given job. + expression: Expression, + }, +} + +impl CallListItem { + /// Returns the last token, for any variant of this enum. + pub fn first_token(&self) -> &TokenReference { + match self { + CallListItem::SetParameter { parameter: first, .. } | CallListItem::Variable(first) => first, + } + } +} + +/// The call list for a job, e.g. `{ param = 1, "init" }` +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize, Default)] +#[display("{}{items}{}", display_option(begin_token), display_option(end_token))] +pub struct CallList { + begin_token: Option<TokenReference>, + items: Punctuated<CallListItem>, + end_token: Option<TokenReference>, +} + +impl CallList { + /// Create a new empty call list + pub fn new() -> Self { + Self::default() + } + + /// Set the `{` token for the call list + pub fn with_begin_token(self, begin_token: Option<TokenReference>) -> Self { + Self { begin_token, ..self } + } + + /// Set the `}` token for the call list + pub fn with_end_token(self, end_token: Option<TokenReference>) -> Self { + Self { end_token, ..self } + } + + /// Set the items in this list + pub fn with_items(self, items: Punctuated<CallListItem>) -> Self { + Self { items, ..self } + } + + /// Get the items out of the call list. + pub fn items(&self) -> &Punctuated<CallListItem> { + &self.items + } +} + +/// The main assignement statement, only inside the `main` statement. +/// +/// ```vivy +/// "OUTLINED" = utils:outline { "BEFORE", "INIT", "AFTER" } +/// "TAGGED" = tag:syl_modulo { every = 3, disp = 1, "OUTLINED" } +/// ``` +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[display("{variable}{assign_token}{module_name}{dot_token}{job_name}{call_list}")] +pub struct MainAssignement { + variable: TokenReference, + assign_token: TokenReference, + + module_name: TokenReference, + dot_token: TokenReference, + job_name: TokenReference, + + call_list: CallList, +} + +impl MainAssignement { + /// Create a new assign statement, only inside the `main` statement. + pub fn new( + assign_token: TokenReference, + variable: TokenReference, + module_name: TokenReference, + dot_token: TokenReference, + job_name: TokenReference, + ) -> Self { + Self { assign_token, variable, module_name, dot_token, job_name, call_list: Default::default() } + } + + /// Set the call-list for this invocation of a job. + pub fn with_call_list(self, call_list: CallList) -> Self { + Self { call_list, ..self } + } + + /// Get the called job out of the assignation + pub fn called_job(&self) -> (&TokenReference, &TokenReference) { + (&self.module_name, &self.job_name) + } + + /// Get the called job out of the assignation as identifiers, otherwise panic. If the program + /// is correct and the parser is Ok, this should never panic + pub fn called_job_identifiers(&self) -> (&ShortString, &ShortString) { + let (module, job) = self.called_job(); + match (module.token_type(), job.token_type()) { + (TokenType::Identifier { identifier: m }, TokenType::Identifier { identifier: j }) => (m, j), + _ => unreachable!("module and job names should be identifiers"), + } + } + + /// Get the call list to know how to call the job. + pub fn call_list(&self) -> &CallList { + &self.call_list + } + + /// Get the items of the call list to know how to call the job. + pub fn call_list_items(&self) -> impl Iterator<Item = &CallListItem> { + self.call_list.items().into_iter() + } + + /// Get the name of the written variable + pub fn destination(&self) -> &TokenReference { + &self.variable + } +} + +/// The main statement: `main "INIT" { ... }` +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[display( + "{main_token}{initial_variable}{begin_token}{}{}{end_token}", + join_vec(assignements), + display_option(write_stmt) +)] +pub struct Main { + main_token: TokenReference, + initial_variable: TokenReference, + begin_token: TokenReference, + assignements: Vec<MainAssignement>, + write_stmt: Option<Write>, + end_token: TokenReference, +} + +impl Main { + /// Create a new empty main statement. + pub fn new( + main_token: TokenReference, + initial_variable: TokenReference, + begin_token: TokenReference, + end_token: TokenReference, + ) -> Self { + Self { main_token, begin_token, end_token, initial_variable, assignements: Vec::new(), write_stmt: None } + } + + /// Get the `main` token. + pub fn main_token(&self) -> &TokenReference { + &self.main_token + } + + /// Get the `do` token in `main do ... end`. + pub fn begin_list_token(&self) -> &TokenReference { + &self.begin_token + } + + /// Get the `end` token in `main do ... end`. + pub fn end_list_token(&self) -> &TokenReference { + &self.end_token + } + + /// Set the `return` variables to write, the token here + pub fn with_returns(self, write_stmt: Option<Write>) -> Self { + Self { write_stmt, ..self } + } + + /// Set the assignements for the 'main' statement. + pub fn with_assignements(self, assignements: Vec<MainAssignement>) -> Self { + Self { assignements, ..self } + } + + /// Get the assignations, i.e. the compute steps + pub fn assignements(&self) -> &[MainAssignement] { + &self.assignements + } + + /// Get the written variables + pub fn returns(&self) -> Option<&Write> { + self.write_stmt.as_ref() + } + + /// Get the name of the initial variable + pub fn initial_variable(&self) -> &TokenReference { + &self.initial_variable + } +} + +/// The write directive, with the variables to write into the final file: `write "INIT"`. +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[display("{write_token}{}{variable_list}{}", + display_option(self.begin_list_token()), + display_option(self.end_list_token()) +)] +pub struct Write { + write_token: TokenReference, + begin_token: Option<TokenReference>, + variable_list: Punctuated<TokenReference>, + end_token: Option<TokenReference>, +} + +impl Write { + /// Create a new empty write statement. + pub fn new(write_token: TokenReference) -> Self { + Self { write_token, begin_token: None, variable_list: Punctuated::new(), end_token: None } + } + + /// Get the `write` token for this statement. + pub fn write_token(&self) -> &TokenReference { + &self.write_token + } + + /// Get the list of variables to write + pub fn variables(&self) -> &Punctuated<TokenReference> { + &self.variable_list + } + + /// Get the '{' token if present in the write statement. + pub fn begin_list_token(&self) -> Option<&TokenReference> { + self.begin_token.as_ref() + } + + /// Get the '}' token if present in the write statement. + pub fn end_list_token(&self) -> Option<&TokenReference> { + self.end_token.as_ref() + } + + /// Set the `}` token. + pub fn with_end_list_token(self, end_token: Option<TokenReference>) -> Self { + Self { end_token, ..self } + } + + /// Set the `{` token. + pub fn with_begin_list_token(self, begin_token: Option<TokenReference>) -> Self { + Self { begin_token, ..self } + } + + /// Set the list of variables to write. + pub fn with_variables(self, variable_list: Punctuated<TokenReference>) -> Self { + Self { variable_list, ..self } + } +} + +#[doc(hidden)] +#[macro_export] +macro_rules! make_bin_op { + ($(#[$outer:meta])* { $( + $operator:ident = $precedence:expr, + )+ }) => { + paste::paste! { + #[derive(Clone, Debug, Display, PartialEq, Eq, Node, Visit, Deserialize, Serialize)] + #[non_exhaustive] + $(#[$outer])* + pub enum BinOp { + $(#[display("{_0}")] #[allow(missing_docs)] $operator(TokenReference),)+ + } + + impl BinOp { + /// The precedence of non-unary operator. The larger the number, the higher the precedence. + /// Shares the same precedence table as unary operators. + pub fn precedence_of_token(token: &TokenReference) -> Option<u8> { + match token.token_type() { + TokenType::Symbol { symbol } => match symbol { + $(Symbol::$operator => Some($precedence),)+ _ => None, + }, + _ => None + } + } + + /// The token associated with this operator + pub fn token(&self) -> &TokenReference { + match self { + $(BinOp::$operator(token) => token,)+ + } + } + + pub(crate) fn consume(state: &mut ParserState) -> Option<Self> { + match state.current().unwrap().token_type() { + TokenType::Symbol { symbol } => match symbol { + $(Symbol::$operator => { Some(BinOp::$operator(state.consume().unwrap())) },)+ + _ => None, + }, + _ => None, + } + } + } + } + }; +} + +make_bin_op!( + #[doc = "Operators that require two operands, such as X + Y or X - Y"] + #[visit(skip_visit_self)] + { + Caret = 12, + + // At the 11° position we have the unary operations. + + Percent = 10, + Slash = 10, + Star = 10, + DoubleSlash = 10, + + Minus = 9, + Plus = 9, + + TwoDots = 8, + + DoubleGreaterThan = 7, + DoubleLesserThan = 7, + + Ampersand = 6, + + Tilde = 5, + + Pipe = 4, + + GreaterThan = 3, + GreaterThanEqual = 3, + LessThan = 3, + LessThanEqual = 3, + TildeEqual = 3, + TwoEqual = 3, + + And = 2, + + Or = 1, + } +); + +impl BinOp { + /// The precedence of the operator. The larger the number, the higher the precedence. + /// See more at <http://www.lua.org/manual/5.1/manual.html#2.5.6> + pub fn precedence(&self) -> u8 { + BinOp::precedence_of_token(self.token()).expect("invalid token") + } + + /// Whether the operator is right associative. If not, it is left associative. + /// See more at <https://www.lua.org/pil/3.5.html> + pub fn is_right_associative(&self) -> bool { + matches!(*self, BinOp::Caret(_) | BinOp::TwoDots(_)) + } + + /// Given a token, returns whether it is a right associative binary operator. + pub fn is_right_associative_token(token: &TokenReference) -> bool { + matches!( + token.token_type(), + TokenType::Symbol { symbol: Symbol::Caret } | TokenType::Symbol { symbol: Symbol::TwoDots } + ) + } +} + +/// Operators that require just one operand, such as #X +#[derive(Clone, Debug, Display, PartialEq, Eq, Node, Visit, Deserialize, Serialize)] +#[allow(missing_docs)] +#[non_exhaustive] +pub enum UnOp { + Minus(TokenReference), + Not(TokenReference), + Hash(TokenReference), + Tilde(TokenReference), +} + +impl UnOp { + /// The token associated with the operator + pub fn token(&self) -> &TokenReference { + match self { + UnOp::Minus(token) | UnOp::Not(token) | UnOp::Hash(token) => token, + UnOp::Tilde(token) => token, + } + } + + /// The precedence of unary operator. The larger the number, the higher the precedence. + /// Shares the same precedence table as binary operators. + pub fn precedence() -> u8 { + 11 + } +} + +impl OptionDecl { + /// Returns a new OptionSet from the given name list + pub fn new(name_list: Punctuated<TokenReference>) -> Self { + Self { + option_token: TokenReference::basic_symbol("option "), + type_specifiers: Vec::new(), + name_list, + equal_token: TokenReference::basic_symbol("= "), + expr_list: Punctuated::new(), + } + } + + /// Get the `option` token + pub fn option_token(&self) -> &TokenReference { + &self.option_token + } + + /// Get the `=` token + pub fn equal_token(&self) -> &TokenReference { + &self.equal_token + } + + /// Get the expressions + pub fn expressions(&self) -> &Punctuated<Expression> { + &self.expr_list + } + + /// Get the names of the options to set + pub fn names(&self) -> &Punctuated<TokenReference> { + &self.name_list + } + + /// Get the type specifiers + pub fn type_specifiers(&self) -> impl Iterator<Item = Option<&TypeSpecifier>> { + self.type_specifiers.iter().map(Option::as_ref) + } + + /// Set the type specifiers + pub fn with_type_specifiers(self, type_specifiers: Vec<Option<TypeSpecifier>>) -> Self { + Self { type_specifiers, ..self } + } + + /// Set the `option` token + pub fn with_option_token(self, option_token: TokenReference) -> Self { + Self { option_token, ..self } + } + + /// Set the `=` token + pub fn with_equal_token(self, equal_token: TokenReference) -> Self { + Self { equal_token, ..self } + } + + /// Set the expressions + pub fn with_expressions(self, expr_list: Punctuated<Expression>) -> Self { + Self { expr_list, ..self } + } +} + +/// An error that occurs when creating the AST. +#[derive(Clone, Debug, PartialEq, Eq, Display, Deserialize, Serialize)] +#[display( + "unexpected token `{token}`. (starting from line {}, character {} and ending on line {}, character {})\nadditional information: {additional}", + self.range().0.line(), + self.range().0.character(), + self.range().1.line(), + self.range().1.character(), +)] +pub struct AstError { + /// The token that caused the error + token: Token, + + /// Any additional information that could be provided for debugging + additional: Cow<'static, str>, + + /// If set, this is the complete range of the error + #[serde(skip_serializing_if = "Option::is_none")] + range: Option<(Position, Position)>, +} + +impl AstError { + /// Returns the token that caused the error + pub fn token(&self) -> &Token { + &self.token + } + + /// Returns a human readable error message + pub fn error_message(&self) -> Cow<'static, str> { + self.additional.clone() + } + + /// Returns the range of the error + pub fn range(&self) -> (Position, Position) { + self.range + .or_else(|| Some((self.token.start_position(), self.token.end_position()))) + .unwrap() + } + + /// Create an error from its parts, not really something we want to expose, but errors may come + /// from the passes and not the parse stage... + pub(crate) fn from_parts(token_reference: TokenReference, error: impl Into<Cow<'static, str>>) -> Self { + Self { token: token_reference.token().clone(), additional: error.into(), range: token_reference.range() } + } +} + +impl std::error::Error for AstError {} + +/// An abstract syntax tree, contains all the nodes used in the code +#[derive(Clone, Debug, Display, Deserialize, Serialize)] +#[display("{nodes}{eof}")] +pub struct Ast { + pub(crate) nodes: Block, + pub(crate) eof: TokenReference, +} + +impl Ast { + /// Returns a new Ast with the given nodes + pub fn with_nodes(self, nodes: Block) -> Self { + Self { nodes, ..self } + } + + /// Returns a new Ast with the given EOF token + pub fn with_eof(self, eof: TokenReference) -> Self { + Self { eof, ..self } + } + + /// The entire code of the function + pub fn nodes(&self) -> &Block { + &self.nodes + } + + /// The entire code of the function, but mutable + pub fn nodes_mut(&mut self) -> &mut Block { + &mut self.nodes + } + + /// The EOF token at the end of every Ast + pub fn eof(&self) -> &TokenReference { + &self.eof + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{prelude::parser::parse_lua_tree, visitors::VisitorMut}; + + #[test] + fn test_with_eof_safety() { + print!("{}", { + let ast = parse_lua_tree("local foo = 1").unwrap(); + let eof = ast.eof().clone(); + ast.with_eof(eof) + }); + } + + #[test] + fn test_with_nodes_safety() { + print!("{}", { + let ast = parse_lua_tree("local foo = 1").unwrap(); + let nodes = ast.nodes().clone(); + ast.with_nodes(nodes) + }); + } + + #[test] + fn test_with_visitor_safety() { + print!("{}", { + let ast = parse_lua_tree("local foo = 1").unwrap(); + struct SyntaxRewriter; + impl VisitorMut for SyntaxRewriter { + fn visit_token(&mut self, token: Token) -> Token { + token + } + } + SyntaxRewriter.visit_ast(ast) + }); + } + + // Tests AST nodes with new methods that call unwrap + #[test] + fn test_new_validity() { + let token: TokenReference = + TokenReference::new(Vec::new(), Token::new(TokenType::Identifier { identifier: "foo".into() }), Vec::new()); + + let expression = Expression::Var(Var::Name(token.clone())); + + Assignment::new(Punctuated::new(), Punctuated::new()); + Do::new(); + ElseIf::new(expression.clone()); + FunctionBody::new(); + FunctionCall::new(Prefix::Name(token.clone())); + FunctionDeclaration::new(FunctionName::new(Punctuated::new())); + GenericFor::new(Punctuated::new(), Punctuated::new()); + If::new(expression.clone()); + LocalAssignment::new(Punctuated::new()); + LocalFunction::new(token.clone()); + MethodCall::new( + token.clone(), + FunctionArgs::Parentheses { + arguments: Punctuated::new(), + parentheses: ContainedSpan::new(token.clone(), token.clone()), + }, + ); + NumericFor::new(token, expression.clone(), expression.clone()); + Repeat::new(expression.clone()); + Return::new(); + TableConstructor::new(); + While::new(expression); + } + + #[test] + fn test_local_assignment_print() { + let block = Block::new().with_stmts(vec![( + Stmt::LocalAssignment( + LocalAssignment::new( + std::iter::once(Pair::End(TokenReference::new( + vec![], + Token::new(TokenType::Identifier { identifier: "variable".into() }), + vec![], + ))) + .collect(), + ) + .with_equal_token(Some(TokenReference::symbol(" = ").unwrap())) + .with_expressions( + std::iter::once(Pair::End(Expression::Number(TokenReference::new( + vec![], + Token::new(TokenType::Number { text: "1".into() }), + vec![], + )))) + .collect(), + ), + ), + None, + )]); + + let ast = parse_lua_tree("").unwrap().with_nodes(block); + assert_eq!(format!("{ast}"), "local variable = 1"); + } +} + +/// Any type, such as `string`, `boolean?`, etc. +#[derive(Clone, Debug, Display, IsVariant, PartialEq, Node, Deserialize, Serialize)] +#[non_exhaustive] +pub enum TypeInfo { + /// A shorthand type annotating the structure of an array: { number } + #[display("{}{type_info}{}", braces.tokens().0, braces.tokens().1)] + Array { + /// The braces (`{}`) containing the type info. + braces: ContainedSpan, + + /// The type info for the values in the Array + type_info: Box<TypeInfo>, + }, + + /// A standalone type, such as `string` or `Foo`. + #[display("{_0}")] + Basic(TokenReference), + + /// A callback type, such as `(string, number) => boolean`. + #[display("{}{arguments}{}{arrow}{return_type}", parentheses.tokens().0, parentheses.tokens().1)] + Callback { + /// The parentheses for the arguments. + parentheses: ContainedSpan, + + /// The argument types: `(string, number)`. + arguments: Punctuated<TypeArgument>, + + /// The "thin arrow" (`->`) in between the arguments and the return type. + arrow: TokenReference, + + /// The return type: `boolean`. + return_type: Box<TypeInfo>, + }, + + /// An optional type, such as `string?`. + #[display("{base}{question_mark}")] + Optional { + /// The type that is optional: `string`. + base: Box<TypeInfo>, + + /// The question mark: `?`. + question_mark: TokenReference, + }, + + /// A type annotating the structure of a table: { foo: number, bar: string } + #[display("{}{fields}{}", braces.tokens().0, braces.tokens().1)] + Table { + /// The braces (`{}`) containing the fields. + braces: ContainedSpan, + + /// The fields: `foo: number, bar: string`. + fields: Punctuated<TypeField>, + }, + + /// A type in the form of `typeof(foo)`. + #[display("{typeof_token}{}{inner}{}", parentheses.tokens().0, parentheses.tokens().1)] + Typeof { + /// The token `typeof`. + typeof_token: TokenReference, + + /// The parentheses used to contain the expression. + parentheses: ContainedSpan, + + /// The inner expression: `foo`. + inner: Box<Expression>, + }, + + /// A tuple expression: `(string, number)`. + #[display("{}{types}{}", parentheses.tokens().0, parentheses.tokens().1)] + Tuple { + /// The parentheses used to contain the types + parentheses: ContainedSpan, + + /// The types: `(string, number)`. + types: Punctuated<TypeInfo>, + }, +} + +macro_rules! basic_type_info { + ($type: ident, $($types: ident),+ $(,)?) => { + basic_type_info! { $type } + basic_type_info! { $($types),+ } + }; + + ($type: ident) => { + #[doc = concat!("Get the type for '", stringify!($type), "'")] + pub fn $type() -> &'static Self { + const _: () = assert!(stringify!($type).len() <= 23, "the type name can't be inline"); + static TYPE_INFO: TypeInfo = TypeInfo::Basic(TokenReference::new( + vec![], + Token::new(TokenType::Identifier { identifier: ShortString::new_inline(stringify!($type)) }), + vec![]) + ); + &TYPE_INFO + } + }; +} + +impl TypeInfo { + basic_type_info! { + string, number, char, nil, table, aux, any, + line, lines, syllabe, syllabes, + } +} + +impl Default for TypeInfo { + fn default() -> Self { + TypeInfo::nil().clone() + } +} + +impl DefaultRef for TypeInfo { + fn default_ref() -> &'static Self { + TypeInfo::nil() + } +} + +/// A type field used within table types. +/// The `foo: number` in `{ foo: number }`. +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[display("{key}{colon}{value}")] +pub struct TypeField { + pub(crate) key: TypeFieldKey, + pub(crate) colon: TokenReference, + pub(crate) value: TypeInfo, +} + +impl TypeField { + /// Creates a new TypeField from the given key and value + pub fn new(key: TypeFieldKey, value: TypeInfo) -> Self { + Self { key, colon: TokenReference::symbol(": ").unwrap(), value } + } + + /// The key of the field, `foo` in `foo: number`. + pub fn key(&self) -> &TypeFieldKey { + &self.key + } + + /// The colon in between the key name and the value type. + pub fn colon_token(&self) -> &TokenReference { + &self.colon + } + + /// The type for the field, `number` in `foo: number`. + pub fn value(&self) -> &TypeInfo { + &self.value + } + + /// Returns a new TypeField with the given key + pub fn with_key(self, key: TypeFieldKey) -> Self { + Self { key, ..self } + } + + /// Returns a new TypeField with the `:` token + pub fn with_colon_token(self, colon_token: TokenReference) -> Self { + Self { colon: colon_token, ..self } + } + + /// Returns a new TypeField with the `:` token + pub fn with_value(self, value: TypeInfo) -> Self { + Self { value, ..self } + } +} + +/// A key in a [`TypeField`]. Can either be a name or an index signature. +#[derive(Clone, Debug, Display, PartialEq, Node, Deserialize, Serialize)] +#[non_exhaustive] +pub enum TypeFieldKey { + /// A name, such as `foo`. + #[display("{_0}")] + Name(TokenReference), + + /// An index signature, such as `[number]`. + #[display("{}{inner}{}", brackets.tokens().0, brackets.tokens().1)] + IndexSignature { + /// The brackets (`[]`) used to contain the type. + brackets: ContainedSpan, + + /// The type for the index signature, `number` in `[number]`. + inner: TypeInfo, + }, +} + +/// A type assertion using `::`, such as `:: number`. +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[display("{assertion_op}{cast_to}")] +pub struct TypeAssertion { + pub(crate) assertion_op: TokenReference, + pub(crate) cast_to: TypeInfo, +} + +impl TypeAssertion { + /// Creates a new TypeAssertion from the given cast to TypeInfo + pub fn new(cast_to: TypeInfo) -> Self { + Self { assertion_op: TokenReference::symbol("::").unwrap(), cast_to } + } + + /// The token `::`. + pub fn assertion_op(&self) -> &TokenReference { + &self.assertion_op + } + + /// The type to cast the expression into, `number` in `:: number`. + pub fn cast_to(&self) -> &TypeInfo { + &self.cast_to + } + + /// Returns a new TypeAssertion with the given `::` token + pub fn with_assertion_op(self, assertion_op: TokenReference) -> Self { + Self { assertion_op, ..self } + } + + /// Returns a new TypeAssertion with the given TypeInfo to cast to + pub fn with_cast_to(self, cast_to: TypeInfo) -> Self { + Self { cast_to, ..self } + } +} + +/// A type declaration, such as `type Meters = number` +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[display("{type_token}{base}{equal_token}{declare_as}")] +pub struct TypeDeclaration { + pub(crate) type_token: TokenReference, + pub(crate) base: TokenReference, + pub(crate) equal_token: TokenReference, + pub(crate) declare_as: TypeInfo, +} + +impl TypeDeclaration { + /// Creates a new TypeDeclaration from the given type name and type declaration + pub fn new(type_name: TokenReference, type_definition: TypeInfo) -> Self { + Self { + type_token: TokenReference::new( + Vec::new(), + Token::new(TokenType::Identifier { identifier: "type".into() }), + vec![Token::new(TokenType::spaces(1))], + ), + base: type_name, + equal_token: TokenReference::symbol(" = ").unwrap(), + declare_as: type_definition, + } + } + + /// The token `type`. + pub fn type_token(&self) -> &TokenReference { + &self.type_token + } + + /// The name of the type, `Meters` in `type Meters = number`. + pub fn type_name(&self) -> &TokenReference { + &self.base + } + + /// The `=` token in between the type name and the definition. + pub fn equal_token(&self) -> &TokenReference { + &self.equal_token + } + + /// The definition of the type, `number` in `type Meters = number`. + pub fn type_definition(&self) -> &TypeInfo { + &self.declare_as + } + + /// Returns a new TypeDeclaration with the given `type` token + pub fn with_type_token(self, type_token: TokenReference) -> Self { + Self { type_token, ..self } + } + + /// Returns a new TypeDeclaration with the given type name + pub fn with_type_name(self, type_name: TokenReference) -> Self { + Self { base: type_name, ..self } + } + + /// Returns a new TypeDeclaration with the given generics of the type + pub fn with_equal_token(self, equal_token: TokenReference) -> Self { + Self { equal_token, ..self } + } + + /// Returns a new TypeDeclaration with the given generics of the type + pub fn with_type_definition(self, type_definition: TypeInfo) -> Self { + Self { declare_as: type_definition, ..self } + } +} + +/// A type specifier, the `: number` in `local foo: number` +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[display("{punctuation}{type_info}")] +pub struct TypeSpecifier { + pub(crate) punctuation: TokenReference, + pub(crate) type_info: TypeInfo, +} + +impl TypeSpecifier { + /// Creates a new TypeSpecifier with the given type info + pub fn new(type_info: TypeInfo) -> Self { + Self { punctuation: TokenReference::symbol(": ").unwrap(), type_info } + } + + /// The punctuation being used. + /// `:` for `local foo: number`. + pub fn punctuation(&self) -> &TokenReference { + &self.punctuation + } + + /// The type being specified: `number` in `local foo: number`. + pub fn type_info(&self) -> &TypeInfo { + &self.type_info + } + + /// Returns a new TypeSpecifier with the given punctuation + pub fn with_punctuation(self, punctuation: TokenReference) -> Self { + Self { punctuation, ..self } + } + + /// Returns a new TypeSpecifier with the given type being specified + pub fn with_type_info(self, type_info: TypeInfo) -> Self { + Self { type_info, ..self } + } +} + +/// A type argument specified in a callback type, the `count: number` in `(count: number) -> ()` +#[derive(Clone, Debug, PartialEq, Node, Visit, Deserialize, Serialize)] +pub struct TypeArgument { + pub(crate) name: Option<(TokenReference, TokenReference)>, + pub(crate) type_info: TypeInfo, +} + +impl TypeArgument { + /// Creates a new TypeArgument with the given type info + pub fn new(type_info: TypeInfo) -> Self { + Self { name: None, type_info } + } + + /// The name of the argument split into identifier and punctuation: `count:` in `count: number`. + pub fn name(&self) -> Option<&(TokenReference, TokenReference)> { + self.name.as_ref() + } + + /// The type info for the argument: `number` in `count: number`. + pub fn type_info(&self) -> &TypeInfo { + &self.type_info + } + + /// Returns a new TypeArgument with the given punctuation + pub fn with_name(self, name: Option<(TokenReference, TokenReference)>) -> Self { + Self { name, ..self } + } + + /// Returns a new TypeArgument with the given type info + pub fn with_type_info(self, type_info: TypeInfo) -> Self { + Self { type_info, ..self } + } +} + +impl fmt::Display for TypeArgument { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + if let Some((identifier, punctuation)) = self.name() { + write!(formatter, "{}{}{}", identifier, punctuation, self.type_info) + } else { + write!(formatter, "{}", self.type_info) + } + } +} + +/// Compound operators, such as X += Y or X -= Y +#[derive(Clone, Debug, Display, PartialEq, Eq, Node, Visit, Deserialize, Serialize)] +#[non_exhaustive] +#[allow(missing_docs)] +pub enum CompoundOp { + PlusEqual(TokenReference), + MinusEqual(TokenReference), + StarEqual(TokenReference), + SlashEqual(TokenReference), + DoubleSlashEqual(TokenReference), + PercentEqual(TokenReference), + CaretEqual(TokenReference), + TwoDotsEqual(TokenReference), +} + +impl CompoundOp { + /// The token associated with the operator + pub fn token(&self) -> &TokenReference { + match self { + Self::PlusEqual(token) + | Self::MinusEqual(token) + | Self::StarEqual(token) + | Self::SlashEqual(token) + | Self::DoubleSlashEqual(token) + | Self::PercentEqual(token) + | Self::CaretEqual(token) + | Self::TwoDotsEqual(token) => token, + } + } + + pub(crate) fn from_token(token: TokenReference) -> Self { + if token.is_symbol(Symbol::PlusEqual) { + Self::PlusEqual(token) + } else if token.is_symbol(Symbol::MinusEqual) { + Self::MinusEqual(token) + } else if token.is_symbol(Symbol::StarEqual) { + Self::StarEqual(token) + } else if token.is_symbol(Symbol::SlashEqual) { + Self::SlashEqual(token) + } else if token.is_symbol(Symbol::DoubleSlashEqual) { + Self::DoubleSlashEqual(token) + } else if token.is_symbol(Symbol::PercentEqual) { + Self::PercentEqual(token) + } else if token.is_symbol(Symbol::CaretEqual) { + Self::CaretEqual(token) + } else if token.is_symbol(Symbol::TwoDotsEqual) { + Self::TwoDotsEqual(token) + } else { + unreachable!("converting an unknown token into a compound operator") + } + } +} + +/// A Compound Assignment statement, such as `x += 1` or `x -= 1` +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[display("{lhs}{compound_operator}{rhs}")] +pub struct CompoundAssignment { + pub(crate) lhs: Var, + pub(crate) compound_operator: CompoundOp, + pub(crate) rhs: Expression, +} + +impl CompoundAssignment { + /// Creates a new CompoundAssignment from the left and right hand side + pub fn new(lhs: Var, compound_operator: CompoundOp, rhs: Expression) -> Self { + Self { lhs, compound_operator, rhs } + } + + /// The variable assigned to, the `x` part of `x += 1` + pub fn lhs(&self) -> &Var { + &self.lhs + } + + /// The operator used, the `+=` part of `x += 1` + pub fn compound_operator(&self) -> &CompoundOp { + &self.compound_operator + } + + /// The value being assigned, the `1` part of `x += 1` + pub fn rhs(&self) -> &Expression { + &self.rhs + } + + /// Returns a new CompoundAssignment with the given variable being assigned to + pub fn with_lhs(self, lhs: Var) -> Self { + Self { lhs, ..self } + } + + /// Returns a new CompoundAssignment with the given operator used + pub fn with_compound_operator(self, compound_operator: CompoundOp) -> Self { + Self { compound_operator, ..self } + } + + /// Returns a new CompoundAssignment with the given value being assigned + pub fn with_rhs(self, rhs: Expression) -> Self { + Self { rhs, ..self } + } +} + +/// An if statement +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[display("{if_token}{condition}{then_token}{if_expression}{}{else_token}{else_expression}", + display_option(else_if_expressions.as_ref().map(join_vec)), +)] +pub struct IfExpression { + pub(crate) if_token: TokenReference, + pub(crate) condition: Box<Expression>, + pub(crate) then_token: TokenReference, + pub(crate) if_expression: Box<Expression>, + pub(crate) else_if_expressions: Option<Vec<ElseIfExpression>>, + pub(crate) else_token: TokenReference, + pub(crate) else_expression: Box<Expression>, +} + +impl IfExpression { + /// Creates a new If from the given condition + pub fn new(condition: Expression, if_expression: Expression, else_expression: Expression) -> Self { + Self { + if_token: TokenReference::symbol("if ").unwrap(), + condition: Box::new(condition), + then_token: TokenReference::symbol(" then").unwrap(), + if_expression: Box::new(if_expression), + else_if_expressions: None, + else_token: TokenReference::symbol(" else ").unwrap(), + else_expression: Box::new(else_expression), + } + } + + /// The `if` token + pub fn if_token(&self) -> &TokenReference { + &self.if_token + } + + /// The condition of the if expression, `condition` in `if condition then` + pub fn condition(&self) -> &Expression { + &self.condition + } + + /// The `then` token + pub fn then_token(&self) -> &TokenReference { + &self.then_token + } + + /// The expression evaluated if the initial if condition holds + pub fn if_expression(&self) -> &Expression { + &self.if_expression + } + + /// The `else` token + pub fn else_token(&self) -> &TokenReference { + &self.else_token + } + + /// If there are `elseif` conditions, returns a vector of them + pub fn else_if_expressions(&self) -> impl Iterator<Item = &ElseIfExpression> { + self.else_if_expressions.as_ref().into_iter().flatten() + } + + /// The else expression if all other conditions do not hold + pub fn else_expression(&self) -> &Expression { + &self.else_expression + } + + /// Returns a new IfExpression with the given `if` token + pub fn with_if_token(self, if_token: TokenReference) -> Self { + Self { if_token, ..self } + } + + /// Returns a new IfExpression with the given condition + pub fn with_condition(self, condition: Expression) -> Self { + Self { condition: Box::new(condition), ..self } + } + + /// Returns a new IfExpression with the given `then` token + pub fn with_then_token(self, then_token: TokenReference) -> Self { + Self { then_token, ..self } + } + + /// Returns a new IfExpression with the given if expression + pub fn with_if_expression(self, if_expression: Expression) -> Self { + Self { if_expression: Box::new(if_expression), ..self } + } + + /// Returns a new If with the given list of `elseif` expressions + pub fn with_else_if(self, else_if_expressions: Option<Vec<ElseIfExpression>>) -> Self { + Self { else_if_expressions, ..self } + } + + /// Returns a new IfExpression with the given `else` token + pub fn with_else_token(self, else_token: TokenReference) -> Self { + Self { else_token, ..self } + } + + /// Returns a new IfExpression with the given `else` expression + pub fn with_else(self, else_expression: Expression) -> Self { + Self { else_expression: Box::new(else_expression), ..self } + } +} + +/// An elseif expression in a bigger [`IfExpression`] expression +#[derive(Clone, Debug, Display, PartialEq, Node, Visit, Deserialize, Serialize)] +#[display("{else_if_token}{condition}{then_token}{expression}")] +pub struct ElseIfExpression { + pub(crate) else_if_token: TokenReference, + pub(crate) condition: Expression, + pub(crate) then_token: TokenReference, + pub(crate) expression: Expression, +} + +impl ElseIfExpression { + /// Creates a new ElseIf from the given condition + pub fn new(condition: Expression, expression: Expression) -> Self { + Self { + else_if_token: TokenReference::symbol(" elseif ").unwrap(), + condition, + then_token: TokenReference::symbol(" then ").unwrap(), + expression, + } + } + + /// The `elseif` token + pub fn else_if_token(&self) -> &TokenReference { + &self.else_if_token + } + + /// The condition of the `elseif`, `condition` in `elseif condition then` + pub fn condition(&self) -> &Expression { + &self.condition + } + + /// The `then` token + pub fn then_token(&self) -> &TokenReference { + &self.then_token + } + + /// The evaluated expression of the `elseif` when condition is true + pub fn expression(&self) -> &Expression { + &self.expression + } + + /// Returns a new ElseIfExpression with the given `elseif` token + pub fn with_else_if_token(self, else_if_token: TokenReference) -> Self { + Self { else_if_token, ..self } + } + + /// Returns a new ElseIfExpression with the given condition + pub fn with_condition(self, condition: Expression) -> Self { + Self { condition, ..self } + } + + /// Returns a new ElseIfExpression with the given `then` token + pub fn with_then_token(self, then_token: TokenReference) -> Self { + Self { then_token, ..self } + } + + /// Returns a new ElseIfExpression with the given expression + pub fn with_block(self, expression: Expression) -> Self { + Self { expression, ..self } + } +} diff --git a/src/Rust/vvs_parser/src/ast/options.rs b/src/Rust/vvs_parser/src/ast/options.rs new file mode 100644 index 0000000000000000000000000000000000000000..228af95da682bb3fb9b4a104542735e5e8761c93 --- /dev/null +++ b/src/Rust/vvs_parser/src/ast/options.rs @@ -0,0 +1,108 @@ +//! Option table passed to the Vivy program at runtime. + +use crate::{ast::Expression, ShortString}; +use serde::{Deserialize, Serialize}; + +/// Options for a program, represent the thing that is red from a file. +/// +/// The syntax was a bit modified: +/// ```ini +/// [module] +/// option = some Lua/VivyScript expression +/// ``` +#[derive(Default, Serialize, Deserialize)] +pub struct OptionTable { + modules: Vec<(ShortString, Vec<(ShortString, Expression)>)>, +} + +pub(crate) struct OptionTableSectionMut<'a> { + options: &'a mut Vec<(ShortString, Expression)>, +} + +impl OptionTable { + /// Create a new empty default option table. + pub fn new() -> Self { + Default::default() + } + + /// Get the number of options in the table + pub fn len(&self) -> usize { + self.modules.iter().map(|(_, section)| section.len()).sum() + } + + /// Tells whever we have options in the table or not. + pub fn is_empty(&self) -> bool { + self.modules.iter().all(|(_, section)| section.is_empty()) + } + + /// Get the asked option if it exists in this table. + pub fn get(&self, module: impl AsRef<str>, option: impl AsRef<str>) -> Option<&Expression> { + self.modules + .iter() + .find_map(|(name, section)| (name.as_str() == module.as_ref()).then_some(section))? + .iter() + .find_map(|(name, value)| (name.as_str() == option.as_ref()).then_some(value)) + } + + /// Tells whether we have a said section or not in the option table. + pub(crate) fn has_section(&self, section: impl AsRef<str>) -> bool { + self.modules.iter().any(|(m, _)| m.as_str() == section.as_ref()) + } + + /// Get a section of the table in mutable access. If the section doesn't exist it will be + /// created and will be empty. + pub(crate) fn section_mut(&mut self, section: impl Into<ShortString>) -> OptionTableSectionMut<'_> { + let section = section.into(); + let mut sections = self.modules.iter().enumerate(); + let idx = sections + .find_map(|(idx, (module, _))| (*module == section).then_some(idx)) + .unwrap_or_else(|| { + self.modules.push((section, vec![])); + self.modules.len() - 1 + }); + OptionTableSectionMut::new(&mut self.modules[idx].1) + } +} + +impl<'a> OptionTableSectionMut<'a> { + fn new(options: &'a mut Vec<(ShortString, Expression)>) -> Self { + Self { options } + } +} + +impl<'a> Iterator for OptionTableSectionMut<'a> { + type Item = (ShortString, Expression); + + fn next(&mut self) -> Option<Self::Item> { + self.options.pop() + } +} + +impl<'a> Extend<(ShortString, Expression)> for OptionTableSectionMut<'a> { + fn extend<T: IntoIterator<Item = (ShortString, Expression)>>(&mut self, iter: T) { + self.options.extend(iter) + } +} + +impl Iterator for OptionTable { + type Item = (ShortString, ShortString, Expression); + + fn next(&mut self) -> Option<Self::Item> { + let (module, mut section) = self + .modules + .iter_mut() + .find(|(_, opts)| !opts.is_empty()) + .map(|(module, section)| (module, OptionTableSectionMut::new(section)))?; + let (option, expression) = section.next().unwrap(); + Some((module.clone(), option, expression)) + } + + fn size_hint(&self) -> (usize, Option<usize>) { + let count = self.len(); + (count, Some(count)) + } + + fn count(self) -> usize { + self.len() + } +} diff --git a/src/Rust/vvs_parser/src/ast/parsers/mod.rs b/src/Rust/vvs_parser/src/ast/parsers/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..1e79a07d0b6b716f454d737ebf48aa74787697b7 --- /dev/null +++ b/src/Rust/vvs_parser/src/ast/parsers/mod.rs @@ -0,0 +1,2172 @@ +//! Contains things for the parsers. Parse the vvs/vvl files and the option file. + +mod structs; +mod util; + +use crate::{ + ast::{ + self, + punctuated::{Pair, Punctuated}, + span::ContainedSpan, + CallList, Expression, FunctionBody, Parameter, + }, + node::Node, + tokenizer::{Symbol, Token, TokenKind, TokenReference, TokenType}, + try_parser, +}; + +pub use crate::ast::parsers::structs::*; + +pub fn parse_option_table(state: &mut ParserState) -> ParserResult<ast::OptionTable> { + let mut table = ast::OptionTable::default(); + + while let ParserResult::Value(left_bracket) = state.consume() { + let section = match left_bracket.token_type() { + TokenType::MultiLineComment { .. } | TokenType::SingleLineComment { .. } => continue, + TokenType::Eof => break, + TokenType::Symbol { symbol: Symbol::LeftBracket } => expect_option_table_section(state, left_bracket), + _ => todo!("error"), + }; + + let (identifier, options) = match section { + ParserResult::NotFound => break, + ParserResult::Value(( + TokenReference { token: Token { token_type: TokenType::Identifier { identifier, .. }, .. }, .. }, + options, + )) => (identifier, options), + _ => return ParserResult::LexerMoved, + }; + + table + .section_mut(identifier) + .extend(options.into_iter().flat_map(|(option, value)| match option { + TokenReference { + token: Token { token_type: TokenType::Identifier { identifier, .. }, .. }, .. + } => Some((identifier, value)), + _ => None, + })); + } + + ParserResult::Value(table) +} + +fn expect_option_table_section( + state: &mut ParserState, + left_bracket: TokenReference, +) -> ParserResult<(TokenReference, Vec<(TokenReference, Expression)>)> { + let section = match parse_identifier(state) { + ParserResult::Value(section) => section, + _ => { + state.token_error(left_bracket, "expected an identifier as the option section name"); + return ParserResult::LexerMoved; + } + }; + + if state.consume_if(Symbol::RightBracket).is_none() { + state.token_error(section, "expected a ']' to close after the section name declaration"); + return ParserResult::LexerMoved; + } + + let mut options = Vec::new(); + while let Ok(current) = state.current() { + match current.token_type() { + TokenType::Eof | TokenType::Symbol { symbol: Symbol::LeftBracket } => break, + TokenType::Identifier { .. } => {} + _ => { + state.token_error(current.clone(), "expected the name of an option"); + return ParserResult::LexerMoved; + } + } + let option = state.consume().unwrap(); + + let separator = match state.consume_ifs(&[Symbol::Equal, Symbol::Colon]) { + Some(separator) => separator, + None => { + state.token_error(option, "expected a ':' or a '=' to assign the option"); + return ParserResult::LexerMoved; + } + }; + + let expression = match parse_expression(state) { + ParserResult::Value(expression) => expression, + ParserResult::LexerMoved | ParserResult::NotFound => { + state.token_error(separator, "expected an expression as the option value"); + return ParserResult::LexerMoved; + } + }; + + options.push((option, expression)); + } + + ParserResult::Value((section, options)) +} + +pub fn parse_block(state: &mut ParserState) -> ParserResult<ast::Block> { + let mut stmts = Vec::new(); + + loop { + match parse_stmt(state) { + ParserResult::Value(StmtVariant::Stmt(stmt)) => { + stmts.push((stmt, state.consume_if(Symbol::Semicolon))); + } + ParserResult::Value(StmtVariant::LastStmt(last_stmt)) => { + let semicolon = state.consume_if(Symbol::Semicolon); + let last_stmt = Some((last_stmt, semicolon)); + return ParserResult::Value(ast::Block { stmts, last_stmt }); + } + ParserResult::NotFound => break, + ParserResult::LexerMoved if stmts.is_empty() => return ParserResult::LexerMoved, + ParserResult::LexerMoved => break, + } + } + + let last_stmt = parse_last_stmt(state).ok(); + ParserResult::Value(ast::Block { stmts, last_stmt }) +} + +// Blocks in general are not very fallible. This means, for instance, not finishing `function()` +// will result in a completely ignored function body. +// This is an opinionated choice because I believe selene is going to produce terrible outputs if we don't. +fn expect_block_with_end( + state: &mut ParserState, + name: &str, + start_for_errors: &TokenReference, +) -> Result<(ast::Block, TokenReference), ()> { + let block = match parse_block(state) { + ParserResult::Value(block) => block, + ParserResult::NotFound => unreachable!("parse_block should always return a value"), + ParserResult::LexerMoved => return Err(()), + }; + + let (start, end) = if let Some(last_stmt) = block.last_stmt() { + let mut tokens = last_stmt.tokens(); + let start = tokens.next().unwrap(); + let end = tokens.last().unwrap_or(start); + (start, end) + } else if let Some(the_last_of_the_stmts) = block.stmts().last() { + let mut tokens = the_last_of_the_stmts.tokens(); + let start = tokens.next().unwrap(); + let end = tokens.last().unwrap_or(start); + (start, end) + } else { + (start_for_errors, start_for_errors) + }; + + let Some(end_token) = state.require_with_reference_range( + Symbol::End, + || format!("expected `end` to close {} block", name), + start, + end, + ) else { + return Ok((block, TokenReference::basic_symbol("end"))); + }; + + Ok((block, end_token)) +} + +enum StmtVariant { + Stmt(ast::Stmt), + + // Used for things like Luau's `continue`, but nothing constructs it in Lua 5.1 alone. + #[allow(unused)] + LastStmt(ast::LastStmt), +} + +fn parse_stmt(state: &mut ParserState) -> ParserResult<StmtVariant> { + let Ok(current_token) = state.current() else { + return ParserResult::NotFound; + }; + + match current_token.token_type() { + TokenType::Symbol { symbol: Symbol::Local } => { + let local_token = state.consume().unwrap(); + let next_token = match state.current() { + Ok(token) => token, + Err(()) => return ParserResult::LexerMoved, + }; + + match next_token.token_type() { + TokenType::Identifier { .. } => ParserResult::Value(StmtVariant::Stmt(ast::Stmt::LocalAssignment( + match expect_local_assignment(state, local_token) { + Ok(local_assignment) => local_assignment, + Err(()) => return ParserResult::LexerMoved, + }, + ))), + + TokenType::Symbol { symbol: Symbol::Function } => { + let callable_token = state.consume().unwrap(); + let name = match state.current() { + Ok(token) if token.token_kind() == TokenKind::Identifier => state.consume().unwrap(), + Ok(token) => { + state.token_error(token.clone(), "expected a function name"); + return ParserResult::LexerMoved; + } + Err(()) => return ParserResult::LexerMoved, + }; + + let body = match parse_function_body(state) { + ParserResult::Value(function_body) => function_body, + ParserResult::NotFound => { + state.token_error(callable_token, "expected a function body"); + return ParserResult::LexerMoved; + } + ParserResult::LexerMoved => return ParserResult::LexerMoved, + }; + + ParserResult::Value(StmtVariant::Stmt(ast::Stmt::LocalFunction(ast::LocalFunction { + local_token, + function_token: callable_token, + name, + body, + }))) + } + + _ => { + state.token_error(next_token.clone(), "expected either a variable name or `function`"); + ParserResult::LexerMoved + } + } + } + + TokenType::Symbol { symbol: Symbol::For } => { + let for_token = state.consume().unwrap(); + ParserResult::Value(StmtVariant::Stmt(match expect_for_stmt(state, for_token) { + Ok(for_stmt) => for_stmt, + Err(()) => return ParserResult::LexerMoved, + })) + } + + TokenType::Symbol { symbol: Symbol::Option } => { + let option_token = state.consume().unwrap(); + ParserResult::Value(StmtVariant::Stmt(ast::Stmt::OptionDecl( + match expect_option_decl(state, option_token) { + Ok(option_decl_stmt) => option_decl_stmt, + Err(()) => return ParserResult::LexerMoved, + }, + ))) + } + + TokenType::Symbol { symbol: Symbol::Yield } => { + let yield_token = state.consume().unwrap(); + ParserResult::Value(StmtVariant::Stmt(ast::Stmt::Yield(match expect_yield(state, yield_token) { + Ok(yield_stmt) => yield_stmt, + Err(()) => return ParserResult::LexerMoved, + }))) + } + + TokenType::Symbol { symbol: Symbol::Main } => { + let main_token = state.consume().unwrap(); + ParserResult::Value(StmtVariant::Stmt(ast::Stmt::Main(match expect_main(state, main_token) { + Ok(main_stmt) => main_stmt, + Err(()) => return ParserResult::LexerMoved, + }))) + } + + TokenType::Symbol { symbol: Symbol::Do } => { + let do_token = state.consume().unwrap(); + let (block, end_token) = match expect_block_with_end(state, "do", &do_token) { + Ok(block) => block, + Err(()) => return ParserResult::LexerMoved, + }; + ParserResult::Value(StmtVariant::Stmt(ast::Stmt::Do(ast::Do { do_token, block, end_token }))) + } + + TokenType::Symbol { symbol: Symbol::If } => { + let if_token = state.consume().unwrap(); + ParserResult::Value(StmtVariant::Stmt(ast::Stmt::If(match expect_if_stmt(state, if_token) { + Ok(if_stmt) => if_stmt, + Err(()) => return ParserResult::LexerMoved, + }))) + } + + TokenType::Symbol { symbol: Symbol::Import } => { + let import_token = state.consume().unwrap(); + let name = match state.current() { + Ok(token) if token.token_kind() == TokenKind::StringLiteral => state.consume().unwrap(), + Ok(token) => { + state.token_error(token.clone(), "expected a string as the module name"); + return ParserResult::LexerMoved; + } + Err(()) => return ParserResult::LexerMoved, + }; + ParserResult::Value(StmtVariant::Stmt(ast::Stmt::Import(ast::Import { import_token, name }))) + } + + TokenType::Symbol { symbol: callable @ Symbol::Function | callable @ Symbol::Job } => { + let callable = *callable; + let token = state.consume().unwrap(); + let declaration = match expect_function_declaration(state, token) { + Ok(declaration) => declaration, + Err(()) => return ParserResult::LexerMoved, + }; + let job_name_is_invalid = { + let name = declaration.name(); + name.names().len() != 1 || name.method_colon().is_some() || name.method_name().is_some() + }; + match callable { + Symbol::Job if job_name_is_invalid => { + state.token_error( + declaration.function_token().clone(), + "invalid name for a job, can't be ponctuated or have columns", + ); + ParserResult::LexerMoved + } + Symbol::Job => ParserResult::Value(StmtVariant::Stmt(ast::Stmt::JobDeclaration(declaration))), + Symbol::Function => ParserResult::Value(StmtVariant::Stmt(ast::Stmt::FunctionDeclaration(declaration))), + _ => unreachable!(), + } + } + + TokenType::Symbol { symbol: Symbol::Repeat } => { + let repeat_token = state.consume().unwrap(); + ParserResult::Value(StmtVariant::Stmt(match expect_repeat_stmt(state, repeat_token) { + Ok(repeat_stmt) => repeat_stmt, + Err(()) => return ParserResult::LexerMoved, + })) + } + + TokenType::Symbol { symbol: Symbol::While } => { + let while_token = state.consume().unwrap(); + ParserResult::Value(StmtVariant::Stmt(ast::Stmt::While(match expect_while_stmt(state, while_token) { + Ok(while_stmt) => while_stmt, + Err(()) => return ParserResult::LexerMoved, + }))) + } + + TokenType::Symbol { symbol: Symbol::LeftParen } | TokenType::Identifier { .. } => { + let (prefix, suffixes) = + try_parser!(parse_prefix_and_suffixes(state)).expect("we should always be starting on the right path"); + let var = match suffixes.last() { + Some(ast::Suffix::Call(_)) => { + return ParserResult::Value(StmtVariant::Stmt(ast::Stmt::FunctionCall(ast::FunctionCall { + prefix, + suffixes, + }))); + } + Some(ast::Suffix::Index(_)) => ast::Var::Expression(Box::new(ast::VarExpression { prefix, suffixes })), + None => match prefix { + ast::Prefix::Name(name) => ast::Var::Name(name), + // I think this only happens in error cases + prefix @ ast::Prefix::Expression(_) => { + ast::Var::Expression(Box::new(ast::VarExpression { prefix, suffixes })) + } + }, + }; + + match state.current() { + // Compound Assignment + Ok(token) + if token.in_symbols(&[ + Symbol::PlusEqual, + Symbol::MinusEqual, + Symbol::StarEqual, + Symbol::SlashEqual, + Symbol::DoubleSlashEqual, + Symbol::PercentEqual, + Symbol::CaretEqual, + Symbol::TwoDotsEqual, + ]) => + { + let compound_operator = state.consume().unwrap(); + let ParserResult::Value(expr) = parse_expression(state) else { + state.token_error(compound_operator, "expected expression to set to"); + return ParserResult::LexerMoved; + }; + return ParserResult::Value(StmtVariant::Stmt(ast::Stmt::CompoundAssignment( + ast::CompoundAssignment { + lhs: var, + compound_operator: ast::CompoundOp::from_token(compound_operator), + rhs: expr, + }, + ))); + } + + Ok(token) if token.in_symbols(&[Symbol::Comma, Symbol::Equal]) => {} + + Ok(token) => { + // Check if the consumed token is a potential context-sensitive keyword + if let ast::Var::Name(token) = var { + match token.token_type() { + TokenType::Identifier { identifier } if identifier.as_str() == "type" => { + let type_token = token; + return ParserResult::Value(StmtVariant::Stmt(ast::Stmt::TypeDeclaration( + match expect_type_declaration(state, type_token) { + Ok(type_declaration) => type_declaration, + Err(()) => return ParserResult::LexerMoved, + }, + ))); + } + TokenType::Identifier { identifier } if identifier.as_str() == "continue" => { + let continue_token = token; + return ParserResult::Value(StmtVariant::LastStmt(ast::LastStmt::Continue( + continue_token, + ))); + } + _ => (), + } + } + + state.token_error(token.clone(), "unexpected expression when looking for a statement"); + return ParserResult::LexerMoved; + } + + Err(()) => return ParserResult::LexerMoved, + }; + + let mut var_list = Punctuated::new(); + var_list.push(Pair::End(var)); + + loop { + let next_comma = match state.current() { + Ok(token) if token.is_symbol(Symbol::Comma) => state.consume().unwrap(), + Ok(_) => break, + Err(()) => return ParserResult::LexerMoved, + }; + + let (next_prefix, next_suffixes) = match parse_prefix_and_suffixes(state) { + ParserResult::Value((prefix, suffixes)) => (prefix, suffixes), + ParserResult::LexerMoved => break, + ParserResult::NotFound => { + state.token_error(next_comma, "expected another variable"); + break; + } + }; + + match next_suffixes.last() { + Some(ast::Suffix::Call(call)) => { + state + .token_error(call.tokens().last().unwrap().clone(), "can't assign to the result of a call"); + break; + } + + Some(ast::Suffix::Index(_)) => var_list.push_punctuated( + ast::Var::Expression(Box::new(ast::VarExpression { + prefix: next_prefix, + suffixes: next_suffixes, + })), + next_comma, + ), + + None => match next_prefix { + ast::Prefix::Name(name) => var_list.push_punctuated(ast::Var::Name(name), next_comma), + prefix @ ast::Prefix::Expression(_) => var_list.push_punctuated( + ast::Var::Expression(Box::new(ast::VarExpression { prefix, suffixes: next_suffixes })), + next_comma, + ), + }, + } + } + + let Some(equal_token) = state.require(Symbol::Equal, "expected `=` after name") else { + return ParserResult::LexerMoved; + }; + + let expr_list = match parse_expression_list(state) { + ParserResult::Value(expr_list) => expr_list, + ParserResult::NotFound => { + state.token_error(equal_token.clone(), "expected values to set to"); + Punctuated::new() + } + ParserResult::LexerMoved => Punctuated::new(), + }; + + ParserResult::Value(StmtVariant::Stmt(ast::Stmt::Assignment(ast::Assignment { + var_list, + equal_token, + expr_list, + }))) + } + + _ => ParserResult::NotFound, + } +} + +fn parse_last_stmt(state: &mut ParserState) -> ParserResult<(ast::LastStmt, Option<TokenReference>)> { + let last_stmt = match state.current() { + Ok(token) if token.is_symbol(Symbol::Return) => { + let return_token = state.consume().unwrap(); + let expr_list = match parse_expression_list(state) { + ParserResult::Value(expr_list) => expr_list, + ParserResult::LexerMoved | ParserResult::NotFound => Punctuated::new(), + }; + ast::LastStmt::Return(ast::Return { token: return_token, returns: expr_list }) + } + + Ok(token) if token.is_symbol(Symbol::Break) => { + let break_token = state.consume().unwrap(); + ast::LastStmt::Break(break_token) + } + + _ => return ParserResult::NotFound, + }; + + let semicolon = state.consume_if(Symbol::Semicolon); + ParserResult::Value((last_stmt, semicolon)) +} + +fn expect_function_name(state: &mut ParserState) -> ParserResult<ast::FunctionName> { + let mut names = Punctuated::new(); + let name = match state.current() { + Ok(token) if matches!(token.token_type(), TokenType::Identifier { .. }) => state.consume().unwrap(), + Ok(token) => { + state.token_error(token.clone(), "expected function name"); + return ParserResult::NotFound; + } + Err(()) => return ParserResult::NotFound, + }; + + names.push(Pair::End(name)); + + loop { + let middle_token = match state.current() { + Ok(token) if token.in_symbols(&[Symbol::Colon, Symbol::Dot]) => state.consume().unwrap(), + Ok(_) => break, + Err(()) => return ParserResult::LexerMoved, + }; + + let name = match state.current() { + Ok(token) if matches!(token.token_type(), TokenType::Identifier { .. }) => state.consume().unwrap(), + Ok(token) => { + state.token_error(token.clone(), format!("expected name after `{}`", middle_token.token())); + return ParserResult::NotFound; + } + Err(()) => return ParserResult::LexerMoved, + }; + + if middle_token.is_symbol(Symbol::Dot) { + names.push_punctuated(name, middle_token); + } else if middle_token.is_symbol(Symbol::Colon) { + return ParserResult::Value(ast::FunctionName { names, colon_name: Some((middle_token, name)) }); + } else { + unreachable!(); + } + } + + ParserResult::Value(ast::FunctionName { names, colon_name: None }) +} + +fn expect_function_declaration( + state: &mut ParserState, + function_token: TokenReference, +) -> Result<ast::FunctionDeclaration, ()> { + let function_name = expect_function_name(state).ok_or(())?; + let function_body = match parse_function_body(state) { + ParserResult::Value(body) => body, + ParserResult::LexerMoved => ast::FunctionBody::new(), + ParserResult::NotFound => { + state.token_error(function_token.clone(), "expected a function body"); + ast::FunctionBody::new() + } + }; + Ok(ast::FunctionDeclaration { function_token, name: function_name, body: function_body }) +} + +fn expect_for_stmt(state: &mut ParserState, for_token: TokenReference) -> Result<ast::Stmt, ()> { + let name_list = match parse_name_list(state) { + ParserResult::Value(name_list) => name_list, + ParserResult::NotFound => { + state.token_error(for_token, "expected name after `for`"); + return Err(()); + } + ParserResult::LexerMoved => return Err(()), + }; + + let current_token = state.current()?; + debug_assert!(!name_list.is_empty()); + + if name_list.len() == 1 && current_token.is_symbol(Symbol::Equal) { + return Ok(ast::Stmt::NumericFor(expect_numeric_for_stmt( + state, + for_token, + name_list.into_iter().next().unwrap(), + )?)); + } + + let in_token = match current_token { + token if token.is_symbol(Symbol::In) => state.consume().unwrap(), + token => { + state.token_error(token.clone(), "expected `in` after name list"); + return Err(()); + } + }; + + let expressions = match parse_expression_list(state) { + ParserResult::Value(expressions) => expressions, + ParserResult::NotFound => { + state.token_error(in_token, "expected expressions after `in`"); + return Err(()); + } + ParserResult::LexerMoved => return Err(()), + }; + + let Some(do_token) = state.require(Symbol::Do, "expected `do` after expression list") else { + return Ok(ast::Stmt::GenericFor(ast::GenericFor { + for_token, + names: name_list + .clone() + .into_pairs() + .map(|pair| pair.map(|name| name.name)) + .collect(), + type_specifiers: name_list.into_iter().map(|name| name.type_specifier).collect(), + in_token, + expr_list: expressions, + do_token: TokenReference::basic_symbol("do"), + block: ast::Block::new(), + end_token: TokenReference::basic_symbol("end"), + })); + }; + + let (block, end) = match expect_block_with_end(state, "for loop", &do_token) { + Ok(block) => block, + Err(()) => (ast::Block::new(), TokenReference::basic_symbol("end")), + }; + + Ok(ast::Stmt::GenericFor(ast::GenericFor { + for_token, + names: name_list + .clone() + .into_pairs() + .map(|pair| pair.map(|name| name.name)) + .collect(), + type_specifiers: name_list.into_iter().map(|name| name.type_specifier).collect(), + in_token, + expr_list: expressions, + do_token, + block, + end_token: end, + })) +} + +fn expect_numeric_for_stmt( + state: &mut ParserState, + for_token: TokenReference, + index_variable: Name, +) -> Result<ast::NumericFor, ()> { + let equal_token = state.consume().unwrap(); + debug_assert!(equal_token.is_symbol(Symbol::Equal)); + + let start = match parse_expression(state) { + ParserResult::Value(start) => start, + ParserResult::NotFound => { + state.token_error(equal_token, "expected start expression after `=`"); + return Err(()); + } + ParserResult::LexerMoved => return Err(()), + }; + + let start_end_comma = state + .require(Symbol::Comma, "expected `,` after start expression") + .ok_or(())?; + + let end = match parse_expression(state) { + ParserResult::Value(end) => end, + ParserResult::NotFound => { + state.token_error(start_end_comma, "expected end expression after `,`"); + return Err(()); + } + ParserResult::LexerMoved => return Err(()), + }; + + // rewrite todo: this can recover into a numeric for loop with no step (or simulate the do..end) + let (end_step_comma, step) = match state.consume_if(Symbol::Comma) { + Some(end_step_comma) => match parse_expression(state) { + ParserResult::Value(step) => (Some(end_step_comma), Some(step)), + ParserResult::NotFound => { + state.token_error(start_end_comma, "expected step expression after `,`"); + return Err(()); + } + ParserResult::LexerMoved => return Err(()), + }, + + None => (None, None), + }; + + let do_token = state + .require(Symbol::Do, "expected `do` after step expression") + .ok_or(())?; + + let (block, end_token) = match expect_block_with_end(state, "numeric for loop", &do_token) { + Ok(block) => block, + Err(()) => (ast::Block::new(), TokenReference::basic_symbol("end")), + }; + + Ok(ast::NumericFor { + for_token, + index_variable: index_variable.name, + type_specifier: index_variable.type_specifier, + equal_token, + start, + start_end_comma, + end, + end_step_comma, + step, + do_token, + block, + end_token, + }) +} + +fn expect_if_stmt(state: &mut ParserState, if_token: TokenReference) -> Result<ast::If, ()> { + let condition = match parse_expression(state) { + ParserResult::Value(condition) => condition, + ParserResult::NotFound => { + state.token_error(if_token, "expected condition after `if`"); + return Err(()); + } + ParserResult::LexerMoved => return Err(()), + }; + + let then_token = state + .require(Symbol::Then, "expected `then` after condition") + .ok_or(())?; + + let then_block = match parse_block(state) { + ParserResult::Value(block) => block, + ParserResult::NotFound => { + state.token_error(then_token, "expected block after `then`"); + return Ok(ast::If::new(condition)); + } + ParserResult::LexerMoved => return Ok(ast::If::new(condition)), + }; + + let mut else_if = Vec::new(); + + let else_if_optional = |else_if: Vec<ast::ElseIf>| (!else_if.is_empty()).then_some(else_if); + let unfinished_if = |condition, else_if| Ok(ast::If::new(condition).with_else_if(else_if_optional(else_if))); + + loop { + let else_if_token = match state.current() { + Ok(else_if_token) if else_if_token.in_symbols(&[Symbol::ElseIf, Symbol::ElIf]) => state.consume().unwrap(), + Ok(_) => break, + Err(()) => return unfinished_if(condition, else_if), + }; + + let condition = match parse_expression(state) { + ParserResult::Value(condition) => condition, + ParserResult::NotFound => { + state.token_error(else_if_token, "expected condition after `elseif` or `elif`"); + return unfinished_if(condition, else_if); + } + ParserResult::LexerMoved => return unfinished_if(condition, else_if), + }; + + let Some(then_token) = state.require(Symbol::Then, "expected `then` after condition") else { + return unfinished_if(condition, else_if); + }; + + let then_block = match parse_block(state) { + ParserResult::Value(block) => block, + ParserResult::NotFound => { + state.token_error(then_token, "expected block after `then`"); + return unfinished_if(condition, else_if); + } + ParserResult::LexerMoved => return unfinished_if(condition, else_if), + }; + + else_if.push(ast::ElseIf { else_if_token, condition, then_token, block: then_block }); + } + + let (else_block, else_token) = match state.consume_if(Symbol::Else) { + Some(else_token) => match parse_block(state) { + ParserResult::Value(block) => (Some(block), Some(else_token)), + ParserResult::NotFound => { + state.token_error(else_token.clone(), "expected block after `else`"); + (Some(ast::Block::new()), Some(else_token)) + } + ParserResult::LexerMoved => (Some(ast::Block::new()), Some(else_token)), + }, + None => (None, None), + }; + + let end_token = match state.current() { + Ok(token) if token.is_symbol(Symbol::End) => state.consume().unwrap(), + Ok(token) => { + state.token_error(token.clone(), "expected `end` to conclude `if`"); + TokenReference::basic_symbol("end") + } + Err(()) => TokenReference::basic_symbol("end"), + }; + + Ok(ast::If { + if_token, + condition, + then_token, + block: then_block, + else_if: else_if_optional(else_if), + else_token, + r#else: else_block, + end_token, + }) +} + +fn expect_yield(state: &mut ParserState, yield_token: TokenReference) -> Result<ast::Yield, ()> { + match parse_expression_list(state) { + ParserResult::Value(expr_list) => Ok(ast::Yield::new().with_token(yield_token).with_yields(expr_list)), + ParserResult::LexerMoved | ParserResult::NotFound => { + state.token_error(yield_token, "expected an expression to yield"); + Err(()) + } + } +} + +fn expect_main(state: &mut ParserState, main_token: TokenReference) -> Result<ast::Main, ()> { + let initial_variable = state.consume_kind(TokenKind::StringLiteral).ok_or(())?; + + let begin_token = state + .require(Symbol::Do, "need to specify the instructions in a list") + .ok_or(())?; + + let mut assignements = Vec::new(); + let (end_token, write_stmt) = loop { + if let Some(end_token) = state.consume_if(Symbol::End) { + break (end_token, None); + } else if let Some(return_token) = state.consume_if(Symbol::Return) { + let write_stmt = expect_write_variable(state, return_token)?; + break state + .require(Symbol::End, "expected no more assignations after the return token") + .map(|end_token| (end_token, Some(write_stmt))) + .ok_or(())?; + } + assignements.push(expect_main_assign(state)?); + }; + + Ok(ast::Main::new(main_token, initial_variable, begin_token, end_token) + .with_assignements(assignements) + .with_returns(write_stmt)) +} + +fn expect_main_assign(state: &mut ParserState) -> Result<ast::MainAssignement, ()> { + let dest_token = state.consume_kind(TokenKind::StringLiteral).ok_or(())?; + let assign_token = state + .require(Symbol::Equal, "expected `=` to assign variable") + .ok_or(())?; + + let module = state.consume_kind(TokenKind::Identifier).ok_or(())?; + let dot_token = state + .require(Symbol::Dot, "expected a dot `.` to get which job from the module to call") + .ok_or(())?; + let the_job = state.consume_kind(TokenKind::Identifier).ok_or(())?; + + let call_list = expect_call_list(state) + .map_err(|()| state.token_error(the_job.clone(), "expected a call list to know how to call the job"))?; + + Ok(ast::MainAssignement::new(assign_token, dest_token, module, dot_token, the_job).with_call_list(call_list)) +} + +fn expect_call_list(state: &mut ParserState) -> Result<ast::CallList, ()> { + let current = state.current()?; + + let mut items = Punctuated::new(); + let (mut start_list_token, mut end_list_token) = (None, None); + match current.token_type() { + TokenType::StringLiteral { .. } => items.push(Pair::End(ast::CallListItem::Variable(state.consume().unwrap()))), + + TokenType::Symbol { symbol: Symbol::LeftBrace } => { + start_list_token = state.consume().ok(); + while let Ok(token) = state.current() { + let next_item = match token.token_type() { + TokenType::StringLiteral { .. } => ast::CallListItem::Variable(state.consume().unwrap()), + + TokenType::Identifier { .. } => { + let parameter = state.consume().unwrap(); + let equal_token = state.consume_if(Symbol::Equal).ok_or_else(|| { + state.token_error(parameter.clone(), "expected an assignation with `=` for this parameter") + })?; + let expression = parse_expression(state).ok_or(())?; + ast::CallListItem::SetParameter { parameter, equal_token, expression } + } + + _ => { + state.token_error( + token.clone(), + "expected a string literal to name a parameter or an assignation", + ); + return Err(()); + } + }; + + if let Some(comma_token) = state.consume_if(Symbol::Comma) { + items.push(Pair::Punctuated(next_item, comma_token)); + continue; + } else if let Some(end_token) = state.consume_if(Symbol::RightBrace) { + items.push(Pair::End(next_item)); + end_list_token = Some(end_token); + break; + } + + let error_token = state.consume().unwrap_or_else(|| next_item.first_token().clone()); + state.token_error( + error_token, + "expected symbol '}' or ',' after the variable name or a parameter assignation", + ); + return Err(()); + } + } + _ => { + state.token_error(current.clone(), "expected a call list for the job"); + return Err(()); + } + } + + Ok(CallList::new() + .with_begin_token(start_list_token) + .with_end_token(end_list_token) + .with_items(items)) +} + +fn expect_write_variable(state: &mut ParserState, write_token: TokenReference) -> Result<ast::Write, ()> { + let Ok(current) = state.current() else { + state.token_error(write_token, "expected something to write"); + return Err(()); + }; + + let mut variables = Punctuated::new(); + let (mut start_list_token, mut end_list_token) = (None, None); + match current.token_type() { + TokenType::StringLiteral { .. } => variables.push(Pair::End(state.consume().unwrap())), + + TokenType::Symbol { symbol: Symbol::LeftBrace } => { + start_list_token = state.consume().ok(); + while let Ok(token) = state.current() { + let next_variable = match token.token_kind() { + TokenKind::StringLiteral => state.consume().unwrap(), + _ => { + state.token_error(token.clone(), "expected a string literal to name a variable"); + return Err(()); + } + }; + + if let Some(comma_token) = state.consume_if(Symbol::Comma) { + variables.push(Pair::Punctuated(next_variable, comma_token)); + continue; + } else if let Some(end_token) = state.consume_if(Symbol::RightBrace) { + variables.push(Pair::End(next_variable)); + end_list_token = Some(end_token); + break; + } + + let error_token = state.consume().unwrap_or(next_variable); + state.token_error(error_token, "expected '}' or ',' after the variable name"); + return Err(()); + } + } + + _ => { + state.token_error(current.clone(), "expected a variable name or a list of variable name"); + return Err(()); + } + } + + Ok(ast::Write::new(write_token) + .with_variables(variables) + .with_begin_list_token(start_list_token) + .with_end_list_token(end_list_token)) +} + +fn expect_option_decl(state: &mut ParserState, option_token: TokenReference) -> Result<ast::OptionDecl, ()> { + let mut name_list = Punctuated::<TokenReference>::new(); + let mut type_specifiers = Vec::<Option<ast::TypeSpecifier>>::new(); + + let equal_token = loop { + let name = match parse_identifier(state) { + ParserResult::Value(name) => name, + _ => { + state.token_error(state.current()?.clone(), "expected an identifier"); + return Err(()); + } + }; + + type_specifiers.push(match state.consume_if(Symbol::Colon) { + Some(colon) => Some(expect_type_specifier(state, colon)?), + None => None, + }); + + if let Some(comma) = state.consume_if(Symbol::Comma) { + name_list.push_punctuated(name, comma); + continue; + } else if let Some(equal) = state.consume_if(Symbol::Equal) { + name_list.push(Pair::End(name)); + break equal; + } + + state.token_error(option_token, "invalid option specifier statement"); + state.token_error( + state.current().cloned()?, + "expected ',' to continue option list or '=' to assign default values to the list", + ); + return Err(()); + }; + + debug_assert_eq!(name_list.len(), type_specifiers.len()); + + let expr_list = match parse_expression_list(state) { + ParserResult::Value(expr_list) if name_list.len() != expr_list.len() => { + state.token_error(option_token, "expected to assign all declared options"); + return Err(()); + } + ParserResult::NotFound => { + state.token_error(equal_token.clone(), "expected an expression"); + return Err(()); + } + ParserResult::LexerMoved => return Err(()), + ParserResult::Value(expr_list) => expr_list, + }; + + Ok(ast::OptionDecl { option_token, name_list, type_specifiers, equal_token, expr_list }) +} + +fn expect_local_assignment(state: &mut ParserState, local_token: TokenReference) -> Result<ast::LocalAssignment, ()> { + let names = match one_or_more(state, parse_name_with_attributes, Symbol::Comma) { + ParserResult::Value(names) => names, + ParserResult::NotFound => { + unreachable!("expect_local_assignment called without upcoming identifier"); + } + ParserResult::LexerMoved => return Err(()), + }; + + let mut name_list = Punctuated::new(); + let mut type_specifiers = Vec::new(); + let mut attributes = Vec::new(); + + for name in names.into_pairs() { + let (name, punctuation) = name.into_tuple(); + attributes.push(name.attribute); + type_specifiers.push(name.type_specifier); + name_list.push(match punctuation { + Some(punctuation) => Pair::Punctuated(name.name, punctuation), + None => Pair::End(name.name), + }); + } + + let mut local_assignment = ast::LocalAssignment { + local_token, + name_list, + type_specifiers, + equal_token: None, + expr_list: Punctuated::new(), + attributes, + }; + + local_assignment.equal_token = match state.consume_if(Symbol::Equal) { + Some(equal_token) => Some(equal_token), + None => return Ok(local_assignment), + }; + + match parse_expression_list(state) { + ParserResult::Value(expr_list) => local_assignment.expr_list = expr_list, + ParserResult::NotFound => { + state.token_error(local_assignment.equal_token.clone().unwrap(), "expected an expression") + } + ParserResult::LexerMoved => {} + }; + + Ok(local_assignment) +} + +fn expect_expression_key(state: &mut ParserState, left_bracket: TokenReference) -> Result<ast::Field, ()> { + let expression = match parse_expression(state) { + ParserResult::Value(expression) => expression, + ParserResult::NotFound => { + state.token_error(left_bracket, "expected an expression after `[`"); + return Err(()); + } + ParserResult::LexerMoved => return Err(()), + }; + + let right_bracket = state + .require_with_reference_range_callback(Symbol::RightBracket, "expected `]` after expression", || { + (left_bracket.clone(), expression.tokens().last().unwrap().clone()) + }) + .ok_or(())?; + + // rewrite todo: we can realistically construct a field in error recovery + // rewrite todo: this should also be range + let equal_token = state + .require_with_reference_range(Symbol::Equal, "expected `=` after expression", &left_bracket, &right_bracket) + .ok_or(())?; + + let value = match parse_expression(state) { + ParserResult::Value(expression) => expression, + ParserResult::NotFound => { + state.token_error(equal_token, "expected an expression after `=`"); + return Err(()); + } + ParserResult::LexerMoved => return Err(()), + }; + + Ok(ast::Field::ExpressionKey { + brackets: ContainedSpan::new(left_bracket, right_bracket), + key: expression, + equal: equal_token, + value, + }) +} + +fn force_table_constructor(state: &mut ParserState, left_brace: TokenReference) -> ast::TableConstructor { + let mut fields = Punctuated::new(); + let unfinished_table = |left_brace: TokenReference, fields: Punctuated<ast::Field>| ast::TableConstructor { + braces: ContainedSpan::new(left_brace, TokenReference::basic_symbol("}")), + fields, + }; + + loop { + let Ok(current_token) = state.current() else { + return unfinished_table(left_brace, fields); + }; + + let field = match current_token.token_type() { + TokenType::Symbol { symbol: Symbol::RightBrace } => { + return ast::TableConstructor { + braces: ContainedSpan::new(left_brace, state.consume().unwrap()), + fields, + } + } + + TokenType::Symbol { symbol: Symbol::LeftBracket } => { + let left_bracket = state.consume().unwrap(); + match expect_expression_key(state, left_bracket) { + Ok(field) => field, + Err(()) => return unfinished_table(left_brace, fields), + } + } + + TokenType::Identifier { .. } if matches!(state.peek(), Ok(peek_token) if peek_token.is_symbol(Symbol::Equal)) => + { + let key = state.consume().unwrap(); + let equal_token = state.consume().unwrap(); + let value = match parse_expression(state) { + ParserResult::Value(expression) => expression, + ParserResult::NotFound => { + state.token_error(equal_token, "expected an expression after `=`"); + return unfinished_table(left_brace, fields); + } + ParserResult::LexerMoved => return unfinished_table(left_brace, fields), + }; + ast::Field::NameKey { key, equal: equal_token, value } + } + + _ => ast::Field::NoKey(match parse_expression(state) { + ParserResult::Value(expression) => expression, + ParserResult::NotFound => { + state.token_error( + match fields.last() { + Some(Pair::End(field)) => field.tokens().last().unwrap().clone(), + Some(Pair::Punctuated(field, _)) => field.tokens().last().unwrap().clone(), + None => left_brace.clone(), + }, + "expected a field", + ); + return unfinished_table(left_brace, fields); + } + ParserResult::LexerMoved => return unfinished_table(left_brace, fields), + }), + }; + + match state.current() { + Ok(token) => { + if token.in_symbols(&[Symbol::Comma, Symbol::Semicolon]) { + fields.push(Pair::Punctuated(field, state.consume().unwrap())) + } else { + fields.push(Pair::End(field)); + break; + } + } + + Err(()) => { + fields.push(Pair::End(field)); + break; + } + }; + } + + let right_brace = match state.require(Symbol::RightBrace, "expected `}` after last field") { + Some(right_brace) => right_brace, + None => TokenReference::basic_symbol("}"), + }; + + ast::TableConstructor { braces: ContainedSpan::new(left_brace, right_brace), fields } +} + +fn expect_repeat_stmt(state: &mut ParserState, repeat_token: TokenReference) -> Result<ast::Stmt, ()> { + let block = match parse_block(state) { + ParserResult::Value(block) => block, + ParserResult::NotFound => { + state.token_error(repeat_token, "expected a block after `repeat`"); + return Err(()); + } + ParserResult::LexerMoved => return Err(()), + }; + + let Some(until_token) = state.require(Symbol::Until, "expected `until` after block") else { + return Ok(ast::Stmt::Do(ast::Do::new().with_block(block))); + }; + + let condition = match parse_expression(state) { + ParserResult::Value(expression) => expression, + ParserResult::NotFound => { + state.token_error(until_token, "expected a condition after `until`"); + return Ok(ast::Stmt::Do(ast::Do::new().with_block(block))); + } + ParserResult::LexerMoved => return Ok(ast::Stmt::Do(ast::Do::new().with_block(block))), + }; + + Ok(ast::Stmt::Repeat(ast::Repeat { repeat_token, block, until: condition, until_token })) +} + +fn expect_while_stmt(state: &mut ParserState, while_token: TokenReference) -> Result<ast::While, ()> { + let condition = match parse_expression(state) { + ParserResult::Value(expression) => expression, + ParserResult::NotFound => { + state.token_error(while_token, "expected a condition after `while`"); + return Err(()); + } + ParserResult::LexerMoved => return Err(()), + }; + + let Some(do_token) = state.require(Symbol::Do, "expected `do` after condition") else { + return Ok(ast::While::new(condition)); + }; + + let (block, end_token) = match expect_block_with_end(state, "while loop", &do_token) { + Ok((block, end_token)) => (block, end_token), + Err(()) => return Ok(ast::While::new(condition)), + }; + + Ok(ast::While { while_token, condition, do_token, block, end_token }) +} + +fn expect_type_declaration(state: &mut ParserState, type_token: TokenReference) -> Result<ast::TypeDeclaration, ()> { + let base = match state.current()? { + token if token.token_kind() == TokenKind::Identifier => state.consume().unwrap(), + token => { + state.token_error(token.clone(), "expected type name"); + // rewrite todo (in future if needed): maybe we can add an error name here to continue parsing? + return Err(()); + } + }; + + let equal_token = state + .require(Symbol::Equal, "expected `=` after type name") + .unwrap_or_else(|| TokenReference::basic_symbol("=")); + + let declare_as = parse_type(state).ok_or(())?; + + Ok(ast::TypeDeclaration { type_token, base, equal_token, declare_as }) +} + +fn parse_prefix(state: &mut ParserState) -> ParserResult<ast::Prefix> { + let current_token = match state.current() { + Ok(token) => token, + Err(()) => return ParserResult::NotFound, + }; + + match current_token.token_type() { + TokenType::Symbol { symbol: Symbol::LeftParen } => { + let left_parenthesis = state.consume().unwrap(); + let expression = Box::new(match try_parser!(parse_expression(state)) { + Some(expression) => expression, + None => { + state.token_error(left_parenthesis, "expected an expression after `(`"); + return ParserResult::LexerMoved; + } + }); + + let Some(right_parenthesis) = state.require(Symbol::RightParen, "expected `)` after expression") else { + return ParserResult::Value(ast::Prefix::Expression(Box::new(ast::Expression::Parentheses { + contained: ContainedSpan::new(left_parenthesis, TokenReference::basic_symbol(")")), + expression, + }))); + }; + + ParserResult::Value(ast::Prefix::Expression(Box::new(ast::Expression::Parentheses { + contained: ContainedSpan::new(left_parenthesis, right_parenthesis), + expression, + }))) + } + + TokenType::Identifier { .. } => ParserResult::Value(ast::Prefix::Name(state.consume().unwrap())), + + _ => ParserResult::NotFound, + } +} + +fn parse_arguments(state: &mut ParserState) -> ParserResult<ast::FunctionArgs> { + let Ok(current) = state.current() else { + return ParserResult::NotFound; + }; + + match current.token_type() { + TokenType::Symbol { symbol: Symbol::LeftParen } => { + let left_parenthesis = state.consume().unwrap(); + let arguments = try_parser!(parse_expression_list(state)).unwrap_or_default(); + let right_parenthesis = match state.require_with_reference_token( + Symbol::RightParen, + "expected `)` to close function call", + &left_parenthesis, + ) { + Some(token) => token, + None => TokenReference::basic_symbol(")"), + }; + + ParserResult::Value(ast::FunctionArgs::Parentheses { + parentheses: ContainedSpan::new(left_parenthesis, right_parenthesis), + arguments, + }) + } + + TokenType::Symbol { symbol: Symbol::LeftBrace } => { + let left_brace = state.consume().unwrap(); + ParserResult::Value(ast::FunctionArgs::TableConstructor(force_table_constructor(state, left_brace))) + } + + TokenType::StringLiteral { .. } => ParserResult::Value(ast::FunctionArgs::String(state.consume().unwrap())), + + _ => ParserResult::NotFound, + } +} + +fn parse_suffix(state: &mut ParserState) -> ParserResult<ast::Suffix> { + let Ok(current) = state.current() else { + return ParserResult::NotFound; + }; + + match current.token_type() { + TokenType::Symbol { symbol: Symbol::Dot } => { + let dot = state.consume().unwrap(); + let name = match state.current() { + Ok(token) if token.token_kind() == TokenKind::Identifier => state.consume().unwrap(), + Ok(_) => { + state.token_error(dot, "expected identifier after `.`"); + return ParserResult::LexerMoved; + } + Err(()) => return ParserResult::LexerMoved, + }; + + ParserResult::Value(ast::Suffix::Index(ast::Index::Dot { dot, name })) + } + + TokenType::Symbol { symbol: Symbol::LeftBracket } => { + let left_bracket = state.consume().unwrap(); + + let expression = match parse_expression(state) { + ParserResult::Value(expression) => expression, + ParserResult::LexerMoved => return ParserResult::LexerMoved, + ParserResult::NotFound => { + state.token_error(left_bracket, "expected expression after `[`"); + return ParserResult::LexerMoved; + } + }; + + let right_bracket = match state.require_with_reference_range( + Symbol::RightBracket, + "expected `]` to close index expression", + &left_bracket, + expression.tokens().last().unwrap(), + ) { + Some(right_bracket) => right_bracket, + None => TokenReference::basic_symbol("]"), + }; + + ParserResult::Value(ast::Suffix::Index(ast::Index::Brackets { + brackets: ContainedSpan::new(left_bracket, right_bracket), + expression, + })) + } + + TokenType::Symbol { symbol: Symbol::LeftParen | Symbol::LeftBrace } | TokenType::StringLiteral { .. } => { + let arguments = try_parser!(parse_arguments(state)).unwrap(); + ParserResult::Value(ast::Suffix::Call(ast::Call::AnonymousCall(arguments))) + } + + TokenType::Symbol { symbol: Symbol::Colon } => { + let colon_token = state.consume().unwrap(); + let name = match state.current() { + Ok(token) if token.token_kind() == TokenKind::Identifier => state.consume().unwrap(), + Ok(_) => { + state.token_error(colon_token, "expected identifier after `:`"); + return ParserResult::LexerMoved; + } + Err(()) => return ParserResult::LexerMoved, + }; + + let args = match parse_arguments(state) { + ParserResult::Value(args) => args, + ParserResult::LexerMoved => ast::FunctionArgs::empty(), + ParserResult::NotFound => { + state.token_error(name.clone(), "expected arguments after `:`"); + ast::FunctionArgs::empty() + } + }; + + ParserResult::Value(ast::Suffix::Call(ast::Call::MethodCall(ast::MethodCall { colon_token, name, args }))) + } + + _ => ParserResult::NotFound, + } +} + +fn parse_prefix_and_suffixes(state: &mut ParserState) -> ParserResult<(ast::Prefix, Vec<ast::Suffix>)> { + let prefix = match parse_prefix(state) { + ParserResult::Value(prefix) => prefix, + ParserResult::LexerMoved => return ParserResult::LexerMoved, + ParserResult::NotFound => return ParserResult::NotFound, + }; + let suffixes = std::iter::from_fn(|| parse_suffix(state).ok()).collect(); + ParserResult::Value((prefix, suffixes)) +} + +fn parse_expression(state: &mut ParserState) -> ParserResult<Expression> { + let primary_expression = match parse_primary_expression(state) { + ParserResult::Value(expression) => expression, + ParserResult::NotFound => return ParserResult::NotFound, + ParserResult::LexerMoved => return ParserResult::LexerMoved, + }; + parse_expression_with_precedence(state, primary_expression, 0) +} + +fn parse_primary_expression(state: &mut ParserState) -> ParserResult<Expression> { + let Ok(current_token) = state.current() else { + return ParserResult::NotFound; + }; + + let expression = match current_token.token_type() { + TokenType::Symbol { symbol: Symbol::Function } => { + let function_token = state.consume().unwrap(); + let function_body = match parse_function_body(state) { + ParserResult::Value(body) => body, + ParserResult::LexerMoved => return ParserResult::LexerMoved, + ParserResult::NotFound => { + state.token_error(function_token, "expected a function body"); + return ParserResult::LexerMoved; + } + }; + + ParserResult::Value(Expression::Function(Box::new((function_token, function_body)))) + } + + TokenType::Symbol { symbol: Symbol::True | Symbol::False | Symbol::Nil } => { + ParserResult::Value(Expression::Symbol(state.consume().unwrap())) + } + + TokenType::StringLiteral { .. } => ParserResult::Value(Expression::String(state.consume().unwrap())), + TokenType::Number { .. } => ParserResult::Value(Expression::Number(state.consume().unwrap())), + + TokenType::Identifier { .. } | TokenType::Symbol { symbol: Symbol::LeftParen } => { + let (prefix, suffixes) = match parse_prefix_and_suffixes(state) { + ParserResult::Value(value) => value, + ParserResult::LexerMoved => return ParserResult::LexerMoved, + ParserResult::NotFound => { + unreachable!("identifier found but parse_prefix_and_suffixes didn't even move") + } + }; + + if suffixes.is_empty() { + match prefix { + ast::Prefix::Expression(expression) => ParserResult::Value(*expression), + ast::Prefix::Name(name) => ParserResult::Value(Expression::Var(ast::Var::Name(name))), + } + } else if matches!(suffixes.last().unwrap(), ast::Suffix::Call(_)) { + ParserResult::Value(Expression::FunctionCall(ast::FunctionCall { prefix, suffixes })) + } else { + ParserResult::Value(Expression::Var(ast::Var::Expression(Box::new(ast::VarExpression { + prefix, + suffixes, + })))) + } + } + + TokenType::Symbol { symbol: Symbol::Minus | Symbol::Not | Symbol::Hash | Symbol::Tilde } => { + let unary_operator_token = state.consume().unwrap(); + parse_unary_expression(state, unary_operator_token) + } + + TokenType::Symbol { symbol: Symbol::LeftBrace } => { + let left_brace = state.consume().unwrap(); + ParserResult::Value(ast::Expression::TableConstructor(force_table_constructor(state, left_brace))) + } + + TokenType::Symbol { symbol: Symbol::If } => { + let if_token = state.consume().unwrap(); + match expect_if_else_expression(state, if_token) { + Ok(if_expression) => ParserResult::Value(ast::Expression::IfExpression(if_expression)), + Err(_) => ParserResult::LexerMoved, + } + } + + _ => ParserResult::NotFound, + }; + + match expression { + ParserResult::Value(expression) => { + if let Some(assertion_op) = state.consume_if(Symbol::TwoColons) { + let ParserResult::Value(cast_to) = parse_type(state) else { + return ParserResult::LexerMoved; + }; + ParserResult::Value(ast::Expression::TypeAssertion { + expression: Box::new(expression), + type_assertion: ast::TypeAssertion { assertion_op, cast_to }, + }) + } else { + ParserResult::Value(expression) + } + } + _ => expression, + } +} + +// rewrite todo: i think this should be iterative instead of recursive +fn parse_expression_with_precedence( + state: &mut ParserState, + mut lhs: Expression, + precedence: u8, +) -> ParserResult<Expression> { + loop { + let Some(bin_op_precedence) = ast::BinOp::precedence_of_token(match state.current() { + Ok(token) => token, + Err(()) => return ParserResult::Value(lhs), + }) else { + return ParserResult::Value(lhs); + }; + + if bin_op_precedence < precedence { + return ParserResult::Value(lhs); + } + + let bin_op = ast::BinOp::consume(state).unwrap(); + + let mut rhs = match parse_primary_expression(state) { + ParserResult::Value(expression) => expression, + ParserResult::NotFound => { + state.token_error(bin_op.token().clone(), "expected expression after binary operator"); + return ParserResult::Value(lhs); + } + ParserResult::LexerMoved => return ParserResult::LexerMoved, + }; + + while let Ok(next_bin_op_token) = state.current() { + let Some(next_bin_op_precedence) = ast::BinOp::precedence_of_token(next_bin_op_token) else { + break; + }; + + let precedence_to_search = if next_bin_op_precedence > bin_op_precedence { + bin_op_precedence + 1 + } else if ast::BinOp::is_right_associative_token(next_bin_op_token) + && next_bin_op_precedence == bin_op_precedence + { + bin_op_precedence + } else { + break; + }; + + rhs = match parse_expression_with_precedence(state, rhs, precedence_to_search) { + ParserResult::Value(expression) => expression, + ParserResult::NotFound => { + state.token_error(bin_op.token().clone(), "expected expression after binary operator"); + return ParserResult::Value(lhs); + } + ParserResult::LexerMoved => return ParserResult::Value(lhs), + }; + } + + lhs = Expression::BinaryOperator { lhs: Box::new(lhs), binop: bin_op, rhs: Box::new(rhs) }; + } +} + +fn parse_unary_expression( + state: &mut ParserState, + unary_operator_token: ast::TokenReference, +) -> ParserResult<ast::Expression> { + let unary_operator = match unary_operator_token.token_type() { + TokenType::Symbol { symbol } => match symbol { + Symbol::Minus => ast::UnOp::Minus(unary_operator_token), + Symbol::Not => ast::UnOp::Not(unary_operator_token), + Symbol::Hash => ast::UnOp::Hash(unary_operator_token), + Symbol::Tilde => ast::UnOp::Tilde(unary_operator_token), + _ => unreachable!(), + }, + + _ => unreachable!(), + }; + + let primary_expression = match parse_primary_expression(state) { + ParserResult::Value(expression) => expression, + ParserResult::NotFound => { + state.token_error( + unary_operator.token().clone(), + format!("expected an expression after {}", unary_operator.token().token()), + ); + return ParserResult::NotFound; + } + ParserResult::LexerMoved => return ParserResult::LexerMoved, + }; + + let expression = match parse_expression_with_precedence(state, primary_expression, ast::UnOp::precedence()) { + ParserResult::Value(expression) => expression, + ParserResult::LexerMoved => return ParserResult::LexerMoved, + ParserResult::NotFound => { + state.token_error( + unary_operator.token().clone(), + format!("expected an expression after {}", unary_operator.token().token()), + ); + return ParserResult::LexerMoved; + } + }; + + ParserResult::Value(Expression::UnaryOperator { unop: unary_operator, expression: Box::new(expression) }) +} + +fn parse_function_body(state: &mut ParserState) -> ParserResult<FunctionBody> { + let Some(left_parenthesis) = state.consume_if(Symbol::LeftParen) else { + return ParserResult::NotFound; + }; + + let mut parameters = Punctuated::new(); + let mut type_specifiers = Vec::new(); + let right_parenthesis; + + let unfinished_function_body = |left_parenthesis: TokenReference, mut parameters: Punctuated<Parameter>| { + if matches!(parameters.last(), Some(Pair::Punctuated(..))) { + let last_parameter = parameters.pop().unwrap(); + parameters.push(Pair::End(last_parameter.into_value())); + } + + // rewrite todo: we should appropriately recover the parsed type_specifiers here but it + // becomes messy with cfg feature toggles and moves. + ParserResult::Value(FunctionBody { + parameters_parentheses: ContainedSpan::new(left_parenthesis, TokenReference::basic_symbol(")")), + parameters, + type_specifiers: Vec::new(), // rewrite todo: fix + return_type: None, + block: ast::Block::new(), + end_token: TokenReference::basic_symbol("end"), + }) + }; + + loop { + match state.current() { + Ok(token) if token.is_symbol(Symbol::RightParen) => { + right_parenthesis = state.consume().unwrap(); + break; + } + + Ok(TokenReference { token: Token { token_type: TokenType::Identifier { .. }, .. }, .. }) => { + let name_parameter = match parse_name_with_type_specifiers(state) { + ParserResult::Value(Name { name, type_specifier, .. }) => { + type_specifiers.push(type_specifier); + ast::Parameter { name } + } + _ => unreachable!(), + }; + + let Some(comma) = state.consume_if(Symbol::Comma) else { + parameters.push(Pair::End(name_parameter)); + match state.require(Symbol::RightParen, "expected a `)`") { + Some(new_right_parenthesis) => { + right_parenthesis = new_right_parenthesis; + break; + } + None => return unfinished_function_body(left_parenthesis, parameters), + }; + }; + + parameters.push(Pair::Punctuated(name_parameter, comma)); + } + + Ok(token) => { + state.token_error(token.clone(), "expected a parameter name or `)`"); + return unfinished_function_body(left_parenthesis, parameters); + } + + Err(()) => return unfinished_function_body(left_parenthesis, parameters), + } + } + + if matches!(parameters.last(), Some(Pair::Punctuated(..))) { + let last_parameter = parameters.pop().unwrap(); + state + .token_error(last_parameter.punctuation().unwrap().clone(), "trailing commas in arguments are not allowed"); + parameters.push(Pair::End(last_parameter.into_value())); + } + + let return_type = if let Some(punctuation) = state.consume_if(Symbol::Colon) { + match parse_return_type(state) { + ParserResult::Value(type_info) => Some(ast::TypeSpecifier { punctuation, type_info }), + _ => return ParserResult::LexerMoved, + } + } else if let Some(punctuation) = state.consume_if(Symbol::ThinArrow) { + state.token_error(punctuation.clone(), "function return type annotations should use `:` instead of `->`"); + match parse_return_type(state) { + ParserResult::Value(type_info) => Some(ast::TypeSpecifier { punctuation, type_info }), + _ => return ParserResult::LexerMoved, + } + } else { + None + }; + + let (block, end) = match expect_block_with_end(state, "function body", &right_parenthesis) { + Ok((block, end)) => (block, end), + Err(()) => return ParserResult::LexerMoved, + }; + + ParserResult::Value(FunctionBody { + parameters_parentheses: ContainedSpan::new(left_parenthesis, right_parenthesis), + parameters, + type_specifiers, + return_type, + block, + end_token: end, + }) +} + +fn expect_if_else_expression(state: &mut ParserState, if_token: TokenReference) -> Result<ast::IfExpression, ()> { + let condition = parse_expression(state).ok_or(())?; + let then_token = state + .require(Symbol::Then, "expected `then` after condition") + .ok_or(())?; + let if_expression = parse_expression(state).ok_or(())?; + + let mut else_if_expressions = Vec::new(); + while let Some(else_if_token) = state.consume_ifs(&[Symbol::ElseIf, Symbol::ElIf]) { + let condition = parse_expression(state).ok_or(())?; + let then_token = state + .require(Symbol::Then, "expected `then` after condition") + .ok_or(())?; + let expression = parse_expression(state).ok_or(())?; + else_if_expressions.push(ast::ElseIfExpression { else_if_token, condition, then_token, expression }) + } + + let else_token = state + .require(Symbol::Else, "expected `else` to end if-else expression") + .ok_or(())?; + let else_expression = parse_expression(state).ok_or(())?; + + Ok(ast::IfExpression { + if_token, + condition: Box::new(condition), + then_token, + if_expression: Box::new(if_expression), + else_if_expressions: if else_if_expressions.is_empty() { None } else { Some(else_if_expressions) }, + else_token, + else_expression: Box::new(else_expression), + }) +} + +fn parse_type(state: &mut ParserState) -> ParserResult<ast::TypeInfo> { + let ParserResult::Value(simple_type) = parse_simple_type(state) else { + return ParserResult::LexerMoved; + }; + + let mut current_type = simple_type; + while let Some(question_mark) = state.consume_if(Symbol::QuestionMark) { + current_type = ast::TypeInfo::Optional { base: Box::new(current_type), question_mark }; + } + ParserResult::Value(current_type) +} + +fn parse_simple_type(state: &mut ParserState) -> ParserResult<ast::TypeInfo> { + let Ok(current_token) = state.current() else { + return ParserResult::NotFound; + }; + + match current_token.token_type() { + TokenType::Symbol { symbol: Symbol::Nil } => { + let nil_token = state.consume().unwrap(); + ParserResult::Value(ast::TypeInfo::Basic(nil_token)) + } + TokenType::Identifier { .. } => { + let name = state.consume().unwrap(); + if name.to_string() == "typeof" { + let left_parenthesis = match state.require(Symbol::LeftParen, "expected `(` after `typeof`") { + Some(token) => token, + None => TokenReference::basic_symbol("("), + }; + + let ParserResult::Value(expression) = parse_expression(state) else { + return ParserResult::LexerMoved; + }; + + let right_parenthesis = match state.require_with_reference_token( + Symbol::RightParen, + "expected `)` to close typeof call", + &left_parenthesis, + ) { + Some(token) => token, + None => TokenReference::basic_symbol(")"), + }; + + ParserResult::Value(ast::TypeInfo::Typeof { + typeof_token: name, + parentheses: ContainedSpan::new(left_parenthesis, right_parenthesis), + inner: Box::new(expression), + }) + } else { + ParserResult::Value(ast::TypeInfo::Basic(name)) + } + } + TokenType::Symbol { symbol: Symbol::LeftBrace } => { + let left_brace = state.consume().unwrap(); + match expect_type_table(state, left_brace) { + Ok(table) => ParserResult::Value(table), + Err(_) => ParserResult::LexerMoved, + } + } + TokenType::Symbol { symbol: Symbol::LeftParen } => match expect_function_type(state) { + Ok(type_info) => ParserResult::Value(type_info), + Err(_) => ParserResult::LexerMoved, + }, + _ => ParserResult::NotFound, + } +} + +fn expect_type_table(state: &mut ParserState, left_brace: TokenReference) -> Result<ast::TypeInfo, ()> { + let mut fields = Punctuated::new(); + let mut has_indexer = false; + let mut array_type = None; + + loop { + let current_token = state.current()?; + + let field = if current_token.is_symbol(Symbol::RightBrace) { + debug_assert!(array_type.is_none(), "consuming right brace in loop but have seen array type"); + let braces = ContainedSpan::new(left_brace, state.consume().unwrap()); + return Ok(ast::TypeInfo::Table { braces, fields }); + } else if current_token.is_symbol(Symbol::LeftBracket) { + let left_brace = state.consume().unwrap(); + let key = match parse_type(state) { + ParserResult::Value(value) => value, + ParserResult::NotFound => { + state.token_error(state.current().unwrap().clone(), "expected type for type field key"); + return Err(()); + } + ParserResult::LexerMoved => return Err(()), + }; + let right_brace = state + .require(Symbol::RightBracket, "expected `]` to close `[` for type table field") + .ok_or(())?; + let colon = state + .require(Symbol::Colon, "expected `:` after type field key") + .ok_or(())?; + + let value = match parse_type(state) { + ParserResult::Value(value) => value, + ParserResult::NotFound => { + state.token_error(state.current().unwrap().clone(), "expected type after type field key"); + return Err(()); + } + ParserResult::LexerMoved => return Err(()), + }; + + if has_indexer { + state.token_error_ranged( + left_brace.clone(), + "cannot have more than one table indexer", + &left_brace, + value.tokens().last().unwrap(), + ); + } + has_indexer = true; + + ast::TypeField { + key: ast::TypeFieldKey::IndexSignature { + brackets: ContainedSpan::new(left_brace, right_brace), + inner: key, + }, + colon, + value, + } + } else if fields.is_empty() + && !has_indexer + && !(current_token.token_kind() == TokenKind::Identifier + && matches!(state.peek(), Ok(token) if token.is_symbol(Symbol::Colon))) + { + array_type = Some(match parse_type(state) { + ParserResult::Value(value) => value, + ParserResult::NotFound => { + state.token_error(state.current().unwrap().clone(), "expected type for table array"); + return Err(()); + } + ParserResult::LexerMoved => return Err(()), + }); + break; + } else { + match parse_name(state) { + ParserResult::Value(name) => { + let colon = state + .require(Symbol::Colon, "expected `:` after type field key") + .ok_or(())?; + let value = match parse_type(state) { + ParserResult::Value(value) => value, + ParserResult::NotFound => { + state.token_error(state.current().unwrap().clone(), "expected type after type field key"); + return Err(()); + } + ParserResult::LexerMoved => return Err(()), + }; + ast::TypeField { key: ast::TypeFieldKey::Name(name.name), colon, value } + } + ParserResult::NotFound => break, + ParserResult::LexerMoved => return Err(()), + } + }; + + match state.current() { + Ok(token) => { + if token.in_symbols(&[Symbol::Comma, Symbol::Semicolon]) { + fields.push(Pair::Punctuated(field, state.consume().unwrap())) + } else { + fields.push(Pair::End(field)); + break; + } + } + + Err(()) => { + fields.push(Pair::End(field)); + break; + } + }; + } + + let right_brace = state + .require(Symbol::RightBrace, "expected `}` to close type table") + .unwrap_or_else(|| TokenReference::basic_symbol("}")); + + let braces = ContainedSpan::new(left_brace, right_brace); + + if let Some(type_info) = array_type { + Ok(ast::TypeInfo::Array { braces, type_info: Box::new(type_info) }) + } else { + Ok(ast::TypeInfo::Table { braces, fields }) + } +} + +fn expect_function_type(state: &mut ParserState) -> Result<ast::TypeInfo, ()> { + let mut arguments = Punctuated::new(); + let left_paren = state.require(Symbol::LeftParen, "expected `(`").ok_or(())?; + + while !matches!(state.current(), Ok(token) if token.is_symbol(Symbol::RightParen)) { + let current_token = state.current()?; + let name = if current_token.token_kind() == TokenKind::Identifier + && matches!(state.peek(), Ok(token) if token.is_symbol(Symbol::Colon)) + { + Some((state.consume().unwrap(), state.consume().unwrap())) + } else { + None + }; + + let type_info = parse_type(state).ok_or(())?; + let type_argument = ast::TypeArgument { name, type_info }; + if !matches!(state.current(), Ok(token) if token.is_symbol(Symbol::Comma)) { + arguments.push(Pair::End(type_argument)); + break; + } + + let punctuation = state.consume().unwrap(); + arguments.push(Pair::Punctuated(type_argument, punctuation)); + if matches!(state.current(), Ok(token) if token.is_symbol(Symbol::RightParen)) { + state.token_error(state.current().unwrap().clone(), "expected type after `,` but got `)` instead"); + break; + } + } + + let right_paren = state + .require(Symbol::RightParen, "expected `)` to close `(`") + .ok_or(())?; + + let parentheses = ContainedSpan::new(left_paren, right_paren); + + if !arguments.iter().any(|arg: &ast::TypeArgument| arg.name().is_some()) + && !matches!(state.current(), Ok(token) if token.is_symbol(Symbol::ThinArrow)) + && !arguments.is_empty() + { + let types = arguments + .into_pairs() + .map(|pair| pair.map(|argument| argument.type_info)) + .collect(); + return Ok(ast::TypeInfo::Tuple { parentheses, types }); + } + + let arrow = state + .require(Symbol::ThinArrow, "expected `->` after `()` for function type") + .ok_or(())?; + let return_type = parse_return_type(state).ok_or(())?; + + Ok(ast::TypeInfo::Callback { parentheses, arguments, arrow, return_type: Box::new(return_type) }) +} + +fn expect_type_specifier(state: &mut ParserState, punctuation: TokenReference) -> Result<ast::TypeSpecifier, ()> { + let ParserResult::Value(type_info) = parse_type(state) else { + state.token_error(punctuation, "expected type info after `:`"); + return Err(()); + }; + Ok(ast::TypeSpecifier { punctuation, type_info }) +} + +fn parse_return_type(state: &mut ParserState) -> ParserResult<ast::TypeInfo> { + parse_type(state) + .ok() + .map(ParserResult::Value) + .unwrap_or(ParserResult::LexerMoved) +} + +#[derive(Clone)] +struct Name { + name: TokenReference, + attribute: Option<super::Attribute>, + type_specifier: Option<ast::TypeSpecifier>, +} + +fn parse_name(state: &mut ParserState) -> ParserResult<Name> { + let Ok(current_token) = state.current() else { + return ParserResult::NotFound; + }; + + match current_token.token_type() { + TokenType::Identifier { .. } => { + let name_token = state.consume().unwrap(); + ParserResult::Value(force_name(state, name_token)) + } + + _ => ParserResult::NotFound, + } +} + +fn parse_identifier(state: &mut ParserState) -> ParserResult<TokenReference> { + let Ok(current_token) = state.current() else { + return ParserResult::NotFound; + }; + let token = match current_token.token_type() { + TokenType::Identifier { .. } => state.consume().unwrap(), + _ => { + state.token_error(current_token.clone(), "expected an identifier"); + return ParserResult::NotFound; + } + }; + ParserResult::Value(token) +} + +fn parse_name_with_attributes(state: &mut ParserState) -> ParserResult<Name> { + let Ok(current_token) = state.current() else { + return ParserResult::NotFound; + }; + + match current_token.token_type() { + TokenType::Identifier { .. } => { + let name_token = state.consume().unwrap(); + ParserResult::Value(force_name_with_attributes(state, name_token)) + } + + _ => ParserResult::NotFound, + } +} + +fn parse_name_with_type_specifiers(state: &mut ParserState) -> ParserResult<Name> { + let Ok(current_token) = state.current() else { + return ParserResult::NotFound; + }; + match current_token.token_type() { + TokenType::Identifier { .. } => { + let name_token = state.consume().unwrap(); + ParserResult::Value(force_name_with_type_specifiers(state, name_token)) + } + _ => ParserResult::NotFound, + } +} + +fn force_name(_state: &mut ParserState, name: TokenReference) -> Name { + Name { name, attribute: None, type_specifier: None } +} + +fn force_name_with_attributes(state: &mut ParserState, name: TokenReference) -> Name { + // NOTE: whenever attributes can be parsed, type specifiers are possible + // so we should fall back to parsing type specifiers if an attribute is not found. + // NOTE: we do not attempt to parse both type specifiers and attributes at the same time + + if let Some(left_angle_bracket) = state.consume_if(Symbol::LessThan) { + const ERROR_INVALID_ATTRIBUTE: &str = "expected identifier after `<` for attribute"; + + let attribute_name = match state.current() { + Ok(token) if matches!(token.token_type(), TokenType::Identifier { .. }) => state.consume().unwrap(), + Ok(token) => { + state.token_error_ranged(token.clone(), ERROR_INVALID_ATTRIBUTE, &left_angle_bracket, &token.clone()); + return Name { name, attribute: None, type_specifier: None }; + } + Err(()) => { + state.token_error(left_angle_bracket, ERROR_INVALID_ATTRIBUTE); + return Name { name, attribute: None, type_specifier: None }; + } + }; + + let Some(right_angle_bracket) = state.require(Symbol::GreaterThan, "expected `>` to close attribute") else { + return Name { + name, + attribute: Some(super::Attribute { + brackets: ContainedSpan::new(left_angle_bracket, TokenReference::basic_symbol(">")), + name: attribute_name, + }), + type_specifier: None, + }; + }; + + return Name { + name, + attribute: Some(super::Attribute { + brackets: ContainedSpan::new(left_angle_bracket, right_angle_bracket), + name: attribute_name, + }), + type_specifier: None, + }; + } + + force_name_with_type_specifiers(state, name) +} + +fn force_name_with_type_specifiers(state: &mut ParserState, name: TokenReference) -> Name { + match state.consume_if(Symbol::Colon).map(|p| expect_type_specifier(state, p)) { + Some(Ok(type_specifier)) => Name { name, attribute: None, type_specifier: Some(type_specifier) }, + Some(Err(())) => Name { name, attribute: None, type_specifier: None }, + None => force_name(state, name), + } +} + +fn one_or_more<T, F: Fn(&mut ParserState) -> ParserResult<T>>( + state: &mut ParserState, + parser: F, + delimiter: Symbol, +) -> ParserResult<Punctuated<T>> { + let mut values = Punctuated::new(); + + loop { + let value = match parser(state) { + ParserResult::Value(value) => value, + ParserResult::NotFound | ParserResult::LexerMoved => break, + }; + + match state.consume_if(delimiter) { + Some(delimiter) => values.push(Pair::Punctuated(value, delimiter)), + None => { + values.push(Pair::End(value)); + break; + } + } + } + + if values.is_empty() { + return ParserResult::NotFound; + } + + if let Some(Pair::Punctuated(..)) = values.last() { + let last_value = values.pop().unwrap(); + state.token_error(last_value.punctuation().unwrap().clone(), "trailing commas are not allowed"); + values.push(Pair::End(last_value.into_value())); + } + + ParserResult::Value(values) +} + +fn parse_name_list(state: &mut ParserState) -> ParserResult<Punctuated<Name>> { + one_or_more(state, parse_name_with_type_specifiers, Symbol::Comma) +} + +fn parse_expression_list(state: &mut ParserState) -> ParserResult<Punctuated<Expression>> { + one_or_more(state, parse_expression, Symbol::Comma) +} diff --git a/src/Rust/vvs_parser/src/ast/parsers/structs/ast_result.rs b/src/Rust/vvs_parser/src/ast/parsers/structs/ast_result.rs new file mode 100644 index 0000000000000000000000000000000000000000..9d4ab19016b2c7943a8ab7ee084b9ddd03b6da87 --- /dev/null +++ b/src/Rust/vvs_parser/src/ast/parsers/structs/ast_result.rs @@ -0,0 +1,117 @@ +use crate::{ + ast::{ + parsers::{parse_block, ParserResult, ParserState}, + Ast, + }, + tokenizer::{Lexer, LexerResult, TokenKind}, +}; + +/// A produced [`Ast`](crate::ast::Ast), along with any errors found during parsing. +/// This Ast may not be exactly the same as the input code, as reconstruction may have occurred. +/// For more information, read the documentation for [`parse_fallible`](crate::parse_fallible). +pub struct AstResult { + ast: Ast, + errors: Vec<crate::Error>, +} + +impl AstResult { + /// Returns a reference to the [`Ast`](crate::ast::Ast) that was parsed. + /// If there were any errors, this will not be exactly the same, + /// as reconstruction will have occurred. + /// For more information, read the documentation for [`parse_fallible`](crate::parse_fallible). + pub fn ast(&self) -> &Ast { + &self.ast + } + + /// Consumes the [`Ast`](crate::ast::Ast) that was parsed. + /// If there were any errors, this will not be exactly the same, + /// as reconstruction will have occurred. + /// For more information, read the documentation for [`parse_fallible`](crate::parse_fallible). + pub fn into_ast(self) -> Ast { + self.ast + } + + /// Returns all errors that occurred during parsing. + pub fn errors(&self) -> &[crate::Error] { + &self.errors + } + + pub(crate) fn parse_fallible(code: &str) -> Self { + use crate::{ast::AstError, Error}; + const UNEXPECTED_TOKEN_ERROR: &str = "unexpected token, this needs to be a statement"; + + let lexer = Lexer::new(code); + let mut parser_state = ParserState::new(lexer); + let mut block = parse_block(&mut parser_state).unwrap_or_defaut(); + + loop { + match parser_state.lexer.current() { + Some(LexerResult::Ok(token)) if token.token_kind() == TokenKind::Eof => break, + Some(LexerResult::Ok(_) | LexerResult::Recovered(_, _)) => { + let ParserResult::Value(new_block) = parse_block(&mut parser_state) else { + continue; + }; + if new_block.stmts.is_empty() { + match parser_state.current() { + Ok(token) if token.token_kind() == TokenKind::Eof => break, + _ => {} + } + match parser_state.consume() { + ParserResult::Value(token) => match parser_state.errors.last() { + Some(Error::AstError(AstError { additional, .. })) + if additional == UNEXPECTED_TOKEN_ERROR => + { + continue + } + Some(Error::AstError(AstError { .. })) => { + parser_state.token_error(token, UNEXPECTED_TOKEN_ERROR) + } + _ => parser_state.token_error(token, UNEXPECTED_TOKEN_ERROR), + }, + ParserResult::LexerMoved => {} + ParserResult::NotFound => unreachable!(), + } + continue; + } + block.merge_blocks(new_block); + } + Some(LexerResult::Fatal(_)) => parser_state.errors.extend( + Option::unwrap(parser_state.lexer.consume()) + .unwrap_errors() + .into_iter() + .map(Error::TokenizerError), + ), + None => break, + } + } + + let eof = match parser_state.lexer.consume().unwrap() { + LexerResult::Ok(token) => token, + LexerResult::Recovered(token, errors) => { + parser_state + .errors + .extend(errors.into_iter().map(Error::TokenizerError)); + token + } + LexerResult::Fatal(error) => unreachable!("error: {error:?}"), + }; + + debug_assert_eq!(eof.token_kind(), TokenKind::Eof); + Self { ast: Ast { nodes: block, eof }, errors: parser_state.errors } + } + + /// Consumes this AstResult, returning the [`Ast`](crate::ast::Ast) that was parsed. + pub fn into_result(self) -> Result<Ast, Vec<crate::Error>> { + self.into() + } +} + +impl From<AstResult> for Result<Ast, Vec<crate::Error>> { + fn from(ast_result: AstResult) -> Self { + if ast_result.errors.is_empty() { + Ok(ast_result.ast) + } else { + Err(ast_result.errors) + } + } +} diff --git a/src/Rust/vvs_parser/src/ast/parsers/structs/mod.rs b/src/Rust/vvs_parser/src/ast/parsers/structs/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..6dc9ff1913beae8732b50b1dd3fabdefbd8429f6 --- /dev/null +++ b/src/Rust/vvs_parser/src/ast/parsers/structs/mod.rs @@ -0,0 +1,148 @@ +use crate::{ + tokenizer::{Lexer, LexerResult, Symbol, TokenKind, TokenReference}, + traits::MaybeLazyString, +}; +use std::borrow::Cow; + +mod ast_result; +mod option_table_result; +mod result; + +pub use crate::ast::parsers::structs::{ast_result::*, option_table_result::*, result::*}; + +pub struct ParserState { + errors: Vec<crate::Error>, + lexer: Lexer, +} + +impl ParserState { + pub fn new(lexer: Lexer) -> Self { + Self { errors: Vec::new(), lexer } + } + + pub fn current(&self) -> Result<&TokenReference, ()> { + match self.lexer.current() { + Some(LexerResult::Ok(token) | LexerResult::Recovered(token, _)) => Ok(token), + Some(LexerResult::Fatal(_)) => Err(()), + None => unreachable!("current() called past EOF"), + } + } + + pub fn peek(&self) -> Result<&TokenReference, ()> { + match self.lexer.peek() { + Some(LexerResult::Ok(token) | LexerResult::Recovered(token, _)) => Ok(token), + Some(LexerResult::Fatal(_)) => Err(()), + None => unreachable!("peek() called past EOF"), + } + } + + pub fn consume(&mut self) -> ParserResult<TokenReference> { + match self.lexer.consume() { + Some(LexerResult::Ok(token)) => ParserResult::Value(token), + Some(LexerResult::Recovered(token, errors)) => { + self.errors.extend(errors.into_iter().map(crate::Error::TokenizerError)); + ParserResult::Value(token) + } + Some(LexerResult::Fatal(errors)) => { + self.errors.extend(errors.into_iter().map(crate::Error::TokenizerError)); + ParserResult::LexerMoved + } + None => ParserResult::NotFound, + } + } + + pub fn consume_ifs(&mut self, symbols: &[Symbol]) -> Option<TokenReference> { + symbols.iter().copied().find_map(|symbol| self.consume_if(symbol)) + } + + pub fn consume_if(&mut self, symbol: Symbol) -> Option<TokenReference> { + self.current().ok()?.is_symbol(symbol).then(|| self.consume().unwrap()) + } + + pub fn consume_kind(&mut self, kind: TokenKind) -> Option<TokenReference> { + if self.current().ok()?.is_kind(kind) { + Some(self.consume().unwrap()) + } else { + self.token_error(self.current().unwrap().clone(), format!("expected a token of type {kind:?}")); + None + } + } + + pub fn require(&mut self, symbol: Symbol, error: &'static str) -> Option<TokenReference> { + if self.current().ok()?.is_symbol(symbol) { + Some(self.consume().unwrap()) + } else { + self.token_error(self.current().ok()?.clone(), error); + None + } + } + + pub fn require_with_reference_token( + &mut self, + symbol: Symbol, + error: &'static str, + reference_token: &TokenReference, + ) -> Option<TokenReference> { + if self.current().ok()?.is_symbol(symbol) { + Some(self.consume().unwrap()) + } else { + self.token_error(reference_token.clone(), error); + None + } + } + + pub fn require_with_reference_range( + &mut self, + symbol: Symbol, + error: impl MaybeLazyString, + start_token: &TokenReference, + end_token: &TokenReference, + ) -> Option<TokenReference> { + let token = self.current().ok()?; + if token.is_symbol(symbol) { + Some(self.consume().unwrap()) + } else { + self.token_error_ranged(token.clone(), error.to_str(), start_token, end_token); + None + } + } + + pub fn require_with_reference_range_callback( + &mut self, + symbol: Symbol, + error: impl MaybeLazyString, + tokens: impl FnOnce() -> (TokenReference, TokenReference), + ) -> Option<TokenReference> { + let token = self.current().ok()?; + if token.is_symbol(symbol) { + Some(self.consume().unwrap()) + } else { + let (start_token, end_token) = tokens(); + self.token_error_ranged(token.clone(), error.to_str(), &start_token, &end_token); + None + } + } + + pub fn token_error(&mut self, token_reference: TokenReference, error: impl Into<Cow<'static, str>>) { + self.errors.push(crate::Error::AstError(crate::ast::AstError { + token: token_reference.token, + additional: error.into(), + range: None, + })); + } + + // This takes start_token and end_token as owned references because otherwise, we tend to stack an immutable over mutable borrow. + pub fn token_error_ranged( + &mut self, + token_reference: TokenReference, + error: impl Into<Cow<'static, str>>, + start_token: &TokenReference, + end_token: &TokenReference, + ) { + self.errors.push(crate::Error::AstError(crate::ast::AstError { + token: token_reference.token, + additional: error.into(), + range: Some((start_token.start_position(), end_token.end_position())), + })); + } +} diff --git a/src/Rust/vvs_parser/src/ast/parsers/structs/option_table_result.rs b/src/Rust/vvs_parser/src/ast/parsers/structs/option_table_result.rs new file mode 100644 index 0000000000000000000000000000000000000000..8c8a260e3c3a8abe596ac9b0b72397e93aded7b8 --- /dev/null +++ b/src/Rust/vvs_parser/src/ast/parsers/structs/option_table_result.rs @@ -0,0 +1,56 @@ +use crate::{ + ast::{ + parsers::{parse_option_table, ParserState}, + OptionTable, + }, + tokenizer::Lexer, +}; + +/// A produced [`OptionTable`](crate::ast::OptionTable), along with any errors found during +/// parsing. This option table may not be exactly the same as the input code, as reconstruction may +/// have occurred. For more information. +pub struct OptionTableResult { + option_table: OptionTable, + errors: Vec<crate::Error>, +} + +impl OptionTableResult { + /// Returns a reference to the [OptionTable] that was parsed. If there were any errors, this + /// will not be exactly the same, as reconstruction will have occurred. + pub fn option_table(&self) -> &OptionTable { + &self.option_table + } + + /// Consumes the [OptionTable] that was parsed. If there were any errors, this will not be + /// exactly the same, as reconstruction will have occurred. + pub fn into_option_table(self) -> OptionTable { + self.option_table + } + + /// Returns all errors that occurred during parsing. + pub fn errors(&self) -> &[crate::Error] { + &self.errors + } + + pub(crate) fn parse_fallible(code: &str) -> Self { + let lexer = Lexer::new(code); + let mut parser_state = ParserState::new(lexer); + let option_table = parse_option_table(&mut parser_state).unwrap_or_defaut(); + Self { option_table, errors: parser_state.errors } + } + + /// Consumes this OptionTableResult, returning the [OptionTable] that was parsed. + pub fn into_result(self) -> Result<OptionTable, Vec<crate::Error>> { + self.into() + } +} + +impl From<OptionTableResult> for Result<OptionTable, Vec<crate::Error>> { + fn from(result: OptionTableResult) -> Self { + if result.errors.is_empty() { + Ok(result.option_table) + } else { + Err(result.errors) + } + } +} diff --git a/src/Rust/vvs_parser/src/ast/parsers/structs/result.rs b/src/Rust/vvs_parser/src/ast/parsers/structs/result.rs new file mode 100644 index 0000000000000000000000000000000000000000..8231bb824dbf22209d450654822009d58fc81bf8 --- /dev/null +++ b/src/Rust/vvs_parser/src/ast/parsers/structs/result.rs @@ -0,0 +1,57 @@ +#[derive(Debug)] +pub enum ParserResult<T> { + // This doesn't necessarily mean that there were no errors, + // because this can sometimes be a recovered value. + Value(T), + + // Couldn't get any sort of value, but the lexer has moved. + // This should always come with an error. + LexerMoved, + + NotFound, +} + +impl<T> ParserResult<T> { + pub fn ok(self) -> Option<T> { + match self { + ParserResult::Value(value) => Some(value), + ParserResult::LexerMoved | ParserResult::NotFound => None, + } + } + + pub fn ok_or<E>(self, error: E) -> Result<T, E> { + self.ok().ok_or(error) + } + + pub fn expect(self, msg: &str) -> T { + self.ok().expect(msg) + } + + pub fn unwrap(self) -> T { + match self { + ParserResult::Value(value) => value, + ParserResult::LexerMoved => panic!("unwrap() called when value was LexerMoved"), + ParserResult::NotFound => panic!("unwrap() called when value was NotFound"), + } + } + + pub fn unwrap_or(self, default: T) -> T { + match self { + ParserResult::Value(value) => value, + _ => default, + } + } + + pub fn unwrap_or_else(self, cb: impl FnOnce() -> T) -> T { + match self { + ParserResult::Value(value) => value, + _ => cb(), + } + } +} + +impl<T: Default> ParserResult<T> { + pub fn unwrap_or_defaut(self) -> T { + self.unwrap_or_else(Default::default) + } +} diff --git a/src/Rust/vvs_parser/src/ast/parsers/util.rs b/src/Rust/vvs_parser/src/ast/parsers/util.rs new file mode 100644 index 0000000000000000000000000000000000000000..1daef7139999e194144b0350da0fc391af865a5d --- /dev/null +++ b/src/Rust/vvs_parser/src/ast/parsers/util.rs @@ -0,0 +1,16 @@ +// Consumes a ParserResult into an Option<T>. +// If the ParserResult is LexerMoved, this signifies an unrecoverable error, and +// the function exits early. +// I wish we had Try traits. +#[doc(hidden)] +#[macro_export] +macro_rules! try_parser { + ($result:expr) => {{ + use $crate::ast::parsers::ParserResult; + match $result { + ParserResult::Value(value) => Some(value), + ParserResult::NotFound => None, + ParserResult::LexerMoved => return ParserResult::LexerMoved, + } + }}; +} diff --git a/src/Rust/vvs_parser/src/ast/punctuated.rs b/src/Rust/vvs_parser/src/ast/punctuated.rs new file mode 100644 index 0000000000000000000000000000000000000000..cb070f68f3c502458ad97a7220b3e112f553c865 --- /dev/null +++ b/src/Rust/vvs_parser/src/ast/punctuated.rs @@ -0,0 +1,487 @@ +//! A punctuated sequence of syntax tree nodes separated by punctuation (tokens). +//! +//! Examples of punctuated sequences include: +//! - Arguments in a function call are `Punctuated<Expression>` +//! - Names and definitions in a local assignment are `Punctuated<TokenReference>` and `Punctuated<Expression>` respectively +//! - The values of a return statement are `Punctuated<Expression>` +//! +//! Everything with punctuation uses the [`Punctuated<T>`](Punctuated) type with the following logic. + +use crate::{ + node::{Node, TokenItem, Tokens}, + private::Sealed, + tokenizer::{Position, TokenReference}, + util, + visitors::{Visit, VisitMut, Visitor, VisitorMut}, +}; +use derive_more::Display; +use serde::{Deserialize, Serialize}; +use std::iter::FromIterator; + +/// A punctuated sequence of node `T` separated by +/// [`TokenReference`](crate::tokenizer::TokenReference). +/// Refer to the [module documentation](index.html) for more details. +#[derive(Clone, Debug, Display, PartialEq, Eq, Deserialize, Serialize)] +#[display(bound(T: Display))] +#[display("{}", util::join_vec(pairs))] +pub struct Punctuated<T> { + pairs: Vec<Pair<T>>, +} + +impl<T> Punctuated<T> { + /// Creates an empty punctuated sequence + /// ```rust + /// # use vvs_parser::prelude::ast::*; + /// let mut punctuated: Punctuated<i32> = Punctuated::new(); + /// ``` + pub const fn new() -> Self { + Self { pairs: Vec::new() } + } + + /// Constructs a new, empty [Punctuated<T>] with at least the specified capacity. + /// + /// The vector will be able to hold at least `capacity` elements without + /// reallocating. This method is allowed to allocate for more elements than + /// `capacity`. If `capacity` is 0, the vector will not allocate. + /// ```rust + /// # use vvs_parser::prelude::ast::*; + /// let mut punctuated = Punctuated::<bool>::with_capacity(10); + /// assert!(punctuated.is_empty()); + /// ``` + pub fn with_capacity(capacity: usize) -> Self { + Self { pairs: Vec::with_capacity(capacity) } + } + + /// Returns whether there's any nodes in the punctuated sequence + /// ```rust + /// # use vvs_parser::prelude::ast::*; + /// let mut punctuated = Punctuated::new(); + /// assert!(punctuated.is_empty()); + /// punctuated.push(Pair::new((), None)); + /// assert!(!punctuated.is_empty()); + /// ``` + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + /// Returns the number of pairs in the punctuated sequence + /// ```rust + /// # use vvs_parser::prelude::ast::*; + /// let mut punctuated = Punctuated::new(); + /// assert_eq!(punctuated.len(), 0); + /// punctuated.push(Pair::new((), None)); + /// assert_eq!(punctuated.len(), 1); + /// ``` + pub fn len(&self) -> usize { + self.pairs.len() + } + + /// Returns an iterator over references of the sequence values, ignoring punctuation + /// ```rust + /// # use vvs_parser::prelude::ast::*; + /// let mut punctuated = Punctuated::new(); + /// punctuated.push(Pair::new(1, None)); + /// let mut iterator = punctuated.iter(); + /// assert_eq!(iterator.next(), Some(&1)); + /// assert_eq!(iterator.next(), None); + /// ``` + pub fn iter(&self) -> Iter<'_, T> { + self.into_iter() + } + + /// Returns an iterator over mutable references of the sequence values, ignoring punctuation + /// ```rust + /// # use vvs_parser::prelude::ast::*; + /// let mut punctuated = Punctuated::new(); + /// punctuated.push(Pair::new(1, None)); + /// for item in punctuated.iter_mut() { + /// *item += 1; + /// } + /// assert_eq!(punctuated.pop(), Some(Pair::new(2, None))); + /// ``` + pub fn iter_mut(&mut self) -> IterMut<'_, T> { + self.into_iter() + } + + /// Returns an iterator over pairs + /// ```rust + /// # use vvs_parser::prelude::ast::*; + /// let mut punctuated = Punctuated::new(); + /// punctuated.push(Pair::new(1, None)); + /// let mut iterator = punctuated.into_pairs(); + /// assert_eq!(iterator.next(), Some(Pair::new(1, None))); + /// assert_eq!(iterator.next(), None); + /// ``` + pub fn into_pairs(self) -> impl Iterator<Item = Pair<T>> { + self.pairs.into_iter() + } + + /// Returns the first pair in the sequence + /// ```rust + /// # use vvs_parser::prelude::ast::*; + /// let mut punctuated = Punctuated::new(); + /// assert_eq!(punctuated.first(), None); + /// punctuated.push(Pair::new(1, None)); + /// assert_eq!(punctuated.first(), Some(&Pair::new(1, None))); + /// ``` + pub fn first(&self) -> Option<&Pair<T>> { + self.pairs.first() + } + + /// Returns the last pair in the sequence + /// ```rust + /// # use vvs_parser::prelude::ast::*; + /// let mut punctuated = Punctuated::new(); + /// punctuated.push(Pair::new(1, None)); + /// assert_eq!(punctuated.last(), Some(&Pair::new(1, None))); + /// ``` + pub fn last(&self) -> Option<&Pair<T>> { + self.pairs.last() + } + + /// Returns an iterator over pairs as references + /// ```rust + /// # use vvs_parser::prelude::ast::*; + /// let mut punctuated = Punctuated::new(); + /// punctuated.push(Pair::new(1, None)); + /// let mut iterator = punctuated.pairs(); + /// assert_eq!(iterator.next(), Some(&Pair::new(1, None))); + /// assert_eq!(iterator.next(), None); + /// ``` + pub fn pairs(&self) -> impl Iterator<Item = &Pair<T>> { + self.pairs.iter() + } + + /// Returns an iterator over pairs as mutable references + /// ```rust + /// # use vvs_parser::prelude::ast::*; + /// let mut punctuated = Punctuated::new(); + /// punctuated.push(Pair::new(1, None)); + /// for item in punctuated.pairs_mut() { + /// *item.value_mut() += 1; + /// } + /// assert_eq!(punctuated.pop(), Some(Pair::new(2, None))); + /// ``` + pub fn pairs_mut(&mut self) -> impl Iterator<Item = &mut Pair<T>> { + self.pairs.iter_mut() + } + + /// Pops off the last pair if it isn't empty + /// ```rust + /// # use vvs_parser::prelude::ast::*; + /// let mut punctuated = Punctuated::new(); + /// punctuated.push(Pair::new(1, None)); + /// assert_eq!(punctuated.pop(), Some(Pair::new(1, None))); + /// ``` + pub fn pop(&mut self) -> Option<Pair<T>> { + self.pairs.pop() + } + + /// Pushes a new pair onto the sequence + /// ```rust + /// # use vvs_parser::prelude::ast::*; + /// let mut punctuated = Punctuated::new(); + /// punctuated.push(Pair::new(1, None)); + /// assert_eq!(punctuated.pop(), Some(Pair::new(1, None))); + /// ``` + pub fn push(&mut self, pair: Pair<T>) { + self.pairs.push(pair); + } + + /// Pushes a new node `T` onto the sequence, with the given punctuation. + /// Will apply the punctuation to the last item, which must exist. + pub fn push_punctuated(&mut self, value: T, punctuation: TokenReference) { + let last_pair = self + .pairs + .pop() + .expect("push_punctuated adds the punctuation onto the last element, but there are no elements"); + + if last_pair.punctuation().is_some() { + self.pairs.push(last_pair); + panic!("push_punctuated adds the punctuation onto the last element, but the last element already has punctuation"); + } + + self.pairs.push(Pair::Punctuated(last_pair.into_value(), punctuation)); + self.pairs.push(Pair::new(value, None)); + } +} + +impl<T> Default for Punctuated<T> { + fn default() -> Self { + Self::new() + } +} + +impl<T> Sealed for Punctuated<T> {} + +impl<T: Node> Node for Punctuated<T> { + fn start_position(&self) -> Option<Position> { + self.pairs.first()?.start_position() + } + + fn end_position(&self) -> Option<Position> { + self.pairs.last()?.end_position() + } + + fn similar(&self, other: &Self) -> bool { + self.into_iter() + .collect::<Vec<_>>() + .similar(&other.into_iter().collect::<Vec<_>>()) + } + + fn tokens(&self) -> Tokens { + self.pairs.tokens() + } +} + +impl<T: Visit> Visit for Punctuated<T> { + fn visit<V: Visitor>(&self, visitor: &mut V) { + self.pairs.visit(visitor); + } +} + +impl<T: VisitMut> VisitMut for Punctuated<T> { + fn visit_mut<V: VisitorMut>(self, visitor: &mut V) -> Self { + Punctuated { pairs: self.pairs.visit_mut(visitor) } + } +} + +impl<T> std::iter::Extend<Pair<T>> for Punctuated<T> { + fn extend<I: IntoIterator<Item = Pair<T>>>(&mut self, iter: I) { + self.pairs.extend(iter); + } +} + +impl<T> IntoIterator for Punctuated<T> { + type Item = T; + type IntoIter = IntoIter<T>; + + fn into_iter(self) -> Self::IntoIter { + IntoIter { inner: self.pairs.into_iter() } + } +} + +impl<T> FromIterator<Pair<T>> for Punctuated<T> { + fn from_iter<I: IntoIterator<Item = Pair<T>>>(iter: I) -> Self { + Punctuated { pairs: iter.into_iter().collect() } + } +} + +impl<'a, T> IntoIterator for &'a Punctuated<T> { + type Item = &'a T; + type IntoIter = Iter<'a, T>; + + fn into_iter(self) -> Self::IntoIter { + Iter { inner: self.pairs.iter() } + } +} + +impl<'a, T> IntoIterator for &'a mut Punctuated<T> { + type Item = &'a mut T; + type IntoIter = IterMut<'a, T>; + + fn into_iter(self) -> Self::IntoIter { + IterMut { inner: self.pairs.iter_mut() } + } +} + +/// An iterator over owned values of type `T`. +/// Refer to the [module documentation](index.html) for more details. +pub struct IntoIter<T> { + inner: std::vec::IntoIter<Pair<T>>, +} + +impl<T> Iterator for IntoIter<T> { + type Item = T; + + fn next(&mut self) -> Option<Self::Item> { + Some(self.inner.next()?.into_value()) + } +} + +/// An iterator over borrowed values of type `&T`. +/// Refer to the [module documentation](index.html) for more details. +pub struct Iter<'a, T> { + inner: std::slice::Iter<'a, Pair<T>>, +} + +impl<'a, T> Iterator for Iter<'a, T> { + type Item = &'a T; + + fn next(&mut self) -> Option<Self::Item> { + Some(self.inner.next()?.value()) + } +} + +/// An iterator over borrowed values of type `&mut T`. +/// Refer to the [module documentation](index.html) for more details. +pub struct IterMut<'a, T> { + inner: std::slice::IterMut<'a, Pair<T>>, +} + +impl<'a, T> Iterator for IterMut<'a, T> { + type Item = &'a mut T; + + fn next(&mut self) -> Option<Self::Item> { + Some(self.inner.next()?.value_mut()) + } +} + +/// A node `T` followed by the possible trailing +/// [`TokenReference`](crate::tokenizer::TokenReference). +/// Refer to the [module documentation](index.html) for more details. +#[derive(Clone, Debug, Display, PartialEq, Eq, Deserialize, Serialize)] +#[display(bound(T: Display))] +pub enum Pair<T> { + /// A node `T` with no trailing punctuation + #[display("{_0}")] + End(T), + + /// A node `T` followed by punctuation (in the form of a + /// [`TokenReference`](crate::tokenizer::TokenReference)) + #[display("{_0}{_1}")] + Punctuated(T, TokenReference), +} + +impl<T> Pair<T> { + /// Creates a `Pair` with node `T` and optional punctuation + /// ```rust + /// # use vvs_parser::prelude::ast::*; + /// let pair = Pair::new(1, None); + /// ``` + pub fn new(value: T, punctuation: Option<TokenReference>) -> Self { + match punctuation { + None => Pair::End(value), + Some(punctuation) => Pair::Punctuated(value, punctuation), + } + } + + /// Takes the `Pair` and returns the node `T` and the punctuation, if it exists as a tuple + /// ```rust + /// # use vvs_parser::prelude::ast::*; + /// let pair = Pair::new(1, None); + /// assert_eq!(pair.into_tuple(), (1, None)); + /// ``` + pub fn into_tuple(self) -> (T, Option<TokenReference>) { + match self { + Pair::End(value) => (value, None), + Pair::Punctuated(value, punctuation) => (value, Some(punctuation)), + } + } + + /// Takes the `Pair` and returns the node `T` + /// ```rust + /// # use vvs_parser::prelude::ast::*; + /// let pair = Pair::new(1, None); + /// assert_eq!(pair.into_value(), 1); + /// ``` + pub fn into_value(self) -> T { + self.into_tuple().0 + } + + /// Returns a reference to the node `T` + /// ```rust + /// # use vvs_parser::prelude::ast::*; + /// let pair = Pair::new(1, None); + /// assert_eq!(pair.value(), &1); + /// ``` + pub fn value(&self) -> &T { + match self { + Pair::End(value) => value, + Pair::Punctuated(value, _) => value, + } + } + + /// Returns a mutable reference to the node `T` + /// ```rust + /// # use vvs_parser::prelude::ast::*; + /// let mut pair = Pair::new(1, None); + /// *pair.value_mut() += 1; + /// assert_eq!(pair.into_value(), 2); + /// ``` + pub fn value_mut(&mut self) -> &mut T { + match self { + Pair::End(value) => value, + Pair::Punctuated(value, _) => value, + } + } + + /// Returns the trailing punctuation, if it exists + /// ```rust + /// # use vvs_parser::prelude::ast::*; + /// let pair = Pair::new(1, None); + /// assert_eq!(pair.punctuation(), None); + /// ``` + pub fn punctuation(&self) -> Option<&TokenReference> { + match self { + Pair::End(_) => None, + Pair::Punctuated(_, punctuation) => Some(punctuation), + } + } + + /// Maps a `Pair<T>` to a `Pair<U>` by applying a function to the value of the pair, + /// while preserving punctuation if it is not the end. + /// ```rust + /// # use vvs_parser::prelude::ast::*; + /// let pair = Pair::new(2, None); + /// assert_eq!(*pair.map(|i| i * 2).value(), 4); + /// ``` + pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Pair<U> { + match self { + Pair::End(value) => Pair::End(f(value)), + Pair::Punctuated(value, punctuated) => Pair::Punctuated(f(value), punctuated), + } + } +} + +impl<T> Sealed for Pair<T> {} + +impl<T: Node> Node for Pair<T> { + fn start_position(&self) -> Option<Position> { + self.value().start_position() + } + + fn end_position(&self) -> Option<Position> { + self.punctuation() + .and_then(Node::end_position) + .or_else(|| self.value().end_position()) + } + + fn similar(&self, other: &Self) -> bool { + self.value().similar(other.value()) + } + + fn tokens(&self) -> Tokens { + match self { + Pair::Punctuated(node, separator) => { + let mut items = node.tokens().items; + items.push(TokenItem::TokenReference(separator)); + Tokens { items } + } + Pair::End(node) => node.tokens(), + } + } +} + +impl<T: Visit> Visit for Pair<T> { + fn visit<V: Visitor>(&self, visitor: &mut V) { + match self { + Pair::End(value) => value.visit(visitor), + Pair::Punctuated(value, punctuation) => { + value.visit(visitor); + punctuation.visit(visitor); + } + } + } +} + +impl<T: VisitMut> VisitMut for Pair<T> { + fn visit_mut<V: VisitorMut>(self, visitor: &mut V) -> Self { + match self { + Pair::End(value) => Pair::End(value.visit_mut(visitor)), + Pair::Punctuated(value, punctuation) => { + Pair::Punctuated(value.visit_mut(visitor), punctuation.visit_mut(visitor)) + } + } + } +} diff --git a/src/Rust/vvs_parser/src/ast/span.rs b/src/Rust/vvs_parser/src/ast/span.rs new file mode 100644 index 0000000000000000000000000000000000000000..1b14ca1d8d5584eb225cf3e36ba921c281e1a5f5 --- /dev/null +++ b/src/Rust/vvs_parser/src/ast/span.rs @@ -0,0 +1,55 @@ +//! A representation of a "contained span", or a span within specific bounds. +//! +//! Examples of contained spans include: +//! - Arguments in a function call use parentheses `(...)` +//! - Indexing a table uses brackets `[...]` +//! - Creating a table uses braces `{...}` +//! +//! Contained spans don't contain the inner data, just the start and end bounds. + +use crate::{ + node::{Node, Tokens}, + private::Sealed, + tokenizer::{Position, TokenReference}, +}; +use serde::{Deserialize, Serialize}; +use vvs_parser_derive::Visit; + +/// A contained span with the beginning and ending bounds. +/// Refer to the [module documentation](index.html) for more details. +#[derive(Clone, Debug, PartialEq, Eq, Visit, Deserialize, Serialize)] +pub struct ContainedSpan { + pub(crate) tokens: (TokenReference, TokenReference), +} + +impl ContainedSpan { + /// Creates a contained span from the start and end bounds + pub fn new(start: TokenReference, end: TokenReference) -> Self { + Self { tokens: (start, end) } + } + + /// Returns the start and end bounds in a tuple as references + pub fn tokens(&self) -> (&TokenReference, &TokenReference) { + (&self.tokens.0, &self.tokens.1) + } +} + +impl Node for ContainedSpan { + fn start_position(&self) -> Option<Position> { + self.tokens.0.start_position() + } + + fn end_position(&self) -> Option<Position> { + self.tokens.1.end_position() + } + + fn similar(&self, other: &Self) -> bool { + self.tokens.0.similar(&other.tokens.0) && self.tokens.1.similar(&other.tokens.1) + } + + fn tokens(&self) -> Tokens { + self.tokens.tokens() + } +} + +impl Sealed for ContainedSpan {} diff --git a/src/Rust/vvs_parser/src/ast/update_positions.rs b/src/Rust/vvs_parser/src/ast/update_positions.rs new file mode 100644 index 0000000000000000000000000000000000000000..6939b6f9411791a9b6bb814501cae00a3355fe28 --- /dev/null +++ b/src/Rust/vvs_parser/src/ast/update_positions.rs @@ -0,0 +1,87 @@ +use crate::{ + ast::Ast, + tokenizer::{Position, Token, TokenKind, TokenReference}, + visitors::VisitorMut, +}; + +#[derive(Default)] +struct UpdatePositionsRewriter { + start_position: Position, + next_is_new_line: bool, +} + +impl UpdatePositionsRewriter { + fn update_token(&mut self, token: &Token) -> Token { + let display = token.to_string(); + let mut end_position = self.start_position; + if token.token_kind() != TokenKind::Eof { + for character in display.chars() { + if self.next_is_new_line { + self.next_is_new_line = false; + end_position.line += 1; + end_position.character = 1; + } + + if character == '\n' { + self.next_is_new_line = true; + } else { + end_position.character += 1; + } + + end_position.bytes += character.len_utf8(); + } + } + + let result = + Token { start_position: self.start_position, end_position, token_type: token.token_type.to_owned() }; + + if self.next_is_new_line { + self.next_is_new_line = false; + end_position.line += 1; + end_position.character = 1; + } + + self.start_position = end_position; + result + } +} + +impl VisitorMut for UpdatePositionsRewriter { + fn visit_token_reference(&mut self, token: TokenReference) -> TokenReference { + TokenReference::new( + token.leading_trivia().map(|token| self.update_token(token)).collect(), + self.update_token(token.token()), + token.trailing_trivia().map(|token| self.update_token(token)).collect(), + ) + } +} + +impl Ast { + /// Will update the positions of all the tokens in the tree + /// Necessary if you are both mutating the tree and need the positions of the tokens + pub fn update_positions(self) -> Self { + UpdatePositionsRewriter { start_position: Position { bytes: 0, character: 1, line: 1 }, ..Default::default() } + .visit_ast(self) + } +} + +#[cfg(test)] +mod tests { + use crate::{node::Node, prelude::parser::parse_lua_tree}; + + #[test] + fn test_update_positions_validity() { + let ast = parse_lua_tree("local foo = 1\nlocal bar = 2").unwrap(); + let old_positions: Vec<_> = ast + .tokens() + .map(|token| (token.start_position(), token.end_position())) + .collect(); + let ast = ast.update_positions(); + assert_eq!( + old_positions, + ast.tokens() + .map(|token| (token.start_position(), token.end_position())) + .collect::<Vec<_>>(), + ); + } +} diff --git a/src/Rust/vvs_parser/src/ast/visitors.rs b/src/Rust/vvs_parser/src/ast/visitors.rs new file mode 100644 index 0000000000000000000000000000000000000000..b95353f395d6cbd2e878f03a03699abe239e54bf --- /dev/null +++ b/src/Rust/vvs_parser/src/ast/visitors.rs @@ -0,0 +1,526 @@ +// Implementations of Visit and VisitMut that are not able to be automatically derived yet. +// Ideally everything would be derived. +use super::*; +use crate::visitors::{Visit, VisitMut, Visitor, VisitorMut}; + +// The following have `ContainedSpan`, which when automatically derived will visit the tokens containing +// before they visit what they're actually containing. +// For example, if there is an AST node that represents `(foo)`... +// Then visitors will visit this as `()foo`. +// This is fixed for structs with `#[visit(contains = "...")], but this is not supported on enums. + +impl Visit for Field { + fn visit<V: Visitor>(&self, visitor: &mut V) { + visitor.visit_field(self); + match self { + Field::ExpressionKey { brackets, key, equal, value } => { + brackets.tokens.0.visit(visitor); + key.visit(visitor); + brackets.tokens.1.visit(visitor); + equal.visit(visitor); + value.visit(visitor); + } + Field::NameKey { key, equal, value } => { + key.visit(visitor); + equal.visit(visitor); + value.visit(visitor); + } + Field::NoKey(self_0) => self_0.visit(visitor), + }; + visitor.visit_field_end(self); + } +} + +impl VisitMut for Field { + fn visit_mut<V: VisitorMut>(mut self, visitor: &mut V) -> Self { + self = visitor.visit_field(self); + self = match self { + Field::ExpressionKey { mut brackets, mut key, equal, value } => { + brackets.tokens.0 = brackets.tokens.0.visit_mut(visitor); + key = key.visit_mut(visitor); + brackets.tokens.1 = brackets.tokens.1.visit_mut(visitor); + Field::ExpressionKey { brackets, key, equal: equal.visit_mut(visitor), value: value.visit_mut(visitor) } + } + Field::NameKey { key, equal, value } => Field::NameKey { + key: key.visit_mut(visitor), + equal: equal.visit_mut(visitor), + value: value.visit_mut(visitor), + }, + Field::NoKey(self_0) => Field::NoKey(self_0.visit_mut(visitor)), + }; + self = visitor.visit_field_end(self); + self + } +} + +impl Visit for Expression { + fn visit<V: Visitor>(&self, visitor: &mut V) { + visitor.visit_expression(self); + match self { + Expression::BinaryOperator { lhs, binop, rhs } => { + lhs.visit(visitor); + binop.visit(visitor); + rhs.visit(visitor); + } + Expression::Parentheses { contained, expression } => { + contained.tokens.0.visit(visitor); + expression.visit(visitor); + contained.tokens.1.visit(visitor); + } + Expression::UnaryOperator { unop, expression } => { + unop.visit(visitor); + expression.visit(visitor); + } + Expression::Function(func) => { + func.0.visit(visitor); + func.1.visit(visitor); + } + Expression::TypeAssertion { expression, type_assertion } => { + expression.visit(visitor); + type_assertion.visit(visitor); + } + Expression::Number(token) | Expression::String(token) | Expression::Symbol(token) => { + token.visit(visitor); + } + Expression::FunctionCall(function_call) => function_call.visit(visitor), + Expression::IfExpression(if_expression) => if_expression.visit(visitor), + Expression::TableConstructor(table_constructor) => table_constructor.visit(visitor), + Expression::Var(var) => var.visit(visitor), + }; + visitor.visit_expression_end(self); + } +} + +impl VisitMut for Expression { + fn visit_mut<V: VisitorMut>(mut self, visitor: &mut V) -> Self { + self = visitor.visit_expression(self); + self = match self { + Expression::BinaryOperator { lhs, binop, rhs } => Expression::BinaryOperator { + lhs: lhs.visit_mut(visitor), + binop: binop.visit_mut(visitor), + rhs: rhs.visit_mut(visitor), + }, + Expression::Parentheses { mut contained, mut expression } => { + contained.tokens.0 = contained.tokens.0.visit_mut(visitor); + expression = expression.visit_mut(visitor); + contained.tokens.1 = contained.tokens.1.visit_mut(visitor); + Expression::Parentheses { contained, expression } + } + Expression::UnaryOperator { unop, expression } => { + Expression::UnaryOperator { unop: unop.visit_mut(visitor), expression: expression.visit_mut(visitor) } + } + Expression::Function(func) => { + Expression::Function(Box::new((func.0.visit_mut(visitor), func.1.visit_mut(visitor)))) + } + Expression::FunctionCall(function_call) => Expression::FunctionCall(function_call.visit_mut(visitor)), + Expression::IfExpression(if_expression) => Expression::IfExpression(if_expression.visit_mut(visitor)), + Expression::TableConstructor(table_constructor) => { + Expression::TableConstructor(table_constructor.visit_mut(visitor)) + } + Expression::TypeAssertion { expression, type_assertion } => Expression::TypeAssertion { + expression: expression.visit_mut(visitor), + type_assertion: type_assertion.visit_mut(visitor), + }, + Expression::Number(token) => Expression::Number(token.visit_mut(visitor)), + Expression::String(token) => Expression::String(token.visit_mut(visitor)), + Expression::Symbol(token) => Expression::Symbol(token.visit_mut(visitor)), + Expression::Var(var) => Expression::Var(var.visit_mut(visitor)), + }; + self = visitor.visit_expression_end(self); + self + } +} + +impl Visit for Index { + fn visit<V: Visitor>(&self, visitor: &mut V) { + visitor.visit_index(self); + match self { + Index::Brackets { brackets, expression } => { + brackets.tokens.0.visit(visitor); + expression.visit(visitor); + brackets.tokens.1.visit(visitor); + } + Index::Dot { dot, name } => { + dot.visit(visitor); + name.visit(visitor); + } + }; + visitor.visit_index_end(self); + } +} + +impl VisitMut for Index { + fn visit_mut<V: VisitorMut>(mut self, visitor: &mut V) -> Self { + self = visitor.visit_index(self); + self = match self { + Index::Brackets { mut brackets, mut expression } => { + brackets.tokens.0 = brackets.tokens.0.visit_mut(visitor); + expression = expression.visit_mut(visitor); + brackets.tokens.1 = brackets.tokens.1.visit_mut(visitor); + Index::Brackets { brackets, expression } + } + Index::Dot { dot, name } => Index::Dot { dot: dot.visit_mut(visitor), name: name.visit_mut(visitor) }, + }; + self = visitor.visit_index_end(self); + self + } +} + +impl Visit for FunctionArgs { + fn visit<V: Visitor>(&self, visitor: &mut V) { + visitor.visit_function_args(self); + match self { + FunctionArgs::Parentheses { parentheses, arguments } => { + parentheses.tokens.0.visit(visitor); + arguments.visit(visitor); + parentheses.tokens.1.visit(visitor); + } + FunctionArgs::String(self_0) => self_0.visit(visitor), + FunctionArgs::TableConstructor(self_0) => self_0.visit(visitor), + }; + visitor.visit_function_args_end(self); + } +} + +impl VisitMut for FunctionArgs { + fn visit_mut<V: VisitorMut>(mut self, visitor: &mut V) -> Self { + self = visitor.visit_function_args(self); + self = match self { + FunctionArgs::Parentheses { mut parentheses, mut arguments } => { + parentheses.tokens.0 = parentheses.tokens.0.visit_mut(visitor); + arguments = arguments.visit_mut(visitor); + parentheses.tokens.1 = parentheses.tokens.1.visit_mut(visitor); + FunctionArgs::Parentheses { parentheses, arguments } + } + FunctionArgs::String(self_0) => FunctionArgs::String(self_0.visit_mut(visitor)), + FunctionArgs::TableConstructor(self_0) => FunctionArgs::TableConstructor(self_0.visit_mut(visitor)), + }; + self = visitor.visit_function_args_end(self); + self + } +} + +// The following contain type signatures, which are addendums to previous identities +impl Visit for FunctionBody { + fn visit<V: Visitor>(&self, visitor: &mut V) { + visitor.visit_function_body(self); + self.parameters_parentheses.tokens.0.visit(visitor); + let mut type_specifiers = self.type_specifiers(); + + for parameter in &self.parameters { + parameter.visit(visitor); + type_specifiers.next().visit(visitor); + } + + self.parameters_parentheses.tokens.1.visit(visitor); + self.return_type.visit(visitor); + self.block.visit(visitor); + self.end_token.visit(visitor); + visitor.visit_function_body_end(self); + } +} + +impl VisitMut for FunctionBody { + fn visit_mut<V: VisitorMut>(mut self, visitor: &mut V) -> Self { + self = visitor.visit_function_body(self); + self.parameters_parentheses.tokens.0 = self.parameters_parentheses.tokens.0.visit_mut(visitor); + let mut type_specifiers = self.type_specifiers.into_iter(); + let mut new_type_specifiers = Vec::new(); + let mut new_parameters = Punctuated::new(); + + for parameter_pair in self.parameters.into_pairs() { + let parameter_tuple = parameter_pair.into_tuple(); + let parameter = parameter_tuple.0.visit_mut(visitor); + let type_specifier = type_specifiers + .next() + .and_then(|type_specifier| type_specifier) + .map(|type_specifier| type_specifier.visit_mut(visitor)); + new_type_specifiers.push(type_specifier); + let punctuation = parameter_tuple.1.visit_mut(visitor); + new_parameters.push(Pair::new(parameter, punctuation)); + } + + self.parameters = new_parameters; + self.type_specifiers = new_type_specifiers; + self.parameters_parentheses.tokens.1 = self.parameters_parentheses.tokens.1.visit_mut(visitor); + self.return_type = self.return_type.visit_mut(visitor); + self.block = self.block.visit_mut(visitor); + self.end_token = self.end_token.visit_mut(visitor); + self = visitor.visit_function_body_end(self); + self + } +} + +impl Visit for LocalAssignment { + fn visit<V: Visitor>(&self, visitor: &mut V) { + visitor.visit_local_assignment(self); + self.local_token.visit(visitor); + + let mut attributes = self.attributes(); + let mut type_specifiers = self.type_specifiers(); + for name in &self.name_list { + name.visit(visitor); + attributes.next().visit(visitor); + type_specifiers.next().visit(visitor); + } + + self.equal_token.visit(visitor); + self.expr_list.visit(visitor); + visitor.visit_local_assignment_end(self); + } +} + +impl VisitMut for LocalAssignment { + fn visit_mut<V: VisitorMut>(mut self, visitor: &mut V) -> Self { + self = visitor.visit_local_assignment(self); + self.local_token = self.local_token.visit_mut(visitor); + + let mut attributes = self.attributes.into_iter(); + let mut type_specifiers = self.type_specifiers.into_iter(); + let mut new_attributes = Vec::new(); + let mut new_type_specifiers = Vec::new(); + let mut new_names = Punctuated::new(); + + for parameter_pair in self.name_list.into_pairs() { + let parameter_tuple = parameter_pair.into_tuple(); + let parameter = parameter_tuple.0.visit_mut(visitor); + let attribute = attributes + .next() + .flatten() + .map(|attribute| attribute.visit_mut(visitor)); + let type_specifier = type_specifiers + .next() + .flatten() + .map(|type_specifier| type_specifier.visit_mut(visitor)); + + let punctuation = parameter_tuple.1.visit_mut(visitor); + new_attributes.push(attribute); + new_type_specifiers.push(type_specifier); + new_names.push(Pair::new(parameter, punctuation)); + } + + self.name_list = new_names; + self.attributes = new_attributes; + self.type_specifiers = new_type_specifiers; + self.equal_token = self.equal_token.visit_mut(visitor); + self.expr_list = self.expr_list.visit_mut(visitor); + self = visitor.visit_local_assignment_end(self); + self + } +} + +impl Visit for GenericFor { + fn visit<V: Visitor>(&self, visitor: &mut V) { + visitor.visit_generic_for(self); + self.for_token.visit(visitor); + + let mut type_specifiers = self.type_specifiers(); + for name in &self.names { + name.visit(visitor); + type_specifiers.next().visit(visitor); + } + + self.in_token.visit(visitor); + self.expr_list.visit(visitor); + self.do_token.visit(visitor); + self.block.visit(visitor); + self.end_token.visit(visitor); + + visitor.visit_generic_for_end(self); + } +} + +impl VisitMut for GenericFor { + fn visit_mut<V: VisitorMut>(mut self, visitor: &mut V) -> Self { + self = visitor.visit_generic_for(self); + self.for_token = self.for_token.visit_mut(visitor); + + let mut type_specifiers = self.type_specifiers.into_iter(); + let mut new_type_specifiers = Vec::new(); + let mut new_names = Punctuated::new(); + + for parameter_pair in self.names.into_pairs() { + let parameter_tuple = parameter_pair.into_tuple(); + let parameter = parameter_tuple.0.visit_mut(visitor); + let type_specifier = type_specifiers + .next() + .and_then(|type_specifier| type_specifier) + .map(|type_specifier| type_specifier.visit_mut(visitor)); + + let punctuation = parameter_tuple.1.visit_mut(visitor); + new_type_specifiers.push(type_specifier); + new_names.push(Pair::new(parameter, punctuation)); + } + + self.names = new_names; + self.type_specifiers = new_type_specifiers; + self.in_token = self.in_token.visit_mut(visitor); + self.expr_list = self.expr_list.visit_mut(visitor); + self.do_token = self.do_token.visit_mut(visitor); + self.block = self.block.visit_mut(visitor); + self.end_token = self.end_token.visit_mut(visitor); + + self = visitor.visit_generic_for_end(self); + self + } +} + +impl Visit for NumericFor { + fn visit<V: Visitor>(&self, visitor: &mut V) { + visitor.visit_numeric_for(self); + self.for_token.visit(visitor); + self.index_variable.visit(visitor); + self.type_specifier.visit(visitor); + self.equal_token.visit(visitor); + self.start.visit(visitor); + self.start_end_comma.visit(visitor); + self.end.visit(visitor); + self.end_step_comma.visit(visitor); + self.step.visit(visitor); + self.do_token.visit(visitor); + self.block.visit(visitor); + self.end_token.visit(visitor); + visitor.visit_numeric_for_end(self); + } +} + +impl VisitMut for NumericFor { + fn visit_mut<V: VisitorMut>(mut self, visitor: &mut V) -> Self { + self = visitor.visit_numeric_for(self); + self.for_token = self.for_token.visit_mut(visitor); + self.index_variable = self.index_variable.visit_mut(visitor); + self.type_specifier = self.type_specifier.visit_mut(visitor); + self.equal_token = self.equal_token.visit_mut(visitor); + self.start = self.start.visit_mut(visitor); + self.start_end_comma = self.start_end_comma.visit_mut(visitor); + self.end = self.end.visit_mut(visitor); + self.end_step_comma = self.end_step_comma.visit_mut(visitor); + self.step = self.step.visit_mut(visitor); + self.do_token = self.do_token.visit_mut(visitor); + self.block = self.block.visit_mut(visitor); + self.end_token = self.end_token.visit_mut(visitor); + self = visitor.visit_numeric_for_end(self); + self + } +} + +impl Visit for TypeInfo { + fn visit<V: Visitor>(&self, visitor: &mut V) { + visitor.visit_type_info(self); + match self { + TypeInfo::Array { braces, type_info } => { + braces.tokens.0.visit(visitor); + type_info.visit(visitor); + braces.tokens.1.visit(visitor); + } + TypeInfo::Basic(self_0) => self_0.visit(visitor), + TypeInfo::Callback { parentheses, arguments, arrow, return_type } => { + parentheses.tokens.0.visit(visitor); + arguments.visit(visitor); + parentheses.tokens.1.visit(visitor); + arrow.visit(visitor); + return_type.visit(visitor); + } + TypeInfo::Optional { base, question_mark } => { + base.visit(visitor); + question_mark.visit(visitor); + } + TypeInfo::Table { braces, fields } => { + braces.tokens.0.visit(visitor); + fields.visit(visitor); + braces.tokens.1.visit(visitor); + } + TypeInfo::Typeof { typeof_token, parentheses, inner } => { + typeof_token.visit(visitor); + parentheses.tokens.0.visit(visitor); + inner.visit(visitor); + parentheses.tokens.1.visit(visitor); + } + TypeInfo::Tuple { parentheses, types } => { + parentheses.tokens.0.visit(visitor); + types.visit(visitor); + parentheses.tokens.1.visit(visitor); + } + }; + visitor.visit_type_info_end(self); + } +} + +impl VisitMut for TypeInfo { + fn visit_mut<V: VisitorMut>(mut self, visitor: &mut V) -> Self { + self = visitor.visit_type_info(self); + self = match self { + TypeInfo::Array { mut braces, mut type_info } => { + braces.tokens.0 = braces.tokens.0.visit_mut(visitor); + type_info = type_info.visit_mut(visitor); + braces.tokens.1 = braces.tokens.1.visit_mut(visitor); + TypeInfo::Array { braces, type_info } + } + TypeInfo::Basic(self_0) => TypeInfo::Basic(self_0.visit_mut(visitor)), + TypeInfo::Callback { mut parentheses, mut arguments, mut arrow, mut return_type } => { + parentheses.tokens.0 = parentheses.tokens.0.visit_mut(visitor); + arguments = arguments.visit_mut(visitor); + parentheses.tokens.1 = parentheses.tokens.1.visit_mut(visitor); + arrow = arrow.visit_mut(visitor); + return_type = return_type.visit_mut(visitor); + TypeInfo::Callback { parentheses, arguments, arrow, return_type } + } + TypeInfo::Optional { base, question_mark } => { + TypeInfo::Optional { base: base.visit_mut(visitor), question_mark: question_mark.visit_mut(visitor) } + } + TypeInfo::Table { mut braces, mut fields } => { + braces.tokens.0 = braces.tokens.0.visit_mut(visitor); + fields = fields.visit_mut(visitor); + braces.tokens.1 = braces.tokens.1.visit_mut(visitor); + TypeInfo::Table { braces, fields } + } + TypeInfo::Typeof { mut typeof_token, mut parentheses, mut inner } => { + typeof_token = typeof_token.visit_mut(visitor); + parentheses.tokens.0 = parentheses.tokens.0.visit_mut(visitor); + inner = inner.visit_mut(visitor); + parentheses.tokens.1 = parentheses.tokens.1.visit_mut(visitor); + TypeInfo::Typeof { typeof_token, parentheses, inner } + } + TypeInfo::Tuple { mut parentheses, mut types } => { + parentheses.tokens.0 = parentheses.tokens.0.visit_mut(visitor); + types = types.visit_mut(visitor); + parentheses.tokens.1 = parentheses.tokens.1.visit_mut(visitor); + TypeInfo::Tuple { parentheses, types } + } + }; + self = visitor.visit_type_info_end(self); + self + } +} + +impl Visit for TypeFieldKey { + fn visit<V: Visitor>(&self, visitor: &mut V) { + visitor.visit_type_field_key(self); + match self { + TypeFieldKey::Name(self_0) => self_0.visit(visitor), + TypeFieldKey::IndexSignature { brackets, inner } => { + brackets.tokens.0.visit(visitor); + inner.visit(visitor); + brackets.tokens.1.visit(visitor); + } + }; + visitor.visit_type_field_key_end(self); + } +} + +impl VisitMut for TypeFieldKey { + fn visit_mut<V: VisitorMut>(mut self, visitor: &mut V) -> Self { + self = visitor.visit_type_field_key(self); + self = match self { + TypeFieldKey::Name(self_0) => TypeFieldKey::Name(self_0.visit_mut(visitor)), + TypeFieldKey::IndexSignature { mut brackets, mut inner } => { + brackets.tokens.0 = brackets.tokens.0.visit_mut(visitor); + inner = inner.visit_mut(visitor); + brackets.tokens.1 = brackets.tokens.1.visit_mut(visitor); + TypeFieldKey::IndexSignature { brackets, inner } + } + }; + self = visitor.visit_type_field_key_end(self); + self + } +} diff --git a/src/Rust/vvs_parser/src/error.rs b/src/Rust/vvs_parser/src/error.rs new file mode 100644 index 0000000000000000000000000000000000000000..226e331f46bbb919751f96a9f4c84bd74e1377c0 --- /dev/null +++ b/src/Rust/vvs_parser/src/error.rs @@ -0,0 +1,59 @@ +//! Special errors for the Vivy Script package, so we don't expose anything with anyhow. + +use crate::{ + ast::AstError, + tokenizer::{Position, TokenizerError}, +}; +use derive_more::{Display, From}; +use serde::{Deserialize, Serialize}; +use std::{borrow::Cow, ops}; + +/// An error type that consists of both [`AstError`](ast::AstError) and [`TokenizerError`](tokenizer::TokenizerError) +/// Used by [`parse`] +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, From, Display)] +pub enum Error { + /// Triggered if there's an issue creating an AST, but tokenizing must have succeeded + #[display("error occurred while creating ast: {_0}")] + AstError(AstError), + + /// Triggered if there's an issue when tokenizing, and an AST can't be made + #[display("error occurred while tokenizing: {_0}")] + TokenizerError(TokenizerError), +} + +impl Error { + /// Returns a human readable error message + pub fn error_message(&self) -> Cow<'static, str> { + match self { + Error::AstError(error) => error.error_message(), + Error::TokenizerError(error) => error.to_string().into(), + } + } + + /// Returns the range of the error + pub fn range(&self) -> (Position, Position) { + match self { + Error::AstError(error) => error.range(), + Error::TokenizerError(error) => error.range(), + } + } + + /// Returns the range of the error in bytes + pub fn byte_range(&self) -> ops::Range<usize> { + let (start, end) = match self { + Error::AstError(error) => error.range(), + Error::TokenizerError(error) => error.range(), + }; + start.bytes()..end.bytes() + } + + /// Get the error code. + pub fn error_code(&self) -> &'static str { + match self { + Error::AstError(_) => "ast", + Error::TokenizerError(_) => "tokenizer", + } + } +} + +impl std::error::Error for Error {} diff --git a/src/Rust/vvs_parser/src/lib.rs b/src/Rust/vvs_parser/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..63d28204f9e095bd7711a1665f3b5c981b191cb8 --- /dev/null +++ b/src/Rust/vvs_parser/src/lib.rs @@ -0,0 +1,57 @@ +#![warn(missing_docs)] +#![allow(clippy::large_enum_variant)] + +//! # Vivy Script Parser. +//! +//! `vvs_parser` is a lossless parser for Vivy Script, inspired by Lua and Luau. + +mod ast; +mod error; +mod node; +mod private; +mod short_string; +mod tokenizer; +mod traits; +mod util; +mod visitors; +mod vivy; + +#[cfg(test)] +mod tests; + +use crate::{error::Error, short_string::ShortString}; + +/// Crates depending upon [vss_parser] may import the prelude. +pub mod prelude { + /// Re-export everything that is linked to the [Ast]. + pub mod ast { + pub use crate::{ast::*, node::*, short_string::ShortString, tokenizer::*, visitors::*}; + } + + /// Parsers, get the raw representation of things without transforming or checking the + /// resulting things. May be used for debug or test only. + pub mod parser { + /// Creates an [`Ast`](ast::Ast) for VivyScript code. + /// + /// Note that the resulting code may not be entirely valid! You need to pass it into the + /// [CompilerPipeline] for that! + /// + /// # Errors + /// If the code passed cannot be tokenized, a TokenizerError will be returned. + /// If the code passed is not valid Lua 5.1 code, an AstError will be returned, + /// specifically AstError::UnexpectedToken. + pub fn parse_lua_tree(code: &str) -> Result<crate::ast::Ast, Vec<crate::Error>> { + crate::ast::AstResult::parse_fallible(code).into_result() + } + + /// Given code, will produce an [`ast::OptionTableResult`]. This OptionTableResult always produces + /// some [OptionTableResult], regardless of errors. If a partial Ast is produced (i.e. if there are + /// any errors), a few guarantees are lost. The same remarks can be made as [parse_fallible]. + pub fn parse_options_tree(code: &str) -> Result<crate::ast::OptionTable, Vec<crate::Error>> { + crate::ast::OptionTableResult::parse_fallible(code).into_result() + } + } + + pub use crate::error::Error as VVSParserError; + pub use crate::vivy::*; +} diff --git a/src/Rust/vvs_parser/src/node.rs b/src/Rust/vvs_parser/src/node.rs new file mode 100644 index 0000000000000000000000000000000000000000..dfe90349e1c25e5fc2e6243c69b1910eeeb50916 --- /dev/null +++ b/src/Rust/vvs_parser/src/node.rs @@ -0,0 +1,264 @@ +//! Contains the `Node` trait, implemented on all nodes + +use crate::{ + ast::Ast, + private, + tokenizer::{Position, Token, TokenReference}, +}; +use std::fmt; + +/// Used to represent nodes such as tokens or function definitions +/// +/// This trait is sealed and cannot be implemented for types outside of `full-moon` +pub trait Node: private::Sealed { + /// The start position of a node. None if can't be determined + fn start_position(&self) -> Option<Position>; + + /// The end position of a node. None if it can't be determined + fn end_position(&self) -> Option<Position>; + + /// Whether another node of the same type is the same as this one semantically, ignoring position + fn similar(&self, other: &Self) -> bool + where + Self: Sized; + + /// The token references that comprise a node + fn tokens(&self) -> Tokens; + + /// The full range of a node, if it has both start and end positions + fn range(&self) -> Option<(Position, Position)> { + Some((self.start_position()?, self.end_position()?)) + } + + /// The tokens surrounding a node that are ignored and not accessible through the node's own accessors. + /// Use this if you want to get surrounding comments or whitespace. + /// Returns a tuple of the leading and trailing trivia. + fn surrounding_trivia(&self) -> (Vec<&Token>, Vec<&Token>) { + let mut tokens = self.tokens(); + let leading = tokens.next().map(|token| token.leading_trivia().collect()); + let trailing = tokens.next_back().map(|token| token.trailing_trivia().collect()); + (leading.unwrap_or_default(), trailing.unwrap_or_default()) + } +} + +pub(crate) enum TokenItem<'a> { + MoreTokens(&'a dyn Node), + TokenReference(&'a TokenReference), +} + +impl fmt::Debug for TokenItem<'_> { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + TokenItem::MoreTokens(_) => write!(formatter, "TokenItem::MoreTokens"), + TokenItem::TokenReference(token) => { + write!(formatter, "TokenItem::TokenReference({token})") + } + } + } +} + +/// An iterator that iterates over the tokens of a node +/// Returned by [`Node::tokens`] +#[derive(Default)] +pub struct Tokens<'a> { + pub(crate) items: Vec<TokenItem<'a>>, +} + +impl<'a> Iterator for Tokens<'a> { + type Item = &'a TokenReference; + + fn next(&mut self) -> Option<Self::Item> { + if self.items.is_empty() { + return None; + } + + match self.items.remove(0) { + TokenItem::TokenReference(reference) => Some(reference), + TokenItem::MoreTokens(node) => { + let mut tokens = node.tokens(); + tokens.items.append(&mut self.items); + self.items = tokens.items; + self.next() + } + } + } +} + +impl<'a> DoubleEndedIterator for Tokens<'a> { + fn next_back(&mut self) -> Option<Self::Item> { + if self.items.is_empty() { + return None; + } + + match self.items.pop()? { + TokenItem::TokenReference(reference) => Some(reference), + TokenItem::MoreTokens(node) => { + let mut tokens = node.tokens(); + self.items.append(&mut tokens.items); + self.next_back() + } + } + } +} + +impl Node for Ast { + fn start_position(&self) -> Option<Position> { + self.nodes().start_position() + } + + fn end_position(&self) -> Option<Position> { + self.nodes().end_position() + } + + fn similar(&self, other: &Self) -> bool { + self.nodes().similar(other.nodes()) + } + + fn tokens(&self) -> Tokens { + self.nodes().tokens() + } +} + +impl<T: Node> Node for Box<T> { + fn start_position(&self) -> Option<Position> { + (**self).start_position() + } + + fn end_position(&self) -> Option<Position> { + (**self).end_position() + } + + fn similar(&self, other: &Self) -> bool { + (**self).similar(other) + } + + fn tokens(&self) -> Tokens { + (**self).tokens() + } +} + +impl<T: Node> Node for &T { + fn start_position(&self) -> Option<Position> { + (**self).start_position() + } + + fn end_position(&self) -> Option<Position> { + (**self).end_position() + } + + fn similar(&self, other: &Self) -> bool { + (**self).similar(other) + } + + fn tokens(&self) -> Tokens { + (**self).tokens() + } +} + +impl<T: Node> Node for &mut T { + fn start_position(&self) -> Option<Position> { + (**self).start_position() + } + + fn end_position(&self) -> Option<Position> { + (**self).end_position() + } + + fn similar(&self, other: &Self) -> bool { + (**self).similar(other) + } + + fn tokens(&self) -> Tokens { + (**self).tokens() + } +} + +impl Node for TokenReference { + fn start_position(&self) -> Option<Position> { + Some((**self).start_position()) + } + + fn end_position(&self) -> Option<Position> { + Some((**self).end_position()) + } + + fn similar(&self, other: &Self) -> bool { + *self.token_type() == *other.token_type() + } + + fn tokens(&self) -> Tokens { + Tokens { items: vec![TokenItem::TokenReference(self)] } + } +} + +impl<T: Node> Node for Option<T> { + fn start_position(&self) -> Option<Position> { + self.as_ref().and_then(Node::start_position) + } + + fn end_position(&self) -> Option<Position> { + self.as_ref().and_then(Node::end_position) + } + + fn similar(&self, other: &Self) -> bool { + match (self.as_ref(), other.as_ref()) { + (Some(x), Some(y)) => x.similar(y), + (None, None) => true, + _ => false, + } + } + + fn tokens(&self) -> Tokens { + self.as_ref().map(|node| node.tokens()).unwrap_or_default() + } +} + +impl<T: Node> Node for Vec<T> { + fn start_position(&self) -> Option<Position> { + self.first()?.start_position() + } + + fn end_position(&self) -> Option<Position> { + self.last()?.end_position() + } + + fn similar(&self, other: &Self) -> bool { + if self.len() == other.len() { + self.iter().zip(other.iter()).all(|(x, y)| x.similar(y)) + } else { + false + } + } + + fn tokens(&self) -> Tokens { + Tokens { items: self.iter().flat_map(|node| node.tokens().items).collect() } + } +} + +impl<A: Node, B: Node> Node for (A, B) { + fn start_position(&self) -> Option<Position> { + match (self.0.start_position(), self.1.start_position()) { + (Some(x), Some(y)) => Some(std::cmp::min(x, y)), + (Some(x), None) | (None, Some(x)) => Some(x), + (None, None) => None, + } + } + + fn end_position(&self) -> Option<Position> { + match (self.0.end_position(), self.1.end_position()) { + (Some(x), Some(y)) => Some(std::cmp::max(x, y)), + (Some(x), None) | (None, Some(x)) => Some(x), + (None, None) => None, + } + } + + fn similar(&self, other: &Self) -> bool { + self.0.similar(&other.0) && self.1.similar(&other.1) + } + + fn tokens(&self) -> Tokens { + let mut items = self.0.tokens().items; + items.append(&mut self.1.tokens().items); + Tokens { items } + } +} diff --git a/src/Rust/vvs_parser/src/private.rs b/src/Rust/vvs_parser/src/private.rs new file mode 100644 index 0000000000000000000000000000000000000000..8483d03ca722a450bd9468d844c2e12842d1ce27 --- /dev/null +++ b/src/Rust/vvs_parser/src/private.rs @@ -0,0 +1,23 @@ +use crate::{ + ast::{Ast, AstError}, + tokenizer::{Token, TokenReference, TokenType, TokenizerError}, + Error, +}; +use std::borrow::Cow; + +pub trait Sealed {} + +impl<T> Sealed for &T {} +impl<T> Sealed for &mut T {} +impl<T: ToOwned> Sealed for Cow<'_, T> {} +impl Sealed for Ast {} +impl Sealed for AstError {} +impl Sealed for Error {} +impl Sealed for Token {} +impl Sealed for TokenizerError {} +impl Sealed for TokenReference {} +impl Sealed for TokenType {} +impl<T> Sealed for Box<T> {} +impl<T> Sealed for Option<T> {} +impl<T> Sealed for Vec<T> {} +impl<A, B> Sealed for (A, B) {} diff --git a/src/Rust/vvs_parser/src/short_string.rs b/src/Rust/vvs_parser/src/short_string.rs new file mode 100644 index 0000000000000000000000000000000000000000..130edaee84d07ed768249f54e68aa945c7f49b17 --- /dev/null +++ b/src/Rust/vvs_parser/src/short_string.rs @@ -0,0 +1,118 @@ +//! A small string, with short string optimization. + +use serde::{Deserialize, Serialize}; +use smol_str::SmolStr; +use std::{borrow::Borrow, fmt::Display, ops::Deref}; + +/// A string as used in [crate::tokenizer::TokenType] and such. Does short string optimization. +#[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize, Hash, PartialOrd, Ord)] +#[serde(transparent)] +pub struct ShortString(SmolStr); + +impl ShortString { + /// Creates a new ShortString from the given text. + pub fn new<T: Into<String> + AsRef<str>>(text: T) -> Self + where + SmolStr: From<T>, + { + ShortString(SmolStr::from(text)) + } + + /// Constructs inline variant of [ShortString]. + /// + /// Panics if `text.len() > 23`. (See [SmolStr::new_inline]) + #[inline] + pub const fn new_inline(text: &str) -> Self { + ShortString(SmolStr::new_inline(text)) + } + + /// Constructs [ShortString]. Never allocates nor panic. + #[inline] + pub const fn new_static(text: &'static str) -> Self { + if text.len() <= 23 { + Self::new_inline(text) + } else { + ShortString(SmolStr::new_static(text)) + } + } + + /// Returns a `&str` representation of the ShortString. + pub fn as_str(&self) -> &str { + self.0.as_str() + } + + /// Returns the length of the ShortString. + pub fn len(&self) -> usize { + self.0.len() + } + + /// Returns whether or not the ShortString is empty. + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } +} + +impl Display for ShortString { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } +} + +impl Deref for ShortString { + type Target = str; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Borrow<str> for ShortString { + fn borrow(&self) -> &str { + self.as_str() + } +} + +impl AsRef<str> for ShortString { + fn as_ref(&self) -> &str { + self.as_str() + } +} + +impl<T: Into<String> + AsRef<str>> From<T> for ShortString +where + SmolStr: From<T>, +{ + fn from(value: T) -> Self { + ShortString(SmolStr::from(value)) + } +} + +impl From<&ShortString> for ShortString { + fn from(value: &ShortString) -> Self { + value.clone() + } +} + +impl From<ShortString> for String { + fn from(value: ShortString) -> Self { + value.0.to_string() + } +} + +impl FromIterator<char> for ShortString { + fn from_iter<I: IntoIterator<Item = char>>(iter: I) -> Self { + ShortString(SmolStr::from_iter(iter)) + } +} + +#[test] +fn test_build_inline() { + assert_eq!(ShortString::new_inline("12345678901234567890123").len(), 23); + assert_eq!(ShortString::new_static("123456789012345678901230").len(), 24); +} + +#[test] +#[should_panic] +fn test_oversized_inline() { + let _ = ShortString::new_inline("123456789012345678901230"); +} diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..2166604ebbec8743e7913284657b95f7fede1977 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-1/ast.snap @@ -0,0 +1,71 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/assignment-1 +--- +nodes: + stmts: + - - Assignment: + var_list: + pairs: + - End: + Name: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: [] + expr_list: + pairs: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-1/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-1/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..72e2e4103c8115dd2c19c7810e24a881ebd17626 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-1/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/assignment-1 +--- +x = + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-1/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-1/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..dd052ce7a4937e0fdc7f6eb739e11522df94d1e8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-1/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/assignment-1 +--- +error[ast]: expected values to set to + ┌─ source.lua:1:3 + │ +1 │ x = + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-1/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-1/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..8fdfabb4b77157cf8f071f7fd0c2fb962f20174b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-1/errors.snap @@ -0,0 +1,20 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/assignment-1 +--- +- AstError: + token: + start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: "=" + additional: expected values to set to + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..03c979a26bf68aceef72d5b2947a3b4714dc0868 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-1/source.lua @@ -0,0 +1 @@ +x = \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..f4fa4fa5adad880613c8dcfd8ecaec61fc451ca5 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-1/tokens.snap @@ -0,0 +1,50 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/assignment-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..163310d0e7906c866f303a22ee78e39e659ee4a2 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-2/ast.snap @@ -0,0 +1,82 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/assignment-2 +--- +nodes: + stmts: + - - Assignment: + var_list: + pairs: + - End: + Name: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-2/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-2/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..3aac99086e101954f7697ef8a9c1b876204831d0 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-2/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/assignment-2 +--- +"x = " + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-2/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-2/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..94e9ebe9ffe2057f168c63dfdba04239544cb50b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-2/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/assignment-2 +--- +error[ast]: expected values to set to + ┌─ source.lua:1:3 + │ +1 │ x = end + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:5 + │ +1 │ x = end + │ ^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-2/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-2/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..a286586338093cf5c96a54dabf1f2f13a4170c9d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-2/errors.snap @@ -0,0 +1,34 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/assignment-2 +--- +- AstError: + token: + start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: "=" + additional: expected values to set to +- AstError: + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Symbol + symbol: end + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..078176905b4b84ced4d01fc7fe9a7dc03cb95948 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-2/source.lua @@ -0,0 +1 @@ +x = end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..cbed2bbac98c611e923db907be697ae9913bb8fb --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-2/tokens.snap @@ -0,0 +1,72 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/assignment-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-3/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-3/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..1a91149afdb182fea35f5543b554e696acb3e93d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-3/ast.snap @@ -0,0 +1,23 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/assignment-3 +--- +nodes: + stmts: [] +eof: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-3/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-3/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..8adbdbcadae2f0e35697e53d8d1343eea4449d81 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-3/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/assignment-3 +--- +"" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-3/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-3/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..384242f51df9ee6e749c9576046a5e8900050131 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-3/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/assignment-3 +--- +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:1 + │ +1 │ until = 3 + │ ^^^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-3/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-3/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..48344c4d3af390c7230ec7d6ecdbe32f099a9380 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-3/errors.snap @@ -0,0 +1,20 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/assignment-3 +--- +- AstError: + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: until + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-3/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-3/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..43f04f253dc58ee84756c2118fa0e0c4ae4d2115 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-3/source.lua @@ -0,0 +1 @@ +until = 3 \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-3/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-3/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..57970b57f3e5042c08a5188a5cb43891d06c0051 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/assignment-3/tokens.snap @@ -0,0 +1,72 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/assignment-3 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: until +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Number + text: "3" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..53a108c4e3af67f0ffa18e2e8ff802396a87688b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-1/ast.snap @@ -0,0 +1,81 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/bin-op-1 +--- +nodes: + stmts: [] + last_stmt: + - Return: + token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + returns: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-1/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-1/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..5c1cf3b14fb4cc009afd47e3bcefe6680f008c07 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-1/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/bin-op-1 +--- +"return 1 " + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-1/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-1/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..751e6d01bf30930f48c1714599753f285d9db28c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-1/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/bin-op-1 +--- +error[ast]: expected expression after binary operator + ┌─ source.lua:1:10 + │ +1 │ return 1 + + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-1/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-1/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..89abb66ff7731f25d67e9b01fc088a5d66df34b2 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-1/errors.snap @@ -0,0 +1,20 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/bin-op-1 +--- +- AstError: + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: + + additional: expected expression after binary operator + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..b6842ad8d238ce47ce0eed8fdd521ab850e0e652 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-1/source.lua @@ -0,0 +1 @@ +return 1 + \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..3328193814061c6372a7b15d77b1742652add1cc --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-1/tokens.snap @@ -0,0 +1,72 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/bin-op-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Number + text: "1" +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: + +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..244911f1ab7c94f5f8f7e9b871607ef635cb122a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-2/ast.snap @@ -0,0 +1,81 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/bin-op-2 +--- +nodes: + stmts: [] + last_stmt: + - Return: + token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + returns: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-2/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-2/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..f0d37dcbed67421f3d75b80d154191ac18d852df --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-2/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/bin-op-2 +--- +"return 1 " + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-2/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-2/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..606bcb79643bfc9d58217a61fa7b32a31457c652 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-2/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/bin-op-2 +--- +error[ast]: expected expression after binary operator + ┌─ source.lua:1:10 + │ +1 │ return 1 + until + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:12 + │ +1 │ return 1 + until + │ ^^^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-2/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-2/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..6cdc9042b4a8ddaff8f6c0681ad08d46081659b0 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-2/errors.snap @@ -0,0 +1,34 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/bin-op-2 +--- +- AstError: + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: + + additional: expected expression after binary operator +- AstError: + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Symbol + symbol: until + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..f18ec0a95cf6b3b72ac55c64da941ef2af5873b3 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-2/source.lua @@ -0,0 +1 @@ +return 1 + until \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..770706729abe089c4e259240a0d0c4981def4308 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/bin-op-2/tokens.snap @@ -0,0 +1,94 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/bin-op-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Number + text: "1" +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: + +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Symbol + symbol: until +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..5842f2263b63575712fc83140cbe435a731b7eb8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-1/ast.snap @@ -0,0 +1,77 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/call-1 +--- +nodes: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-1/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-1/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..004a49c7b140dce8887a91fedfd53e414f699fb5 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-1/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/call-1 +--- +call() + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-1/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-1/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..fe2ed585b934fef0616fa276fb1302801c58c2ba --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-1/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/call-1 +--- +error[ast]: expected `)` to close function call + ┌─ source.lua:1:5 + │ +1 │ call( + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-1/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-1/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..b1efc06a0e9bda275bf614b5156808191ca88d61 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-1/errors.snap @@ -0,0 +1,20 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/call-1 +--- +- AstError: + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: ( + additional: "expected `)` to close function call" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..f3433589e9d7828c575efa02dd09699ac3180bf9 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-1/source.lua @@ -0,0 +1 @@ +call( \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..0c665ccf19f2dbebb0f9f63b9aaec4c721cbacd9 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-1/tokens.snap @@ -0,0 +1,39 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/call-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..ab8efbb4d04350d44f12db60d337313d600a64f5 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-2/ast.snap @@ -0,0 +1,94 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/call-2 +--- +nodes: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: StringLiteral + literal: hello + quote_type: Double + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-2/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-2/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..894dba2d765ca03687191ec8133e9d84b3222c73 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-2/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/call-2 +--- +"call(\"hello\")" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-2/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-2/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..b00135ec23f09e6afc4040e36b73e119918e0eb3 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-2/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/call-2 +--- +error[ast]: expected `)` to close function call + ┌─ source.lua:1:5 + │ +1 │ call("hello" + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-2/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-2/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..55506155d36b9d8554d45c0c0cc062ced05547b2 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-2/errors.snap @@ -0,0 +1,20 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/call-2 +--- +- AstError: + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: ( + additional: "expected `)` to close function call" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..5457ce11752cb5c1108230fbeff88d7f53f732ac --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-2/source.lua @@ -0,0 +1 @@ +call("hello" \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..cea03670ac7abad6393a3efde06ba36e913cc81e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-2/tokens.snap @@ -0,0 +1,51 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/call-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: StringLiteral + literal: hello + quote_type: Double +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-3/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-3/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..beadf471b4017a6188991b0c4489deab3a3553de --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-3/ast.snap @@ -0,0 +1,136 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/call-3 +--- +nodes: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: + - Punctuated: + - String: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: StringLiteral + literal: hello + quote_type: Double + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: " " + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: StringLiteral + literal: world + quote_type: Double + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-3/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-3/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..04ae5b44063124d728b43e34fcf6544e5bfb6e6b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-3/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/call-3 +--- +"call(\"hello\", \"world\")" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-3/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-3/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..eb09a07012e3660a9e9898c8acf8e83aa26b055e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-3/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/call-3 +--- +error[ast]: expected `)` to close function call + ┌─ source.lua:1:5 + │ +1 │ call("hello", "world" + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-3/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-3/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..083784b640d425d9a90200651826240e1b792d61 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-3/errors.snap @@ -0,0 +1,20 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/call-3 +--- +- AstError: + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: ( + additional: "expected `)` to close function call" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-3/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-3/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..30bd92016172de76cdf86626ed15826fd8f364c2 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-3/source.lua @@ -0,0 +1 @@ +call("hello", "world" \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-3/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-3/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..f04e3f041efce7b0505ebfb530ee07cb5308ffa0 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-3/tokens.snap @@ -0,0 +1,85 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/call-3 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: StringLiteral + literal: hello + quote_type: Double +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: StringLiteral + literal: world + quote_type: Double +- start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-4/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-4/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..215fa48745d3c7ccb9f6787be939f21972ea281a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-4/ast.snap @@ -0,0 +1,77 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/call-4 +--- +nodes: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-4/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-4/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..9571c27f9fe8495f680ec29f83cdcf7989479f8b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-4/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/call-4 +--- +call() + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-4/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-4/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..8e453c8ded59a34534eee64b4f9093fc98460033 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-4/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/call-4 +--- +error[ast]: expected `)` to close function call + ┌─ source.lua:1:5 + │ +1 │ call(end) + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:6 + │ +1 │ call(end) + │ ^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-4/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-4/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..904d3da45dbac7921825fb761e4cae692715115a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-4/errors.snap @@ -0,0 +1,34 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/call-4 +--- +- AstError: + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: ( + additional: "expected `)` to close function call" +- AstError: + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: end + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-4/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-4/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..80e92aba26c937081b4369705c5d20e8b028e50a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-4/source.lua @@ -0,0 +1 @@ +call(end) \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-4/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-4/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..638e16b1948812f1ee1d45d13254bbc0c5ca08d8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/call-4/tokens.snap @@ -0,0 +1,61 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/call-4 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..c13b270f4d04fa5357e3651afd61a93b8c5abeb7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-1/ast.snap @@ -0,0 +1,133 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/do-1 +--- +nodes: + stmts: + - - Do: + do_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 3 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 3 + line: 2 + character: 1 + end_position: + bytes: 4 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 4 + line: 2 + character: 2 + end_position: + bytes: 8 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 8 + line: 2 + character: 6 + end_position: + bytes: 9 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 9 + line: 2 + character: 7 + end_position: + bytes: 10 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: [] + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 2 + character: 8 + end_position: + bytes: 10 + line: 2 + character: 8 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-1/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-1/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..94e4a870df1356c8035f3f3cd96a399992e2fcfb --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-1/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/do-1 +--- +"do\n\tcall()end" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-1/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-1/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..256493136baf42507cfc28ff2a4cb4db912663c1 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-1/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/do-1 +--- +error[ast]: expected `end` to close do block + ┌─ source.lua:2:2 + │ +2 │ call() + │ ^^^^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-1/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-1/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..289afb5847b4b972136f788620bb8de1a057ed7d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-1/errors.snap @@ -0,0 +1,26 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/do-1 +--- +- AstError: + token: + start_position: + bytes: 10 + line: 2 + character: 8 + end_position: + bytes: 10 + line: 2 + character: 8 + token_type: + type: Eof + additional: "expected `end` to close do block" + range: + - bytes: 4 + line: 2 + character: 2 + - bytes: 10 + line: 2 + character: 8 + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..d280f93e03a50bf1b456ed23903b6ac5fa41213f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-1/source.lua @@ -0,0 +1,2 @@ +do + call() \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..51f120520a463459e86054a8785b99f87998f040 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-1/tokens.snap @@ -0,0 +1,83 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/do-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 3 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 3 + line: 2 + character: 1 + end_position: + bytes: 4 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 4 + line: 2 + character: 2 + end_position: + bytes: 8 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 8 + line: 2 + character: 6 + end_position: + bytes: 9 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 9 + line: 2 + character: 7 + end_position: + bytes: 10 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 10 + line: 2 + character: 8 + end_position: + bytes: 10 + line: 2 + character: 8 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..73409e151ab62c3e8964d24b8e051cdec5aadaa4 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-2/ast.snap @@ -0,0 +1,68 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/do-2 +--- +nodes: + stmts: + - - Do: + do_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Whitespace + characters: " " + block: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-2/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-2/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..a858773488261c7c01f28110745fbab4f7c89b89 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-2/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/do-2 +--- +do end + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-2/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-2/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..cc5ae9ca9b2ff24b8f65e369a74c8ff07d76a8bc --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-2/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/do-2 +--- +error[ast]: expected `end` to close do block + ┌─ source.lua:1:1 + │ +1 │ do until end + │ ^^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:4 + │ +1 │ do until end + │ ^^^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-2/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-2/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..e8441877cea4c93261e1c1e4693cdd63eba3899d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-2/errors.snap @@ -0,0 +1,41 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/do-2 +--- +- AstError: + token: + start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: until + additional: "expected `end` to close do block" + range: + - bytes: 0 + line: 1 + character: 1 + - bytes: 2 + line: 1 + character: 3 +- AstError: + token: + start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: until + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..de672635c5ddc5188c9ad34422c1b0fa66656905 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-2/source.lua @@ -0,0 +1 @@ +do until end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..1978377432e424092025faaa9910058387981f0c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/do-2/tokens.snap @@ -0,0 +1,72 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/do-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: until +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..de634353a1d42d4553a4bb516cbdbda7d05e703e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-1/ast.snap @@ -0,0 +1,23 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/function-1 +--- +nodes: + stmts: [] +eof: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-1/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-1/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..906b407ced718cb53c591f9bed5c350890a3c87a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-1/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/function-1 +--- +"" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-1/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-1/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..3d60663607c6ecd74789f2529769951b2a59b5c9 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-1/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/function-1 +--- +error[ast]: expected function name + ┌─ source.lua:1:9 + │ +1 │ function + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-1/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-1/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..7f753354de8cabc728425d72a0544047bc307a25 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-1/errors.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/function-1 +--- +- AstError: + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Eof + additional: expected function name + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..b2e1f1229a51ffc62cbb46d46d72aabdc91403d5 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-1/source.lua @@ -0,0 +1 @@ +function \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..938768d0407411a179be7fc45d67d1ca6abd429e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-1/tokens.snap @@ -0,0 +1,28 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/function-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..cde02936df6dc0cf51c7020c4ef86246955448b2 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-2/ast.snap @@ -0,0 +1,23 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/function-2 +--- +nodes: + stmts: [] +eof: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-2/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-2/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..8812d23d2b5ae42910a4c18369aed5a084fb9f18 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-2/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/function-2 +--- +"" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-2/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-2/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..827de55ed7e806450b078bb6f42dbf6395936a68 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-2/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/function-2 +--- +error[ast]: expected function name + ┌─ source.lua:1:10 + │ +1 │ function end + │ ^^^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:10 + │ +1 │ function end + │ ^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-2/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-2/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..28aa641992564388b4596431264c170cb3f43276 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-2/errors.snap @@ -0,0 +1,34 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/function-2 +--- +- AstError: + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: end + additional: expected function name +- AstError: + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: end + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..5e3e2e833ed34b712deae9fecee66de49bc0dc34 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-2/source.lua @@ -0,0 +1 @@ +function end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..8ab216d8a3fa4fa7cb48fd28ef5447f72857bcf1 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-2/tokens.snap @@ -0,0 +1,50 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/function-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-3/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-3/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..7f93d13626637402ab08b85d0b578ab97b032690 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-3/ast.snap @@ -0,0 +1,23 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/function-3 +--- +nodes: + stmts: [] +eof: + leading_trivia: [] + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-3/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-3/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..851f72c64a9894c81685f04c5df5b6a86d676708 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-3/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/function-3 +--- +"" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-3/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-3/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..226d16c47d71bd54fb1dcba962c53ac14867a053 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-3/error_display.snap @@ -0,0 +1,25 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/function-3 +--- +error[ast]: expected function name + ┌─ source.lua:1:9 + │ +1 │ function() end + │ ^ + +error[ast]: expected an expression after `(` + ┌─ source.lua:1:9 + │ +1 │ function() end + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:10 + │ +1 │ function() end + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-3/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-3/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..b72091325b6f9c8c6a62988fd532922d6291d6d9 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-3/errors.snap @@ -0,0 +1,48 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/function-3 +--- +- AstError: + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: ( + additional: expected function name +- AstError: + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: ( + additional: "expected an expression after `(`" +- AstError: + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: ) + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-3/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-3/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..793ec7ed02f0bb37fb9c3ef2f61fb22c88b9fcc2 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-3/source.lua @@ -0,0 +1 @@ +function() end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-3/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-3/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..d1155e113362d84719680e4696245a9a2b1913bf --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-3/tokens.snap @@ -0,0 +1,72 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/function-3 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-4/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-4/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..3d453548bec0cd6f9bc032d296b1a18911672599 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-4/ast.snap @@ -0,0 +1,120 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/function-4 +--- +nodes: + stmts: + - - FunctionDeclaration: + function_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: function + trailing_trivia: + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " + name: + names: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Identifier + identifier: x + trailing_trivia: [] + colon_name: ~ + body: + parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + parameters: + pairs: [] + block: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-4/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-4/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..43856080a3bbd6738af718b9dbee76fa400ed498 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-4/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/function-4 +--- +function x()end + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-4/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-4/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..2eba71d8498b318528f8a9b8f9ef540cf3dd04f2 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-4/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/function-4 +--- +error[ast]: expected a parameter name or `)` + ┌─ source.lua:1:12 + │ +1 │ function x( + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-4/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-4/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..a7b350d2e034edd0a1de1974e2ee7676f7769953 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-4/errors.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/function-4 +--- +- AstError: + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Eof + additional: "expected a parameter name or `)`" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-4/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-4/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..447d4a177bf23efe38efa8de177524932fa87871 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-4/source.lua @@ -0,0 +1 @@ +function x( \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-4/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-4/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..7ae41340cd4224f94ff4d7a0000a4a39e06f0553 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-4/tokens.snap @@ -0,0 +1,61 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/function-4 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-5/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-5/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..87d5c55d033135cf417ca54efb0c10cf57745399 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-5/ast.snap @@ -0,0 +1,23 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/function-5 +--- +nodes: + stmts: [] +eof: + leading_trivia: [] + token: + start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-5/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-5/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..91e673b7f411eed0164401d205b527c1f2e3f7d1 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-5/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/function-5 +--- +"" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-5/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-5/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..cec5bb6b0ab35c63dfb500de5c71a3f1fbc89cb8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-5/error_display.snap @@ -0,0 +1,31 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/function-5 +--- +error[ast]: expected function name + ┌─ source.lua:1:10 + │ +1 │ function local() end + │ ^^^^^ + +error[ast]: expected either a variable name or `function` + ┌─ source.lua:1:15 + │ +1 │ function local() end + │ ^ + +error[ast]: expected an expression after `(` + ┌─ source.lua:1:15 + │ +1 │ function local() end + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:16 + │ +1 │ function local() end + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-5/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-5/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..3444232458edf6e1b48a94982ba3f37233d9e9f6 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-5/errors.snap @@ -0,0 +1,62 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/function-5 +--- +- AstError: + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: local + additional: expected function name +- AstError: + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: ( + additional: "expected either a variable name or `function`" +- AstError: + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: ( + additional: "expected an expression after `(`" +- AstError: + token: + start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Symbol + symbol: ) + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-5/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-5/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..c6fc78628a8264d16b3d9012af00cebf79c26d0e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-5/source.lua @@ -0,0 +1 @@ +function local() end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-5/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-5/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..1d1464292cb90a0470c9fea8cb681d3a642cefa1 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-5/tokens.snap @@ -0,0 +1,94 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/function-5 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-6/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-6/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..bc1697614d6b3e871967e07b06491a88fb1bb0bf --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-6/ast.snap @@ -0,0 +1,120 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/function-6 +--- +nodes: + stmts: + - - FunctionDeclaration: + function_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: function + trailing_trivia: + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " + name: + names: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Identifier + identifier: x + trailing_trivia: [] + colon_name: ~ + body: + parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + parameters: + pairs: [] + block: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-6/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-6/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..e7cd0ba7dff0f64ce8e4a3776b185c498b89cb28 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-6/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/function-6 +--- +function x()end + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-6/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-6/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..2153c8672e10b360faef2ea3e7bd275d5e190eb2 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-6/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/function-6 +--- +error[ast]: expected `end` to close function body block + ┌─ source.lua:1:12 + │ +1 │ function x() + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-6/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-6/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..b9ee670c161e35ce2e20c1039abd1dc86a10a65b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-6/errors.snap @@ -0,0 +1,26 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/function-6 +--- +- AstError: + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Eof + additional: "expected `end` to close function body block" + range: + - bytes: 11 + line: 1 + character: 12 + - bytes: 12 + line: 1 + character: 13 + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-6/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-6/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..dc4f65057b9f64bc4264df33530872aafb4ba6e3 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-6/source.lua @@ -0,0 +1 @@ +function x() \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-6/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-6/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..81f1cb73074675eb8bd40c8fbcacac69fac02241 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-6/tokens.snap @@ -0,0 +1,72 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/function-6 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-7/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-7/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..fc5e2f60a0b9e83a6e5ed8a9603f2dfc99808377 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-7/ast.snap @@ -0,0 +1,136 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/function-7 +--- +nodes: + stmts: + - - FunctionDeclaration: + function_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: function + trailing_trivia: + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " + name: + names: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Identifier + identifier: x + trailing_trivia: [] + colon_name: ~ + body: + parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + parameters: + pairs: + - End: + Ellipse: + leading_trivia: [] + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: "..." + trailing_trivia: [] + block: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 22 + line: 2 + character: 4 + end_position: + bytes: 22 + line: 2 + character: 4 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-7/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-7/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..245a4a88b65a8e84ad6e590ae00c3e8cf5cd2c9b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-7/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/function-7 +--- +function x(...)end + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-7/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-7/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..67de43c3f2840c67880abcd9ad02f32bd11d56c8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-7/error_display.snap @@ -0,0 +1,31 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/function-7 +--- +error[ast]: expected a `)` + ┌─ source.lua:1:15 + │ +1 │ function x(..., a) + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:15 + │ +1 │ function x(..., a) + │ ^ + +error[ast]: unexpected expression when looking for a statement + ┌─ source.lua:1:18 + │ +1 │ function x(..., a) + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:18 + │ +1 │ function x(..., a) + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-7/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-7/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..55df5d9f99da4d92e4eb2aaa6a0b2f4e1e3e6b5d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-7/errors.snap @@ -0,0 +1,62 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/function-7 +--- +- AstError: + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: "," + additional: "expected a `)`" +- AstError: + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: "," + additional: "unexpected token, this needs to be a statement" +- AstError: + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: ) + additional: unexpected expression when looking for a statement +- AstError: + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: ) + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-7/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-7/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..f628947310d7d53f8ec9d211d7436fc02bd42f74 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-7/source.lua @@ -0,0 +1,2 @@ +function x(..., a) +end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-7/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-7/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..463022fc3357b2a4154c710824ce17348d8447fb --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-7/tokens.snap @@ -0,0 +1,138 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/function-7 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: "..." +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Identifier + identifier: a +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 19 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 19 + line: 2 + character: 1 + end_position: + bytes: 22 + line: 2 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 22 + line: 2 + character: 4 + end_position: + bytes: 22 + line: 2 + character: 4 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-8/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-8/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..afa57b903ed80d12b07290f796c3005e962c596f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-8/ast.snap @@ -0,0 +1,23 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/function-8 +--- +nodes: + stmts: [] +eof: + leading_trivia: [] + token: + start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-8/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-8/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..c19595d0ca7c2a0ebf3b1845f9d0951f8c7c0b0e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-8/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/function-8 +--- +"" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-8/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-8/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..bc83b3fe913cef9206fd75cfdcf7367d129a8478 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-8/error_display.snap @@ -0,0 +1,31 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/function-8 +--- +error[ast]: expected name after `:` + ┌─ source.lua:1:15 + │ +1 │ function name:3() end + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:15 + │ +1 │ function name:3() end + │ ^ + +error[ast]: expected an expression after `(` + ┌─ source.lua:1:16 + │ +1 │ function name:3() end + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:17 + │ +1 │ function name:3() end + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-8/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-8/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..11c643febda6ae3a064009ef6f9cb6138572a2e7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-8/errors.snap @@ -0,0 +1,62 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/function-8 +--- +- AstError: + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Number + text: "3" + additional: "expected name after `:`" +- AstError: + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Number + text: "3" + additional: "unexpected token, this needs to be a statement" +- AstError: + token: + start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Symbol + symbol: ( + additional: "expected an expression after `(`" +- AstError: + token: + start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: ) + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-8/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-8/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..7f185b65a907ec6c1ec738634eefabd65a9108e8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-8/source.lua @@ -0,0 +1 @@ +function name:3() end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-8/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-8/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..c9ff1ce7796243666f5e86f6e60c232e7512b4c7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/function-8/tokens.snap @@ -0,0 +1,116 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/function-8 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Identifier + identifier: name +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Number + text: "3" +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..a53668a6edeec34fe40a0883d6981950eb98419f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-1/ast.snap @@ -0,0 +1,23 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/generic-for-1 +--- +nodes: + stmts: [] +eof: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-1/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-1/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..1c545d69a9f7d139a3f8003e22b8533a53fad00a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-1/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/generic-for-1 +--- +"" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-1/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-1/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..27048f70c844a4cc53e3f7f28490eb1421e7ff0e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-1/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/generic-for-1 +--- +error[ast]: expected expressions after `in` + ┌─ source.lua:1:7 + │ +1 │ for x in + │ ^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-1/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-1/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..99949dca80c1d14aac69ebad66679803958044e5 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-1/errors.snap @@ -0,0 +1,20 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/generic-for-1 +--- +- AstError: + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: in + additional: "expected expressions after `in`" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..f433096f9affec2ea127d0905bb070f41f40cab7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-1/source.lua @@ -0,0 +1 @@ +for x in \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..9952424c2aebf83253f9f0a36c78b1f5baec37bd --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-1/tokens.snap @@ -0,0 +1,72 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/generic-for-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: for +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: in +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..578e0015b089fe36c418b426ba273d4033978dfc --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-2/ast.snap @@ -0,0 +1,210 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/generic-for-2 +--- +nodes: + stmts: + - - GenericFor: + for_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: for + trailing_trivia: + - start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " + names: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + in_token: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: in + trailing_trivia: + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Identifier + identifier: pairs + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Identifier + identifier: y + trailing_trivia: [] + do_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: do + trailing_trivia: [] + block: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-2/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-2/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..920bfe9e8b527b2826dd09ba4c2cdbda2958ae34 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-2/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/generic-for-2 +--- +for x in pairs(y)doend + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-2/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-2/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..67fae56e89b4ecac6dcb2dedcfee3971972c6e24 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-2/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/generic-for-2 +--- +error[ast]: expected `do` after expression list + ┌─ source.lua:1:18 + │ +1 │ for x in pairs(y) + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-2/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-2/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..8f834d21eae344b77930628d5eb238cc88689b92 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-2/errors.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/generic-for-2 +--- +- AstError: + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Eof + additional: "expected `do` after expression list" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..88e9a0b7d60e678b5e381ad1bcfce3e1ea12e376 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-2/source.lua @@ -0,0 +1 @@ +for x in pairs(y) \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..f3f3f884f2f7030bb88fe96f9c5fd2bed02d430d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-2/tokens.snap @@ -0,0 +1,127 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/generic-for-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: for +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: in +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Identifier + identifier: pairs +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-3/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-3/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..7972c504c902f46aa434928260c72beea2d10f81 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-3/ast.snap @@ -0,0 +1,221 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/generic-for-3 +--- +nodes: + stmts: + - - GenericFor: + for_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: for + trailing_trivia: + - start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " + names: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + in_token: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: in + trailing_trivia: + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Identifier + identifier: pairs + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Whitespace + characters: " " + arguments: + pairs: + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Identifier + identifier: y + trailing_trivia: [] + do_token: + leading_trivia: [] + token: + start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Symbol + symbol: do + trailing_trivia: [] + block: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-3/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-3/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..f739f29bde124dbfcf9995ae30fadfd54e838c91 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-3/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/generic-for-3 +--- +for x in pairs(y) doend + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-3/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-3/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..2e9cf822cd62e723447da3a454205878cba40863 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-3/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/generic-for-3 +--- +error[ast]: expected `end` to close for loop block + ┌─ source.lua:1:19 + │ +1 │ for x in pairs(y) do + │ ^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-3/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-3/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..a7760826323e85a39b8e297456e3c5cf4b98b24a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-3/errors.snap @@ -0,0 +1,26 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/generic-for-3 +--- +- AstError: + token: + start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Eof + additional: "expected `end` to close for loop block" + range: + - bytes: 18 + line: 1 + character: 19 + - bytes: 20 + line: 1 + character: 21 + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-3/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-3/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..1636a9e1fc6a38aca6f91108a2b1222e7aff7e33 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-3/source.lua @@ -0,0 +1 @@ +for x in pairs(y) do \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-3/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-3/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..e4ef33dd9da2c3ee756561076f680c7eaa252917 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-3/tokens.snap @@ -0,0 +1,149 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/generic-for-3 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: for +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: in +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Identifier + identifier: pairs +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-4/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-4/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..9ebd07a61eb5e951efaab78146793b2072da8662 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-4/ast.snap @@ -0,0 +1,150 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/generic-for-4 +--- +nodes: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Identifier + identifier: pairs + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 26 + line: 1 + character: 27 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 30 + line: 1 + character: 31 + end_position: + bytes: 31 + line: 1 + character: 32 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 31 + line: 1 + character: 32 + end_position: + bytes: 32 + line: 1 + character: 33 + token_type: + type: Whitespace + characters: " " + arguments: + pairs: + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 26 + line: 1 + character: 27 + end_position: + bytes: 30 + line: 1 + character: 31 + token_type: + type: Identifier + identifier: list + trailing_trivia: [] + - ~ + - - Do: + do_token: + leading_trivia: [] + token: + start_position: + bytes: 32 + line: 1 + character: 33 + end_position: + bytes: 34 + line: 1 + character: 35 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 34 + line: 1 + character: 35 + end_position: + bytes: 35 + line: 1 + character: 36 + token_type: + type: Whitespace + characters: " " + block: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 35 + line: 1 + character: 36 + end_position: + bytes: 38 + line: 1 + character: 39 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 38 + line: 1 + character: 39 + end_position: + bytes: 38 + line: 1 + character: 39 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-4/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-4/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..80b3ee21f328ac81ed272b040f40c0efa80be23c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-4/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/generic-for-4 +--- +pairs(list) do end + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-4/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-4/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..22df658980360f62c780c97ead1a8bd90f865b97 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-4/error_display.snap @@ -0,0 +1,31 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/generic-for-4 +--- +error[ast]: trailing commas are not allowed + ┌─ source.lua:1:10 + │ +1 │ for index, local in pairs(list) do end + │ ^ + +error[ast]: expected `in` after name list + ┌─ source.lua:1:12 + │ +1 │ for index, local in pairs(list) do end + │ ^^^^^ + +error[ast]: expected either a variable name or `function` + ┌─ source.lua:1:18 + │ +1 │ for index, local in pairs(list) do end + │ ^^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:18 + │ +1 │ for index, local in pairs(list) do end + │ ^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-4/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-4/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..c2e5d95d8958856ba0a172e98bc8003541a063d8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-4/errors.snap @@ -0,0 +1,62 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/generic-for-4 +--- +- AstError: + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "," + additional: trailing commas are not allowed +- AstError: + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Symbol + symbol: local + additional: "expected `in` after name list" +- AstError: + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: in + additional: "expected either a variable name or `function`" +- AstError: + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: in + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-4/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-4/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..0ef1ebdaf4e1b4c789e6fc4c83e803b8aba38f60 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-4/source.lua @@ -0,0 +1 @@ +for index, local in pairs(list) do end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-4/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-4/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..520288b7c6eeb0b0b3aa1fe9b8a3bcd31419c43b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/generic-for-4/tokens.snap @@ -0,0 +1,204 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/generic-for-4 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: for +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Identifier + identifier: index +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: in +- start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Identifier + identifier: pairs +- start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 26 + line: 1 + character: 27 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 26 + line: 1 + character: 27 + end_position: + bytes: 30 + line: 1 + character: 31 + token_type: + type: Identifier + identifier: list +- start_position: + bytes: 30 + line: 1 + character: 31 + end_position: + bytes: 31 + line: 1 + character: 32 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 31 + line: 1 + character: 32 + end_position: + bytes: 32 + line: 1 + character: 33 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 32 + line: 1 + character: 33 + end_position: + bytes: 34 + line: 1 + character: 35 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 34 + line: 1 + character: 35 + end_position: + bytes: 35 + line: 1 + character: 36 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 35 + line: 1 + character: 36 + end_position: + bytes: 38 + line: 1 + character: 39 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 38 + line: 1 + character: 39 + end_position: + bytes: 38 + line: 1 + character: 39 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..175f404d493ba5d6fe5e4f7d2fd6e0ffff051b0c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-1/ast.snap @@ -0,0 +1,114 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/if-1 +--- +nodes: + stmts: + - - If: + if_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: if + trailing_trivia: + - start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Whitespace + characters: " " + condition: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: then + trailing_trivia: [] + block: + stmts: [] + else_if: ~ + else_token: ~ + else: ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-1/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-1/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..9a5d68df8ecdc9255387ac2bd3ebcdbc55919754 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-1/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/if-1 +--- +if x thenend + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-1/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-1/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..fcb0be217aa8f6018e87c52996f40aad8a7925b9 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-1/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/if-1 +--- +error[ast]: expected `end` to conclude `if` + ┌─ source.lua:1:10 + │ +1 │ if x then + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-1/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-1/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..19e156e53888ba2166bf03438e0b87e471e42ffa --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-1/errors.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/if-1 +--- +- AstError: + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Eof + additional: "expected `end` to conclude `if`" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..a3f9a84a473694aef08e3804487de2198887436a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-1/source.lua @@ -0,0 +1 @@ +if x then \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..6cdda87bffc9f789564fbd7b5232f97fde1f1b4b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-1/tokens.snap @@ -0,0 +1,72 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/if-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: if +- start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..c9be778194828f7eb5926dda09e6bc128738a217 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-2/ast.snap @@ -0,0 +1,216 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/if-2 +--- +nodes: + stmts: + - - If: + if_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: if + trailing_trivia: + - start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Whitespace + characters: " " + condition: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: [] + else_if: ~ + else_token: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 2 + character: 1 + end_position: + bytes: 14 + line: 2 + character: 5 + token_type: + type: Symbol + symbol: else + trailing_trivia: + - start_position: + bytes: 14 + line: 2 + character: 5 + end_position: + bytes: 15 + line: 2 + character: 5 + token_type: + type: Whitespace + characters: "\n" + else: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 15 + line: 3 + character: 1 + end_position: + bytes: 16 + line: 3 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 16 + line: 3 + character: 2 + end_position: + bytes: 20 + line: 3 + character: 6 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 20 + line: 3 + character: 6 + end_position: + bytes: 21 + line: 3 + character: 7 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 21 + line: 3 + character: 7 + end_position: + bytes: 22 + line: 3 + character: 8 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: [] + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 22 + line: 3 + character: 8 + end_position: + bytes: 22 + line: 3 + character: 8 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-2/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-2/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..748f4d41b7bf269b521c50dc1642eba7c3ae8f26 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-2/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/if-2 +--- +"if x then\nelse\n\tcall()end" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-2/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-2/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..c69c5395bbbbcd56c1a38fa99a445efd0be0ec19 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-2/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/if-2 +--- +error[ast]: expected `end` to conclude `if` + ┌─ source.lua:3:8 + │ +3 │ call() + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-2/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-2/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..e06a89615923641a206b357b3c8909776f1549bb --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-2/errors.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/if-2 +--- +- AstError: + token: + start_position: + bytes: 22 + line: 3 + character: 8 + end_position: + bytes: 22 + line: 3 + character: 8 + token_type: + type: Eof + additional: "expected `end` to conclude `if`" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..76b5f4e03d524513200c2a98eaafd31b45243576 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-2/source.lua @@ -0,0 +1,3 @@ +if x then +else + call() \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..1effc926137e3b41368f385e275cd0937dc5e250 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-2/tokens.snap @@ -0,0 +1,149 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/if-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: if +- start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 10 + line: 2 + character: 1 + end_position: + bytes: 14 + line: 2 + character: 5 + token_type: + type: Symbol + symbol: else +- start_position: + bytes: 14 + line: 2 + character: 5 + end_position: + bytes: 15 + line: 2 + character: 5 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 15 + line: 3 + character: 1 + end_position: + bytes: 16 + line: 3 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 16 + line: 3 + character: 2 + end_position: + bytes: 20 + line: 3 + character: 6 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 20 + line: 3 + character: 6 + end_position: + bytes: 21 + line: 3 + character: 7 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 21 + line: 3 + character: 7 + end_position: + bytes: 22 + line: 3 + character: 8 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 22 + line: 3 + character: 8 + end_position: + bytes: 22 + line: 3 + character: 8 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-3/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-3/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..1ec7da5e8b1dea944a1e08bd23fe63acb11d1e11 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-3/ast.snap @@ -0,0 +1,23 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/if-3 +--- +nodes: + stmts: [] +eof: + leading_trivia: [] + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-3/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-3/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..fe1b1c2c9b5c675187a4e8c57f5833c455d59c80 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-3/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/if-3 +--- +"" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-3/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-3/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..b1b5b87cf458fb30b8332e7704b2b8d60da1fa1d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-3/error_display.snap @@ -0,0 +1,25 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/if-3 +--- +error[ast]: expected condition after `if` + ┌─ source.lua:1:1 + │ +1 │ if local then end + │ ^^ + +error[ast]: expected either a variable name or `function` + ┌─ source.lua:1:10 + │ +1 │ if local then end + │ ^^^^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:10 + │ +1 │ if local then end + │ ^^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-3/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-3/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..ea1d4d90e4e2b02cc106b64089c9e2ca411a5150 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-3/errors.snap @@ -0,0 +1,48 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/if-3 +--- +- AstError: + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: if + additional: "expected condition after `if`" +- AstError: + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: then + additional: "expected either a variable name or `function`" +- AstError: + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: then + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-3/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-3/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..11aed1fa0ea2879e7d2bddf8b7ae87d11f85cc3b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-3/source.lua @@ -0,0 +1 @@ +if local then end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-3/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-3/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..1eed2f7ab9f2b73c0d29cd0563b9fb84bfd99959 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-3/tokens.snap @@ -0,0 +1,94 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/if-3 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: if +- start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-4/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-4/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..482fc269435878e68d1f9d395e6b2eecbadbd44c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-4/ast.snap @@ -0,0 +1,196 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/if-4 +--- +nodes: + stmts: + - - If: + if_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: if + trailing_trivia: + - start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Whitespace + characters: " " + condition: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: [] + else_if: + - else_if_token: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 2 + character: 1 + end_position: + bytes: 16 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: elseif + trailing_trivia: + - start_position: + bytes: 16 + line: 2 + character: 7 + end_position: + bytes: 17 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: " " + condition: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 17 + line: 2 + character: 8 + end_position: + bytes: 18 + line: 2 + character: 9 + token_type: + type: Identifier + identifier: y + trailing_trivia: + - start_position: + bytes: 18 + line: 2 + character: 9 + end_position: + bytes: 19 + line: 2 + character: 10 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 19 + line: 2 + character: 10 + end_position: + bytes: 23 + line: 2 + character: 14 + token_type: + type: Symbol + symbol: then + trailing_trivia: [] + block: + stmts: [] + else_token: ~ + else: ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 23 + line: 2 + character: 14 + end_position: + bytes: 23 + line: 2 + character: 14 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-4/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-4/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..1adf8e810d916988af4f8d155d72fe1387a7df33 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-4/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/if-4 +--- +"if x then\nelseif y thenend" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-4/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-4/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..a4493dd0b617303f6505eab8eebcf891bfb1e803 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-4/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/if-4 +--- +error[ast]: expected `end` to conclude `if` + ┌─ source.lua:2:14 + │ +2 │ elseif y then + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-4/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-4/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..4e4d976334794a301505da2cda6d076b3cdcc7a7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-4/errors.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/if-4 +--- +- AstError: + token: + start_position: + bytes: 23 + line: 2 + character: 14 + end_position: + bytes: 23 + line: 2 + character: 14 + token_type: + type: Eof + additional: "expected `end` to conclude `if`" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-4/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-4/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..fcaba29b7fabd4c6d148ab6ad2876396c9670541 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-4/source.lua @@ -0,0 +1,2 @@ +if x then +elseif y then \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-4/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-4/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..7a3e1820f56365a5be2cc31963d74c33cb7fb0da --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-4/tokens.snap @@ -0,0 +1,138 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/if-4 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: if +- start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 10 + line: 2 + character: 1 + end_position: + bytes: 16 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: elseif +- start_position: + bytes: 16 + line: 2 + character: 7 + end_position: + bytes: 17 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 17 + line: 2 + character: 8 + end_position: + bytes: 18 + line: 2 + character: 9 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 18 + line: 2 + character: 9 + end_position: + bytes: 19 + line: 2 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 19 + line: 2 + character: 10 + end_position: + bytes: 23 + line: 2 + character: 14 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 23 + line: 2 + character: 14 + end_position: + bytes: 23 + line: 2 + character: 14 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-5/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-5/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..2a9e911167c57f0bf9679b03f442302f7f7ee2ee --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-5/ast.snap @@ -0,0 +1,379 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/if-5 +--- +nodes: + stmts: + - - If: + if_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: if + trailing_trivia: + - start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Whitespace + characters: " " + condition: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 10 + line: 2 + character: 1 + end_position: + bytes: 11 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 11 + line: 2 + character: 2 + end_position: + bytes: 16 + line: 2 + character: 7 + token_type: + type: Identifier + identifier: call1 + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 16 + line: 2 + character: 7 + end_position: + bytes: 17 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 17 + line: 2 + character: 8 + end_position: + bytes: 18 + line: 2 + character: 9 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 18 + line: 2 + character: 9 + end_position: + bytes: 19 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: [] + - ~ + else_if: ~ + else_token: + leading_trivia: [] + token: + start_position: + bytes: 19 + line: 3 + character: 1 + end_position: + bytes: 23 + line: 3 + character: 5 + token_type: + type: Symbol + symbol: else + trailing_trivia: + - start_position: + bytes: 23 + line: 3 + character: 5 + end_position: + bytes: 24 + line: 3 + character: 5 + token_type: + type: Whitespace + characters: "\n" + else: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 24 + line: 4 + character: 1 + end_position: + bytes: 25 + line: 4 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 25 + line: 4 + character: 2 + end_position: + bytes: 30 + line: 4 + character: 7 + token_type: + type: Identifier + identifier: call2 + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 30 + line: 4 + character: 7 + end_position: + bytes: 31 + line: 4 + character: 8 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 31 + line: 4 + character: 8 + end_position: + bytes: 32 + line: 4 + character: 9 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 32 + line: 4 + character: 9 + end_position: + bytes: 33 + line: 4 + character: 9 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: [] + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 47 + line: 6 + character: 1 + end_position: + bytes: 48 + line: 6 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 48 + line: 6 + character: 2 + end_position: + bytes: 53 + line: 6 + character: 7 + token_type: + type: Identifier + identifier: call3 + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 53 + line: 6 + character: 7 + end_position: + bytes: 54 + line: 6 + character: 8 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 54 + line: 6 + character: 8 + end_position: + bytes: 55 + line: 6 + character: 9 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 55 + line: 6 + character: 9 + end_position: + bytes: 56 + line: 6 + character: 9 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 59 + line: 7 + character: 4 + end_position: + bytes: 59 + line: 7 + character: 4 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-5/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-5/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..f7343c4eb59ccd36ddcb194306e60c6a24901d08 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-5/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/if-5 +--- +"if x then\n\tcall1()\nelse\n\tcall2()\nend\tcall3()\n" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-5/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-5/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..c47c9ef31f4982429d54ddd2b407ff59d4ad1d4d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-5/error_display.snap @@ -0,0 +1,31 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/if-5 +--- +error[ast]: expected `end` to conclude `if` + ┌─ source.lua:5:1 + │ +5 │ elseif y then + │ ^^^^^^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:5:1 + │ +5 │ elseif y then + │ ^^^^^^ + +error[ast]: unexpected expression when looking for a statement + ┌─ source.lua:5:10 + │ +5 │ elseif y then + │ ^^^^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:5:10 + │ +5 │ elseif y then + │ ^^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-5/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-5/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..9af48a5ac3437b30ad9bd51f5d68ee30e2572979 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-5/errors.snap @@ -0,0 +1,62 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/if-5 +--- +- AstError: + token: + start_position: + bytes: 33 + line: 5 + character: 1 + end_position: + bytes: 39 + line: 5 + character: 7 + token_type: + type: Symbol + symbol: elseif + additional: "expected `end` to conclude `if`" +- AstError: + token: + start_position: + bytes: 33 + line: 5 + character: 1 + end_position: + bytes: 39 + line: 5 + character: 7 + token_type: + type: Symbol + symbol: elseif + additional: "unexpected token, this needs to be a statement" +- AstError: + token: + start_position: + bytes: 42 + line: 5 + character: 10 + end_position: + bytes: 46 + line: 5 + character: 14 + token_type: + type: Symbol + symbol: then + additional: unexpected expression when looking for a statement +- AstError: + token: + start_position: + bytes: 42 + line: 5 + character: 10 + end_position: + bytes: 46 + line: 5 + character: 14 + token_type: + type: Symbol + symbol: then + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-5/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-5/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..31487e7f626406b6521e4995c0aa8f1bd69940e5 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-5/source.lua @@ -0,0 +1,7 @@ +if x then + call1() +else + call2() +elseif y then + call3() +end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-5/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-5/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..d381cb1fd821fd1616247827c41339fb6fd85eeb --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-5/tokens.snap @@ -0,0 +1,347 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/if-5 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: if +- start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 10 + line: 2 + character: 1 + end_position: + bytes: 11 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 11 + line: 2 + character: 2 + end_position: + bytes: 16 + line: 2 + character: 7 + token_type: + type: Identifier + identifier: call1 +- start_position: + bytes: 16 + line: 2 + character: 7 + end_position: + bytes: 17 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 17 + line: 2 + character: 8 + end_position: + bytes: 18 + line: 2 + character: 9 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 18 + line: 2 + character: 9 + end_position: + bytes: 19 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 19 + line: 3 + character: 1 + end_position: + bytes: 23 + line: 3 + character: 5 + token_type: + type: Symbol + symbol: else +- start_position: + bytes: 23 + line: 3 + character: 5 + end_position: + bytes: 24 + line: 3 + character: 5 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 24 + line: 4 + character: 1 + end_position: + bytes: 25 + line: 4 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 25 + line: 4 + character: 2 + end_position: + bytes: 30 + line: 4 + character: 7 + token_type: + type: Identifier + identifier: call2 +- start_position: + bytes: 30 + line: 4 + character: 7 + end_position: + bytes: 31 + line: 4 + character: 8 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 31 + line: 4 + character: 8 + end_position: + bytes: 32 + line: 4 + character: 9 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 32 + line: 4 + character: 9 + end_position: + bytes: 33 + line: 4 + character: 9 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 33 + line: 5 + character: 1 + end_position: + bytes: 39 + line: 5 + character: 7 + token_type: + type: Symbol + symbol: elseif +- start_position: + bytes: 39 + line: 5 + character: 7 + end_position: + bytes: 40 + line: 5 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 40 + line: 5 + character: 8 + end_position: + bytes: 41 + line: 5 + character: 9 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 41 + line: 5 + character: 9 + end_position: + bytes: 42 + line: 5 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 42 + line: 5 + character: 10 + end_position: + bytes: 46 + line: 5 + character: 14 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 46 + line: 5 + character: 14 + end_position: + bytes: 47 + line: 5 + character: 14 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 47 + line: 6 + character: 1 + end_position: + bytes: 48 + line: 6 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 48 + line: 6 + character: 2 + end_position: + bytes: 53 + line: 6 + character: 7 + token_type: + type: Identifier + identifier: call3 +- start_position: + bytes: 53 + line: 6 + character: 7 + end_position: + bytes: 54 + line: 6 + character: 8 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 54 + line: 6 + character: 8 + end_position: + bytes: 55 + line: 6 + character: 9 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 55 + line: 6 + character: 9 + end_position: + bytes: 56 + line: 6 + character: 9 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 56 + line: 7 + character: 1 + end_position: + bytes: 59 + line: 7 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 59 + line: 7 + character: 4 + end_position: + bytes: 59 + line: 7 + character: 4 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-6/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-6/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..f632be91ba0fd394e7142b5ec60519b6d844234c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-6/ast.snap @@ -0,0 +1,227 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/if-6 +--- +nodes: + stmts: + - - If: + if_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: if + trailing_trivia: + - start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Whitespace + characters: " " + condition: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: [] + else_if: ~ + else_token: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 2 + character: 1 + end_position: + bytes: 14 + line: 2 + character: 5 + token_type: + type: Symbol + symbol: else + trailing_trivia: + - start_position: + bytes: 14 + line: 2 + character: 5 + end_position: + bytes: 15 + line: 2 + character: 6 + token_type: + type: Whitespace + characters: " " + else: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 20 + line: 3 + character: 1 + end_position: + bytes: 21 + line: 3 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 21 + line: 3 + character: 2 + end_position: + bytes: 25 + line: 3 + character: 6 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 25 + line: 3 + character: 6 + end_position: + bytes: 26 + line: 3 + character: 7 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 26 + line: 3 + character: 7 + end_position: + bytes: 27 + line: 3 + character: 8 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 27 + line: 3 + character: 8 + end_position: + bytes: 28 + line: 3 + character: 8 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 31 + line: 4 + character: 4 + end_position: + bytes: 31 + line: 4 + character: 4 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-6/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-6/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..bd3740cbb20d4eae98f57858d48b19f8a5bcce15 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-6/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/if-6 +--- +"if x then\nelse end\tcall()\n" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-6/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-6/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..c8f4e2544a577149da9d951ae2f7055767fbd095 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-6/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/if-6 +--- +error[ast]: expected `end` to conclude `if` + ┌─ source.lua:2:6 + │ +2 │ else then + │ ^^^^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:2:6 + │ +2 │ else then + │ ^^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-6/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-6/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..25bf982ae7bd0c236aff4cf9b34a737dc350f9b3 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-6/errors.snap @@ -0,0 +1,34 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/if-6 +--- +- AstError: + token: + start_position: + bytes: 15 + line: 2 + character: 6 + end_position: + bytes: 19 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: then + additional: "expected `end` to conclude `if`" +- AstError: + token: + start_position: + bytes: 15 + line: 2 + character: 6 + end_position: + bytes: 19 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: then + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-6/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-6/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..eac8a784df1e575714def2606bcd646dfb9ddea8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-6/source.lua @@ -0,0 +1,4 @@ +if x then +else then + call() +end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-6/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-6/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..6559e117db226eb08ba4929e34b917bdbb5d52a4 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-6/tokens.snap @@ -0,0 +1,193 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/if-6 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: if +- start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 10 + line: 2 + character: 1 + end_position: + bytes: 14 + line: 2 + character: 5 + token_type: + type: Symbol + symbol: else +- start_position: + bytes: 14 + line: 2 + character: 5 + end_position: + bytes: 15 + line: 2 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 15 + line: 2 + character: 6 + end_position: + bytes: 19 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 19 + line: 2 + character: 10 + end_position: + bytes: 20 + line: 2 + character: 10 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 20 + line: 3 + character: 1 + end_position: + bytes: 21 + line: 3 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 21 + line: 3 + character: 2 + end_position: + bytes: 25 + line: 3 + character: 6 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 25 + line: 3 + character: 6 + end_position: + bytes: 26 + line: 3 + character: 7 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 26 + line: 3 + character: 7 + end_position: + bytes: 27 + line: 3 + character: 8 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 27 + line: 3 + character: 8 + end_position: + bytes: 28 + line: 3 + character: 8 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 28 + line: 4 + character: 1 + end_position: + bytes: 31 + line: 4 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 31 + line: 4 + character: 4 + end_position: + bytes: 31 + line: 4 + character: 4 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-7/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-7/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..a8bee9d91a2f812c9e0615e233bbc338983d3848 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-7/ast.snap @@ -0,0 +1,170 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/if-7 +--- +nodes: + stmts: + - - If: + if_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: if + trailing_trivia: + - start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Whitespace + characters: " " + condition: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + block: + stmts: + - - Do: + do_token: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 13 + line: 2 + character: 1 + end_position: + bytes: 16 + line: 2 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ + else_if: ~ + else_token: ~ + else: ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 16 + line: 2 + character: 4 + end_position: + bytes: 16 + line: 2 + character: 4 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-7/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-7/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..942af31f4625ca007eb587238ddde366eebb8fb9 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-7/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/if-7 +--- +"if x then do\nendend" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-7/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-7/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..ee217fae2d801b0fae909417a70ea64ad7f6a53c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-7/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/if-7 +--- +error[ast]: expected `end` to conclude `if` + ┌─ source.lua:2:4 + │ +2 │ end + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-7/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-7/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..e3e0debd8597173d1717b28a96f74700f16c79d6 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-7/errors.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/if-7 +--- +- AstError: + token: + start_position: + bytes: 16 + line: 2 + character: 4 + end_position: + bytes: 16 + line: 2 + character: 4 + token_type: + type: Eof + additional: "expected `end` to conclude `if`" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-7/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-7/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..40a78b9522c46ab625f71318ad5f7c5e919e5fde --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-7/source.lua @@ -0,0 +1,2 @@ +if x then do +end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-7/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-7/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..660eb1b5d5050f4037b57559b0808b2bdc40f0c8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/if-7/tokens.snap @@ -0,0 +1,116 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/if-7 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: if +- start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 13 + line: 2 + character: 1 + end_position: + bytes: 16 + line: 2 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 16 + line: 2 + character: 4 + end_position: + bytes: 16 + line: 2 + character: 4 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..222e0dec1e1b9b00fae4e31da4c04090de09a1de --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-1/ast.snap @@ -0,0 +1,23 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/index-1 +--- +nodes: + stmts: [] +eof: + leading_trivia: [] + token: + start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-1/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-1/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..bd24341fe3cd3d802682e77ccaaba8d14f5b7bcb --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-1/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/index-1 +--- +"" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-1/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-1/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..9c69eac1a3098576d58e9f6572f94f7f50ab428e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-1/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/index-1 +--- +error[ast]: expected `]` to close index expression + ┌─ source.lua:1:2 + │ +1 │ x[2 + │ ^^ + +error[ast]: unexpected expression when looking for a statement + ┌─ source.lua:1:4 + │ +1 │ x[2 + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-1/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-1/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..dfb0f21989831310c3bff4523b0a70e0f503e67e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-1/errors.snap @@ -0,0 +1,39 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/index-1 +--- +- AstError: + token: + start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Eof + additional: "expected `]` to close index expression" + range: + - bytes: 1 + line: 1 + character: 2 + - bytes: 3 + line: 1 + character: 4 +- AstError: + token: + start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Eof + additional: unexpected expression when looking for a statement + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..5073f14eb3b44fb291141514ea8d08e8084eb968 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-1/source.lua @@ -0,0 +1 @@ +x[2 \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..c7666f35a265f8163fc9ca816a236337473015a4 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-1/tokens.snap @@ -0,0 +1,50 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/index-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: "[" +- start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Number + text: "2" +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..9b6dfa6a561d37590f820f33ffde2ebc0d1fd48d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-2/ast.snap @@ -0,0 +1,23 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/index-2 +--- +nodes: + stmts: [] +eof: + leading_trivia: [] + token: + start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-2/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-2/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..929be64c46cde6cbf3dee88b73129a0d47d625b2 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-2/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/index-2 +--- +"" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-2/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-2/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..8c235bac74208a863b4005078fdf32f735d730e7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-2/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/index-2 +--- +error[ast]: expected expression after `[` + ┌─ source.lua:1:2 + │ +1 │ x[ + │ ^ + +error[ast]: unexpected expression when looking for a statement + ┌─ source.lua:1:3 + │ +1 │ x[ + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-2/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-2/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..feb31115d55ffce3a103cd74c10959778a8522b4 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-2/errors.snap @@ -0,0 +1,33 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/index-2 +--- +- AstError: + token: + start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: "[" + additional: "expected expression after `[`" +- AstError: + token: + start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Eof + additional: unexpected expression when looking for a statement + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..4ba02ce0053d72d3333c85777dae519427cb0fba --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-2/source.lua @@ -0,0 +1 @@ +x[ \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..a7314f44001def67515be7a26e0cfb278e27e142 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-2/tokens.snap @@ -0,0 +1,39 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/index-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: "[" +- start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-3/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-3/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..71001217e22063877530ea4d4b5dce0d4ea427d9 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-3/ast.snap @@ -0,0 +1,23 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/index-3 +--- +nodes: + stmts: [] +eof: + leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-3/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-3/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..9603cdc42d7466a1bab518d0a8e47b0c4c76d19d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-3/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/index-3 +--- +"" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-3/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-3/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..5a4c49c382088c035d97093c39bdc643ea1c29b9 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-3/error_display.snap @@ -0,0 +1,25 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/index-3 +--- +error[ast]: expected expression after `[` + ┌─ source.lua:1:2 + │ +1 │ x[] = 1 + │ ^ + +error[ast]: unexpected expression when looking for a statement + ┌─ source.lua:1:3 + │ +1 │ x[] = 1 + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:3 + │ +1 │ x[] = 1 + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-3/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-3/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..76ffc51c273ee33f0272f27ce183e5e41d83997f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-3/errors.snap @@ -0,0 +1,48 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/index-3 +--- +- AstError: + token: + start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: "[" + additional: "expected expression after `[`" +- AstError: + token: + start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: "]" + additional: unexpected expression when looking for a statement +- AstError: + token: + start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: "]" + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-3/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-3/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..96f85a9d93222463a20c9f6e6eed2d7f0d460aa1 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-3/source.lua @@ -0,0 +1 @@ +x[] = 1 \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-3/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-3/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..65167c72a49b408f2b1a420bae4bb435e5d968a7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-3/tokens.snap @@ -0,0 +1,94 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/index-3 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: "[" +- start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: "]" +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Number + text: "1" +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-4/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-4/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..5b390d31017cd5b297cf9fc491427822c5096ceb --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-4/ast.snap @@ -0,0 +1,124 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/index-4 +--- +nodes: + stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: y + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Identifier + identifier: x + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-4/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-4/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..2c4d24a33d59476e97f4a9c4ea31a5776a5818db --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-4/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/index-4 +--- +local y = x + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-4/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-4/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..69b67390f3482860aad56bc3221437ec11f37245 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-4/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/index-4 +--- +error[ast]: expected expression after `[` + ┌─ source.lua:1:12 + │ +1 │ local y = x[end] + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:13 + │ +1 │ local y = x[end] + │ ^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-4/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-4/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..c640f83f66c0e7f13f6640e97a85030a7d26235f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-4/errors.snap @@ -0,0 +1,34 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/index-4 +--- +- AstError: + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: "[" + additional: "expected expression after `[`" +- AstError: + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: end + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-4/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-4/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..92169c410006ea0f43fa469a529614005418286a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-4/source.lua @@ -0,0 +1 @@ +local y = x[end] \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-4/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-4/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..7cb056ba3dc01986f7655dba80ea5b25ed599f18 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-4/tokens.snap @@ -0,0 +1,127 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/index-4 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: "[" +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Symbol + symbol: "]" +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-5/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-5/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..7440fbe50b45a14b33ebd25fb2375cdc75132fea --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-5/ast.snap @@ -0,0 +1,71 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/index-5 +--- +nodes: + stmts: [] + last_stmt: + - Return: + token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + returns: + pairs: + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Identifier + identifier: name + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-5/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-5/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..5358da6503875cc10c72e14c87e7e7fdae9dfaab --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-5/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/index-5 +--- +return name + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-5/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-5/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..7fd11fc6b063ac637f4f785019e96e51f9c7f7f8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-5/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/index-5 +--- +error[ast]: expected identifier after `.` + ┌─ source.lua:1:12 + │ +1 │ return name.until + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:13 + │ +1 │ return name.until + │ ^^^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-5/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-5/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..c086086bd37aafcdaf8eab8b012e9c0c1db4092b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-5/errors.snap @@ -0,0 +1,34 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/index-5 +--- +- AstError: + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: "." + additional: "expected identifier after `.`" +- AstError: + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: until + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-5/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-5/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..ebc7fd017aab6fb3745fddfafea496a4d75e1fda --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-5/source.lua @@ -0,0 +1 @@ +return name.until \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-5/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-5/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..faaa37d9f4d9f91cafa60664420ee29131409331 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/index-5/tokens.snap @@ -0,0 +1,72 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/index-5 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Identifier + identifier: name +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: until +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/last-stmt-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/last-stmt-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..a85c6eb6c0e06cb4d2b6ab182e253d31619c3612 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/last-stmt-1/ast.snap @@ -0,0 +1,292 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 23 +expression: result.ast() +input_file: full-moon/tests/cases/fail/parser/last-stmt-1 +--- +nodes: + stmts: + - - LocalFunction: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + function_token: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: function + trailing_trivia: + - start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " + name: + leading_trivia: [] + token: + start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Identifier + identifier: x + trailing_trivia: [] + body: + generics: ~ + parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 19 + token_type: + type: Whitespace + characters: "\n" + parameters: + pairs: [] + type_specifiers: [] + block: + stmts: [] + last_stmt: + - Return: + token: + leading_trivia: + - start_position: + bytes: 19 + line: 2 + character: 1 + end_position: + bytes: 20 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 20 + line: 2 + character: 2 + end_position: + bytes: 26 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 26 + line: 2 + character: 8 + end_position: + bytes: 27 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " + returns: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 27 + line: 2 + character: 9 + end_position: + bytes: 28 + line: 2 + character: 10 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 28 + line: 2 + character: 10 + end_position: + bytes: 29 + line: 2 + character: 10 + token_type: + type: Whitespace + characters: "\n" + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ + last_stmt: + - Return: + token: + leading_trivia: + - start_position: + bytes: 29 + line: 3 + character: 1 + end_position: + bytes: 30 + line: 3 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 30 + line: 3 + character: 2 + end_position: + bytes: 36 + line: 3 + character: 8 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 36 + line: 3 + character: 8 + end_position: + bytes: 37 + line: 3 + character: 9 + token_type: + type: Whitespace + characters: " " + returns: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 37 + line: 3 + character: 9 + end_position: + bytes: 38 + line: 3 + character: 10 + token_type: + type: Number + text: "2" + trailing_trivia: + - start_position: + bytes: 38 + line: 3 + character: 10 + end_position: + bytes: 39 + line: 3 + character: 10 + token_type: + type: Whitespace + characters: "\n" + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 43 + line: 5 + character: 1 + end_position: + bytes: 43 + line: 5 + character: 1 + token_type: + type: Eof + trailing_trivia: [] diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/last-stmt-1/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/last-stmt-1/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..a8f0478edd6a4a0cad4db9d6d0edd637bd586e72 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/last-stmt-1/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 28 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/last-stmt-1 +--- +"local function x()\n\treturn 1\nend\treturn 2\n" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/last-stmt-1/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/last-stmt-1/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..aa58c7139d60098b43214dbf9d146898192c2a00 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/last-stmt-1/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/last-stmt-1 +--- +error[ast]: expected `end` to close function body block + ┌─ source.lua:2:2 + │ +2 │ return 1 + │ ^^^^^^^^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:4:1 + │ +4 │ end + │ ^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/last-stmt-1/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/last-stmt-1/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..d08c245eff153df28508e6196ee2dc0809a1ec05 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/last-stmt-1/errors.snap @@ -0,0 +1,41 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/last-stmt-1 +--- +- AstError: + token: + start_position: + bytes: 30 + line: 3 + character: 2 + end_position: + bytes: 36 + line: 3 + character: 8 + token_type: + type: Symbol + symbol: return + additional: "expected `end` to close function body block" + range: + - bytes: 20 + line: 2 + character: 2 + - bytes: 28 + line: 2 + character: 10 +- AstError: + token: + start_position: + bytes: 39 + line: 4 + character: 1 + end_position: + bytes: 42 + line: 4 + character: 4 + token_type: + type: Symbol + symbol: end + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/last-stmt-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/last-stmt-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..82fa7719b6bc5875081253e4b72de88d0dec8be4 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/last-stmt-1/source.lua @@ -0,0 +1,4 @@ +local function x() + return 1 + return 2 +end diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/last-stmt-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/last-stmt-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..63be35e326ff5bcf45f35e48a4f42dc90330d62b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/last-stmt-1/tokens.snap @@ -0,0 +1,237 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 68 +expression: tokens +input_file: full-moon/tests/cases/fail/parser/last-stmt-1 +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 19 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 19 + line: 2 + character: 1 + end_position: + bytes: 20 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 20 + line: 2 + character: 2 + end_position: + bytes: 26 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 26 + line: 2 + character: 8 + end_position: + bytes: 27 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 27 + line: 2 + character: 9 + end_position: + bytes: 28 + line: 2 + character: 10 + token_type: + type: Number + text: "1" +- start_position: + bytes: 28 + line: 2 + character: 10 + end_position: + bytes: 29 + line: 2 + character: 10 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 29 + line: 3 + character: 1 + end_position: + bytes: 30 + line: 3 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 30 + line: 3 + character: 2 + end_position: + bytes: 36 + line: 3 + character: 8 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 36 + line: 3 + character: 8 + end_position: + bytes: 37 + line: 3 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 37 + line: 3 + character: 9 + end_position: + bytes: 38 + line: 3 + character: 10 + token_type: + type: Number + text: "2" +- start_position: + bytes: 38 + line: 3 + character: 10 + end_position: + bytes: 39 + line: 3 + character: 10 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 39 + line: 4 + character: 1 + end_position: + bytes: 42 + line: 4 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 42 + line: 4 + character: 4 + end_position: + bytes: 43 + line: 4 + character: 4 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 43 + line: 5 + character: 1 + end_position: + bytes: 43 + line: 5 + character: 1 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..ae6bfc2a24025b8cc086412248a5142c6b478efa --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-1/ast.snap @@ -0,0 +1,82 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/local-assignment-1 +--- +nodes: + stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: ~ + expr_list: + pairs: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-1/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-1/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..460d2b6458505e166d2098e6ad6adaa8ba17684a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-1/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/local-assignment-1 +--- +"local x " + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-1/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-1/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..ef5a06f1770e55e0d6746ebb9963ca71a98e5296 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-1/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/local-assignment-1 +--- +error[ast]: unexpected expression when looking for a statement + ┌─ source.lua:1:10 + │ +1 │ local x y + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-1/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-1/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..c96d532124f818ae8fa7ecdf5899440198fe9bd7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-1/errors.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/local-assignment-1 +--- +- AstError: + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Eof + additional: unexpected expression when looking for a statement + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..0cf360b38e3ba5a7dd4ce77ae4e2f1817980b47a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-1/source.lua @@ -0,0 +1 @@ +local x y \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..d6f53d923d4921af1f18e1e7e9ffbc573397b3d5 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-1/tokens.snap @@ -0,0 +1,72 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/local-assignment-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..59339fecf1c0b2d71389b08456b1a7aae562c8ea --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-2/ast.snap @@ -0,0 +1,96 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/local-assignment-2 +--- +nodes: + stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: [] + expr_list: + pairs: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-2/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-2/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..6e832ffeb306ae0713e25fbfddaa3c45322e03f7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-2/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/local-assignment-2 +--- +local x = + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-2/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-2/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..2d3cc9bc4ffa169fee4af84757394e60f95483da --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-2/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/local-assignment-2 +--- +error[ast]: expected an expression + ┌─ source.lua:1:9 + │ +1 │ local x = + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-2/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-2/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..96c0cc2aa334cc95e1bfd20b90248c0bc9da3a40 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-2/errors.snap @@ -0,0 +1,20 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/local-assignment-2 +--- +- AstError: + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + additional: expected an expression + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..2c2dc7b9e5f03fb0c774a9e0ace9dc6d2471d6b1 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-2/source.lua @@ -0,0 +1 @@ +local x = \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..fa211a7d8ea15a1437e973c04a23f3b5544d2c87 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-2/tokens.snap @@ -0,0 +1,72 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/local-assignment-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-3/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-3/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..ae264791d9c3c8011174c6fa1016213abd50b747 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-3/ast.snap @@ -0,0 +1,123 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/local-assignment-3 +--- +nodes: + stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Number + text: "1" + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-3/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-3/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..abf8f3d5f5fbdc41d73dcb338bf7747ea6267c09 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-3/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/local-assignment-3 +--- +local x = 1 + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-3/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-3/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..df0ad91634d3ae3a442de2ba7fb2cb1407b69600 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-3/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/local-assignment-3 +--- +error[ast]: trailing commas are not allowed + ┌─ source.lua:1:12 + │ +1 │ local x = 1, + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-3/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-3/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..803e6f8620d928b827110080e89978ee227ed004 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-3/errors.snap @@ -0,0 +1,20 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/local-assignment-3 +--- +- AstError: + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: "," + additional: trailing commas are not allowed + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-3/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-3/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..300b32197ec3dca35c6b86d7d621757d5d8deee0 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-3/source.lua @@ -0,0 +1 @@ +local x = 1, \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-3/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-3/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..b93054fcfcb02ec9bb0de403f189fc03f7fd9a79 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-3/tokens.snap @@ -0,0 +1,105 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/local-assignment-3 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Number + text: "1" +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-4/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-4/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..c2680a6d4b38cb4c586e97d2cc7351519d901335 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-4/ast.snap @@ -0,0 +1,23 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/local-assignment-4 +--- +nodes: + stmts: [] +eof: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-4/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-4/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..0c38b06a45ec540af2451482cdecbd39a63165d0 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-4/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/local-assignment-4 +--- +"" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-4/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-4/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..1e8474d97a19ef6195b4857bdc245381f1f0489d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-4/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/local-assignment-4 +--- +error[ast]: expected either a variable name or `function` + ┌─ source.lua:1:7 + │ +1 │ local end + │ ^^^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:7 + │ +1 │ local end + │ ^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-4/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-4/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..0986aef8761ef48122afd5d151c69c0bf3e1422c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-4/errors.snap @@ -0,0 +1,34 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/local-assignment-4 +--- +- AstError: + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: end + additional: "expected either a variable name or `function`" +- AstError: + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: end + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-4/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-4/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..8caefb4edddcde0411600a3d7c333fcddc1e9baa --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-4/source.lua @@ -0,0 +1 @@ +local end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-4/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-4/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..75376bb336f447df8e363cc79a92828831f585e0 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-4/tokens.snap @@ -0,0 +1,50 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/local-assignment-4 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-5/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-5/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..b0996b9e2e53a938354d7bad509f8e9aad3e24bd --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-5/ast.snap @@ -0,0 +1,107 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/local-assignment-5 +--- +nodes: + stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-5/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-5/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..176d6100caeb3c34381a15b043b60c15257b5816 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-5/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/local-assignment-5 +--- +"local x = " + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-5/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-5/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..a0e10c7850c663f4ffe330f414d3c73a46798a98 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-5/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/local-assignment-5 +--- +error[ast]: expected an expression + ┌─ source.lua:1:9 + │ +1 │ local x = end + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:11 + │ +1 │ local x = end + │ ^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-5/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-5/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..24481c2eb56cbc0ade2de04c764d0a4a76830720 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-5/errors.snap @@ -0,0 +1,34 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/local-assignment-5 +--- +- AstError: + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + additional: expected an expression +- AstError: + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: end + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-5/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-5/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..3f05e71f2542416b9c7eb5d205502f296296bc64 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-5/source.lua @@ -0,0 +1 @@ +local x = end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-5/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-5/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..79c63ff56f14a9986b2dcdad6784ee7c9a644838 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-5/tokens.snap @@ -0,0 +1,94 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/local-assignment-5 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-6/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-6/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..c028da3662519a17e9d6d917f077193ad587edc3 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-6/ast.snap @@ -0,0 +1,218 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 16 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/local-assignment-6 +--- +nodes: + stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: "\n" + expr_list: + pairs: [] + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 2 + character: 1 + end_position: + bytes: 15 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 15 + line: 2 + character: 6 + end_position: + bytes: 16 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 16 + line: 2 + character: 7 + end_position: + bytes: 17 + line: 2 + character: 8 + token_type: + type: Identifier + identifier: y + trailing_trivia: + - start_position: + bytes: 17 + line: 2 + character: 8 + end_position: + bytes: 18 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 18 + line: 2 + character: 9 + end_position: + bytes: 19 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 19 + line: 2 + character: 10 + end_position: + bytes: 20 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 20 + line: 2 + character: 11 + end_position: + bytes: 21 + line: 2 + character: 12 + token_type: + type: Number + text: "2" + trailing_trivia: + - start_position: + bytes: 21 + line: 2 + character: 12 + end_position: + bytes: 22 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: "\n" + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 22 + line: 3 + character: 1 + end_position: + bytes: 22 + line: 3 + character: 1 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-6/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-6/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..f2e679fd3329658770ed515d232f85b5fd13e15b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-6/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 19 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/local-assignment-6 +--- +"local x =\nlocal y = 2\n" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-6/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-6/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..5a0551bf93410479ab1292c8cbb5fdce4e78c131 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-6/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/local-assignment-6 +--- +error[ast]: expected an expression + ┌─ source.lua:1:9 + │ +1 │ local x = + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-6/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-6/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..4cd3d0c482b4dcc65f8ae0d07280e6279a870dbd --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-6/errors.snap @@ -0,0 +1,20 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/local-assignment-6 +--- +- AstError: + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + additional: expected an expression + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-6/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-6/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..19f15f419a89c400c320278d08fc09610a5cca20 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-6/source.lua @@ -0,0 +1,2 @@ +local x = +local y = 2 diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-6/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-6/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..f139ed2f23e4a9029789825789e962576559bd8c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-assignment-6/tokens.snap @@ -0,0 +1,171 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 28 +expression: tokens +input_file: full-moon/tests/cases/fail/parser/local-assignment-6 +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 10 + line: 2 + character: 1 + end_position: + bytes: 15 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 15 + line: 2 + character: 6 + end_position: + bytes: 16 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 16 + line: 2 + character: 7 + end_position: + bytes: 17 + line: 2 + character: 8 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 17 + line: 2 + character: 8 + end_position: + bytes: 18 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 18 + line: 2 + character: 9 + end_position: + bytes: 19 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 19 + line: 2 + character: 10 + end_position: + bytes: 20 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 20 + line: 2 + character: 11 + end_position: + bytes: 21 + line: 2 + character: 12 + token_type: + type: Number + text: "2" +- start_position: + bytes: 21 + line: 2 + character: 12 + end_position: + bytes: 22 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 22 + line: 3 + character: 1 + end_position: + bytes: 22 + line: 3 + character: 1 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..8f35e17d6f6bbc41d7f2fccfd7db5d3ecc8f7a45 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-1/ast.snap @@ -0,0 +1,23 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/local-function-1 +--- +nodes: + stmts: [] +eof: + leading_trivia: [] + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-1/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-1/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..8d76b470bc3e5ed9e19187004103570256c98c31 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-1/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/local-function-1 +--- +"" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-1/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-1/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..b0f0828bd454361ab90f5be51decb088d8778a21 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-1/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/local-function-1 +--- +error[ast]: expected a function name + ┌─ source.lua:1:15 + │ +1 │ local function + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-1/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-1/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..df14f81b3438fde5ca26c84275cc10df5d3439bc --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-1/errors.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/local-function-1 +--- +- AstError: + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Eof + additional: expected a function name + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..4ed1c4ee1afbd62c1784ae37391e157ac29e959b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-1/source.lua @@ -0,0 +1 @@ +local function \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..715bb932194148612d8b2e6f85ce15a35eb22b7c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-1/tokens.snap @@ -0,0 +1,50 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/local-function-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..b8d987d67a2d4618bb9f26a1727c254008318637 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-2/ast.snap @@ -0,0 +1,23 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/local-function-2 +--- +nodes: + stmts: [] +eof: + leading_trivia: [] + token: + start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-2/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-2/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..ce98dbbd355efdb9167e5763f2f7592e4709796c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-2/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/local-function-2 +--- +"" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-2/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-2/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..bcac5b4cd3b3a5b8d948151b88ccb1a246e16593 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-2/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/local-function-2 +--- +error[ast]: expected a function body + ┌─ source.lua:1:7 + │ +1 │ local function x + │ ^^^^^^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-2/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-2/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..deacbda1040cee869446f7b615424e50fa42038c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-2/errors.snap @@ -0,0 +1,20 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/local-function-2 +--- +- AstError: + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: function + additional: expected a function body + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..71294aa321d4266f8cd1b0aa5c2fb1cc4b306c8b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-2/source.lua @@ -0,0 +1 @@ +local function x \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..cbecbfdadad33cb1d198f0f157f5fef62ea12788 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-2/tokens.snap @@ -0,0 +1,72 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/local-function-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-3/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-3/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..a773c2b70715ec776357fbf73fdfd258bc4873e2 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-3/ast.snap @@ -0,0 +1,142 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/local-function-3 +--- +nodes: + stmts: + - - LocalFunction: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + function_token: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: function + trailing_trivia: + - start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " + name: + leading_trivia: [] + token: + start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Identifier + identifier: x + trailing_trivia: [] + body: + parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + parameters: + pairs: [] + block: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-3/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-3/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..dcd065bc88adc126f4c4e800949a7de82d5beb6e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-3/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/local-function-3 +--- +local function x()end + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-3/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-3/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..5869ede9a8a2fb8d47fb20c5145a328eab6687b8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-3/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/local-function-3 +--- +error[ast]: expected a parameter name or `)` + ┌─ source.lua:1:18 + │ +1 │ local function x( + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-3/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-3/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..9eb9335c6acb01f6fc16d18048141746c9977d5f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-3/errors.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/local-function-3 +--- +- AstError: + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Eof + additional: "expected a parameter name or `)`" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-3/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-3/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..77406ec971ec3aaca37d4525b132527611ec674f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-3/source.lua @@ -0,0 +1 @@ +local function x( \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-3/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-3/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..cda814402975d5b424393bdb5041e8b0a4eb3fda --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-3/tokens.snap @@ -0,0 +1,83 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/local-function-3 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-4/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-4/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..4a10477cbf0adb9a0b2e39de7494d6308d71f7fe --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-4/ast.snap @@ -0,0 +1,218 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/local-function-4 +--- +nodes: + stmts: + - - LocalFunction: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + function_token: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: function + trailing_trivia: + - start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " + name: + leading_trivia: [] + token: + start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Identifier + identifier: x + trailing_trivia: [] + body: + parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 19 + token_type: + type: Whitespace + characters: "\n" + parameters: + pairs: [] + block: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 19 + line: 2 + character: 1 + end_position: + bytes: 20 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 20 + line: 2 + character: 2 + end_position: + bytes: 24 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 24 + line: 2 + character: 6 + end_position: + bytes: 25 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 25 + line: 2 + character: 7 + end_position: + bytes: 26 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: [] + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 26 + line: 2 + character: 8 + end_position: + bytes: 26 + line: 2 + character: 8 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-4/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-4/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..ac7252d66f3cdff17e2282ccdd01846dbcdb47c0 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-4/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/local-function-4 +--- +"local function x()\n\tcall()end" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-4/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-4/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..6f3e49e12ccefdba884742fe361a42de1b79d708 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-4/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/local-function-4 +--- +error[ast]: expected `end` to close function body block + ┌─ source.lua:2:2 + │ +2 │ call() + │ ^^^^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-4/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-4/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..5af4c8dcdc226946abca16a0eddb1e0c79c72e38 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-4/errors.snap @@ -0,0 +1,26 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/local-function-4 +--- +- AstError: + token: + start_position: + bytes: 26 + line: 2 + character: 8 + end_position: + bytes: 26 + line: 2 + character: 8 + token_type: + type: Eof + additional: "expected `end` to close function body block" + range: + - bytes: 20 + line: 2 + character: 2 + - bytes: 26 + line: 2 + character: 8 + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-4/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-4/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..331172a3f721eacee237f197b0e246b0052c0032 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-4/source.lua @@ -0,0 +1,2 @@ +local function x() + call() \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-4/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-4/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..b0627c737e825a21fb1fda8f937ef34df3ba6bc5 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-4/tokens.snap @@ -0,0 +1,149 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/local-function-4 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 19 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 19 + line: 2 + character: 1 + end_position: + bytes: 20 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 20 + line: 2 + character: 2 + end_position: + bytes: 24 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 24 + line: 2 + character: 6 + end_position: + bytes: 25 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 25 + line: 2 + character: 7 + end_position: + bytes: 26 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 26 + line: 2 + character: 8 + end_position: + bytes: 26 + line: 2 + character: 8 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-5/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-5/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..0b5cf6080f132d43a5aa067a4ef75ff1a7ae1cdb --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-5/ast.snap @@ -0,0 +1,99 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/local-function-5 +--- +nodes: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 20 + line: 2 + character: 1 + end_position: + bytes: 21 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 21 + line: 2 + character: 2 + end_position: + bytes: 25 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 25 + line: 2 + character: 6 + end_position: + bytes: 26 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 26 + line: 2 + character: 7 + end_position: + bytes: 27 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 27 + line: 2 + character: 8 + end_position: + bytes: 28 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 31 + line: 3 + character: 4 + end_position: + bytes: 31 + line: 3 + character: 4 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-5/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-5/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..de523db4473eda33b301e8d34667685fbb81d074 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-5/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/local-function-5 +--- +"\tcall()\n" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-5/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-5/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..1dfd6ef626b9c9e789f027eedc256b6b8ae07498 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-5/error_display.snap @@ -0,0 +1,25 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/local-function-5 +--- +error[ast]: expected a function name + ┌─ source.lua:1:16 + │ +1 │ local function do() + │ ^^ + +error[ast]: expected an expression after `(` + ┌─ source.lua:1:18 + │ +1 │ local function do() + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:19 + │ +1 │ local function do() + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-5/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-5/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..62ba729e21dc0ed73698d5ab863ce1c148764e69 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-5/errors.snap @@ -0,0 +1,48 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/local-function-5 +--- +- AstError: + token: + start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: do + additional: expected a function name +- AstError: + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: ( + additional: "expected an expression after `(`" +- AstError: + token: + start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: ) + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-5/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-5/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..da8ec8e722d9a6c5b167edbe473b3233e6abdd15 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-5/source.lua @@ -0,0 +1,3 @@ +local function do() + call() +end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-5/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-5/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..033bdb9e185df42940edde99262bc2dec3156c1c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-5/tokens.snap @@ -0,0 +1,171 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/local-function-5 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 20 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 20 + line: 2 + character: 1 + end_position: + bytes: 21 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 21 + line: 2 + character: 2 + end_position: + bytes: 25 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 25 + line: 2 + character: 6 + end_position: + bytes: 26 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 26 + line: 2 + character: 7 + end_position: + bytes: 27 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 27 + line: 2 + character: 8 + end_position: + bytes: 28 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 28 + line: 3 + character: 1 + end_position: + bytes: 31 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 31 + line: 3 + character: 4 + end_position: + bytes: 31 + line: 3 + character: 4 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-6/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-6/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..e78329aadda9ca8a34e968643ad0a31f4d5a72b6 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-6/ast.snap @@ -0,0 +1,142 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/local-function-6 +--- +nodes: + stmts: + - - LocalFunction: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + function_token: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: function + trailing_trivia: + - start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " + name: + leading_trivia: [] + token: + start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Identifier + identifier: x + trailing_trivia: [] + body: + parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + parameters: + pairs: [] + block: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 25 + line: 2 + character: 4 + end_position: + bytes: 25 + line: 2 + character: 4 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-6/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-6/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..0c52e3cbfef9aa5a5cd585c3153c97832ad518cc --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-6/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/local-function-6 +--- +local function x()end + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-6/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-6/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..f975547be845a56e442757c0c88efeb83d270ef2 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-6/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/local-function-6 +--- +error[ast]: expected a parameter name or `)` + ┌─ source.lua:1:18 + │ +1 │ local function x(,,,) + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:18 + │ +1 │ local function x(,,,) + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-6/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-6/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..e362a18e3323196b60996ade0f0b2ece1e9c989e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-6/errors.snap @@ -0,0 +1,34 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/local-function-6 +--- +- AstError: + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: "," + additional: "expected a parameter name or `)`" +- AstError: + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: "," + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-6/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-6/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..c336e50fac229bc8d66560a99a9defd9049417d7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-6/source.lua @@ -0,0 +1,2 @@ +local function x(,,,) +end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-6/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-6/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..e9f5a5605799ab10b4f68c3cc2252aba7b9638a4 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-6/tokens.snap @@ -0,0 +1,149 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/local-function-6 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 22 + line: 1 + character: 22 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 22 + line: 2 + character: 1 + end_position: + bytes: 25 + line: 2 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 25 + line: 2 + character: 4 + end_position: + bytes: 25 + line: 2 + character: 4 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-7/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-7/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..e7e3d4c8c987a56a62e1b6698f034922dad3e2b0 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-7/ast.snap @@ -0,0 +1,356 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 16 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/local-function-7 +--- +nodes: + stmts: + - - LocalFunction: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + function_token: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: function + trailing_trivia: + - start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " + name: + leading_trivia: [] + token: + start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Identifier + identifier: foo + trailing_trivia: [] + body: + parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 24 + line: 1 + character: 25 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 26 + line: 1 + character: 26 + token_type: + type: Whitespace + characters: "\n" + parameters: + pairs: + - Punctuated: + - Name: + leading_trivia: [] + token: + start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Identifier + identifier: x + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Whitespace + characters: " " + - End: + Name: + leading_trivia: [] + token: + start_position: + bytes: 22 + line: 1 + character: 23 + end_position: + bytes: 23 + line: 1 + character: 24 + token_type: + type: Identifier + identifier: y + trailing_trivia: [] + block: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 26 + line: 2 + character: 1 + end_position: + bytes: 27 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 27 + line: 2 + character: 2 + end_position: + bytes: 32 + line: 2 + character: 7 + token_type: + type: Identifier + identifier: print + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 32 + line: 2 + character: 7 + end_position: + bytes: 33 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 37 + line: 2 + character: 12 + end_position: + bytes: 38 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 38 + line: 2 + character: 13 + end_position: + bytes: 39 + line: 2 + character: 13 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - Punctuated: + - Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 33 + line: 2 + character: 8 + end_position: + bytes: 34 + line: 2 + character: 9 + token_type: + type: Identifier + identifier: x + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 34 + line: 2 + character: 9 + end_position: + bytes: 35 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 35 + line: 2 + character: 10 + end_position: + bytes: 36 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: " " + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 36 + line: 2 + character: 11 + end_position: + bytes: 37 + line: 2 + character: 12 + token_type: + type: Identifier + identifier: y + trailing_trivia: [] + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 39 + line: 3 + character: 1 + end_position: + bytes: 42 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 42 + line: 3 + character: 4 + end_position: + bytes: 43 + line: 3 + character: 4 + token_type: + type: Whitespace + characters: "\n" + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 43 + line: 4 + character: 1 + end_position: + bytes: 43 + line: 4 + character: 1 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-7/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-7/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..1220ccdc504db1b7c481050e2d25c84957815ae7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-7/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 19 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/local-function-7 +--- +"local function foo(x, y)\n\tprint(x, y)\nend\n" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-7/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-7/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..5eeef31cdb311385c5569acf78a61bf914ec2c95 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-7/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/local-function-7 +--- +error[ast]: trailing commas in arguments are not allowed + ┌─ source.lua:1:24 + │ +1 │ local function foo(x, y,) + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-7/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-7/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..9d5612ccbe906817d9b1b9a5975484e1d2b7f853 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-7/errors.snap @@ -0,0 +1,20 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/local-function-7 +--- +- AstError: + token: + start_position: + bytes: 23 + line: 1 + character: 24 + end_position: + bytes: 24 + line: 1 + character: 25 + token_type: + type: Symbol + symbol: "," + additional: trailing commas in arguments are not allowed + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-7/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-7/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..504b767851a30193242afdd77747a15dce986cbd --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-7/source.lua @@ -0,0 +1,3 @@ +local function foo(x, y,) + print(x, y) +end diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-7/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-7/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..f7d41dc317be00fa8d3133d18e050ea307345694 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/local-function-7/tokens.snap @@ -0,0 +1,281 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 28 +expression: tokens +input_file: full-moon/tests/cases/fail/parser/local-function-7 +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 22 + line: 1 + character: 23 + end_position: + bytes: 23 + line: 1 + character: 24 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 23 + line: 1 + character: 24 + end_position: + bytes: 24 + line: 1 + character: 25 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 24 + line: 1 + character: 25 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 26 + line: 1 + character: 26 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 26 + line: 2 + character: 1 + end_position: + bytes: 27 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 27 + line: 2 + character: 2 + end_position: + bytes: 32 + line: 2 + character: 7 + token_type: + type: Identifier + identifier: print +- start_position: + bytes: 32 + line: 2 + character: 7 + end_position: + bytes: 33 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 33 + line: 2 + character: 8 + end_position: + bytes: 34 + line: 2 + character: 9 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 34 + line: 2 + character: 9 + end_position: + bytes: 35 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 35 + line: 2 + character: 10 + end_position: + bytes: 36 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 36 + line: 2 + character: 11 + end_position: + bytes: 37 + line: 2 + character: 12 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 37 + line: 2 + character: 12 + end_position: + bytes: 38 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 38 + line: 2 + character: 13 + end_position: + bytes: 39 + line: 2 + character: 13 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 39 + line: 3 + character: 1 + end_position: + bytes: 42 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 42 + line: 3 + character: 4 + end_position: + bytes: 43 + line: 3 + character: 4 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 43 + line: 4 + character: 1 + end_position: + bytes: 43 + line: 4 + character: 1 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..10cea19b2a0020ff4d74a9688ab63ba059d36ad0 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-1/ast.snap @@ -0,0 +1,71 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/method-call-1 +--- +nodes: + stmts: [] + last_stmt: + - Return: + token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + returns: + pairs: + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Identifier + identifier: name + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-1/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-1/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..34862c5a9473231f0ec2fc277e9a3b3dc5a5f680 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-1/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/method-call-1 +--- +return name + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-1/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-1/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..30fe852b1652331e979dd5cf9fb0fa477c4f4253 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-1/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/method-call-1 +--- +error[ast]: expected identifier after `:` + ┌─ source.lua:1:12 + │ +1 │ return name: + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-1/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-1/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..7ec3fb30bfb5218714638d86341b189d9621e25a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-1/errors.snap @@ -0,0 +1,20 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/method-call-1 +--- +- AstError: + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: ":" + additional: "expected identifier after `:`" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..0f7db618c4ddc75bfe56e889fa2b58d48b02a62c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-1/source.lua @@ -0,0 +1 @@ +return name: \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..b8f4c4345513da039c4001cef868687a379abcf2 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-1/tokens.snap @@ -0,0 +1,61 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/method-call-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Identifier + identifier: name +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..249ed2dedbd3d06af70a06ffb06097502637e09d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-2/ast.snap @@ -0,0 +1,139 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/method-call-2 +--- +nodes: + stmts: [] + last_stmt: + - Return: + token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + returns: + pairs: + - End: + FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Identifier + identifier: name + trailing_trivia: [] + suffixes: + - Call: + MethodCall: + colon_token: + leading_trivia: [] + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Identifier + identifier: method + trailing_trivia: [] + args: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-2/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-2/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..b2bfc3fcaf8f0643267c3a03ec09625551460605 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-2/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/method-call-2 +--- +"return name:method()" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-2/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-2/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..2fbc475f72211455041feafb2d288956cdf34e5a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-2/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/method-call-2 +--- +error[ast]: expected arguments after `:` + ┌─ source.lua:1:13 + │ +1 │ return name:method + │ ^^^^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-2/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-2/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..87bf91f99a9e18f2d0d483f3a43374cf88c6cf32 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-2/errors.snap @@ -0,0 +1,20 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/method-call-2 +--- +- AstError: + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Identifier + identifier: method + additional: "expected arguments after `:`" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..31c242137becd656c8116c1f166ba515bd72fd51 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-2/source.lua @@ -0,0 +1 @@ +return name:method \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..e27b8bc2f9fbc1f42b44c0be2c6aa6c78b28e8a1 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-2/tokens.snap @@ -0,0 +1,72 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/method-call-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Identifier + identifier: name +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Identifier + identifier: method +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-3/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-3/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..9135a8022e0747d03786ac92bccb9594589aa962 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-3/ast.snap @@ -0,0 +1,139 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/method-call-3 +--- +nodes: + stmts: [] + last_stmt: + - Return: + token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + returns: + pairs: + - End: + FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Identifier + identifier: name + trailing_trivia: [] + suffixes: + - Call: + MethodCall: + colon_token: + leading_trivia: [] + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Identifier + identifier: method + trailing_trivia: [] + args: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-3/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-3/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..753afafe66c1b17ff60fa8e290c8ec4e33ab8fdf --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-3/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/method-call-3 +--- +"return name:method()" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-3/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-3/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..3d5571a1511caeecd5c9fe8443116ca0f20ec4d3 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-3/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/method-call-3 +--- +error[ast]: expected `)` to close function call + ┌─ source.lua:1:19 + │ +1 │ return name:method(until) + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:20 + │ +1 │ return name:method(until) + │ ^^^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-3/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-3/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..7d92bd966e23e998095491b3d494c1f47d6cb5c1 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-3/errors.snap @@ -0,0 +1,34 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/method-call-3 +--- +- AstError: + token: + start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: ( + additional: "expected `)` to close function call" +- AstError: + token: + start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 24 + line: 1 + character: 25 + token_type: + type: Symbol + symbol: until + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-3/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-3/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..429cba6ffa10899eb08518fecbb57875729b7c8b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-3/source.lua @@ -0,0 +1 @@ +return name:method(until) \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-3/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-3/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..a4b10b3c53012fd1a33fb34cf25f4e85f193ce7d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/method-call-3/tokens.snap @@ -0,0 +1,105 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/method-call-3 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Identifier + identifier: name +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Identifier + identifier: method +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 24 + line: 1 + character: 25 + token_type: + type: Symbol + symbol: until +- start_position: + bytes: 24 + line: 1 + character: 25 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..50bd5002485d0c57408fae57e66c88f6dd896966 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-1/ast.snap @@ -0,0 +1,23 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/numeric-for-1 +--- +nodes: + stmts: [] +eof: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-1/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-1/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..363e04143ddc77bff490cbe59258ca430aebd43b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-1/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/numeric-for-1 +--- +"" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-1/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-1/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..cdc726b12cb83bf7f928eb6c2c6b182d429d20bf --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-1/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/numeric-for-1 +--- +error[ast]: expected `in` after name list + ┌─ source.lua:1:6 + │ +1 │ for x + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-1/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-1/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..c2a73d30c64652f62708d95399d972271b5e5d7f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-1/errors.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/numeric-for-1 +--- +- AstError: + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Eof + additional: "expected `in` after name list" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..0c7580fbd55234e2f33b547ea7cbf4a0199cc81f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-1/source.lua @@ -0,0 +1 @@ +for x \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..e164a83469a4048209043a3a7f7c5020b1d9bc36 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-1/tokens.snap @@ -0,0 +1,50 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/numeric-for-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: for +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..547db2e22765bd1d546ae5c9696d049fed493304 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-2/ast.snap @@ -0,0 +1,23 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/numeric-for-2 +--- +nodes: + stmts: [] +eof: + leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-2/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-2/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..70fc306dd5b5ac6e4ce678ae2b10ae6881cc5b94 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-2/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/numeric-for-2 +--- +"" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-2/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-2/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..f73b49c048d3ff106c51042e7810410a9ce4e182 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-2/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/numeric-for-2 +--- +error[ast]: expected start expression after `=` + ┌─ source.lua:1:7 + │ +1 │ for x = + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-2/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-2/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..7204f02399c901deea3a8fa14107c66c20251d7b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-2/errors.snap @@ -0,0 +1,20 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/numeric-for-2 +--- +- AstError: + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Symbol + symbol: "=" + additional: "expected start expression after `=`" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..1f74b3d40e68aa5670e5dbc38ddf87e4f8cea61f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-2/source.lua @@ -0,0 +1 @@ +for x = \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..9e7fbad166897de718f777f61696ed899df421b1 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-2/tokens.snap @@ -0,0 +1,72 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/numeric-for-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: for +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-3/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-3/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..8fed389ee9a7fe7b028d7e15fe96230da53ceb7e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-3/ast.snap @@ -0,0 +1,23 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/numeric-for-3 +--- +nodes: + stmts: [] +eof: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-3/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-3/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..9fb0dbedfbae1e795fb369d480c31e89c31293c7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-3/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/numeric-for-3 +--- +"" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-3/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-3/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..920020088426c951f645c115f5d769706a3a1821 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-3/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/numeric-for-3 +--- +error[ast]: expected `,` after start expression + ┌─ source.lua:1:10 + │ +1 │ for x = 1 + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-3/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-3/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..e82f9db0ae4c79c2f5c4de06ce23f7081cc79fd9 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-3/errors.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/numeric-for-3 +--- +- AstError: + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Eof + additional: "expected `,` after start expression" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-3/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-3/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..f4d3b123d5ec5d334e698ebc4132d271a01b656e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-3/source.lua @@ -0,0 +1 @@ +for x = 1 \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-3/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-3/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..c8d19ffde936df174b87edb851f1795c2f54321f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-3/tokens.snap @@ -0,0 +1,94 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/numeric-for-3 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: for +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Number + text: "1" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-4/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-4/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..92be5c7f3b34d6dfb671230dfcadd0ce18910e89 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-4/ast.snap @@ -0,0 +1,206 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/numeric-for-4 +--- +nodes: + stmts: + - - NumericFor: + for_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: for + trailing_trivia: + - start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " + index_variable: + leading_trivia: [] + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + start: + Number: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Number + text: "1" + trailing_trivia: [] + start_end_comma: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " + end: + Number: + leading_trivia: [] + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Number + text: "10" + trailing_trivia: + - start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: " " + end_step_comma: ~ + step: ~ + do_token: + leading_trivia: [] + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Symbol + symbol: do + trailing_trivia: [] + block: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-4/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-4/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..395156c092edb476706e054554f544bef34925a8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-4/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/numeric-for-4 +--- +"for x = 1, 10 doend" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-4/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-4/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..d6a949819f39d87cd4499c42baf4b19033dde88b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-4/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/numeric-for-4 +--- +error[ast]: expected `end` to close numeric for loop block + ┌─ source.lua:1:15 + │ +1 │ for x = 1, 10 do + │ ^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-4/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-4/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..5a548ac903e71e88fb401a143eaed92ff9b71e9f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-4/errors.snap @@ -0,0 +1,26 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/numeric-for-4 +--- +- AstError: + token: + start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Eof + additional: "expected `end` to close numeric for loop block" + range: + - bytes: 14 + line: 1 + character: 15 + - bytes: 16 + line: 1 + character: 17 + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-4/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-4/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..0d07ab005349139f949327e6b1b59ca482d32af2 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-4/source.lua @@ -0,0 +1 @@ +for x = 1, 10 do \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-4/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-4/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..3e9336960139b98dd54c8c24e514bd73e6210979 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-4/tokens.snap @@ -0,0 +1,149 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/numeric-for-4 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: for +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Number + text: "1" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Number + text: "10" +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-5/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-5/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..2ef9e72370685117cc2ae826b93781f09227865a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-5/ast.snap @@ -0,0 +1,68 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/numeric-for-5 +--- +nodes: + stmts: + - - Do: + do_token: + leading_trivia: [] + token: + start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Whitespace + characters: " " + block: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 24 + line: 1 + character: 25 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 24 + line: 1 + character: 25 + end_position: + bytes: 24 + line: 1 + character: 25 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-5/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-5/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..bc70ea9e65bb3f67831bc60b9d8e44ada365b08a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-5/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/numeric-for-5 +--- +do end + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-5/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-5/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..6dd956acde3eeac9b63cac8d4612434ece0d7dea --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-5/error_display.snap @@ -0,0 +1,25 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/numeric-for-5 +--- +error[ast]: expected name after `for` + ┌─ source.lua:1:1 + │ +1 │ for local = 1, 10 do end + │ ^^^ + +error[ast]: expected either a variable name or `function` + ┌─ source.lua:1:11 + │ +1 │ for local = 1, 10 do end + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:11 + │ +1 │ for local = 1, 10 do end + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-5/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-5/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..b9069091cd820feeaf8db9c3eb2804ee081d0bc1 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-5/errors.snap @@ -0,0 +1,48 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/numeric-for-5 +--- +- AstError: + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: for + additional: "expected name after `for`" +- AstError: + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "=" + additional: "expected either a variable name or `function`" +- AstError: + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "=" + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-5/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-5/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..45af1fab8f3468d2514cd9ffe501bfd56fa8b863 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-5/source.lua @@ -0,0 +1 @@ +for local = 1, 10 do end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-5/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-5/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..6d0e42a24ff6b43ea15f12b170766536dd80d4e5 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/numeric-for-5/tokens.snap @@ -0,0 +1,171 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/numeric-for-5 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: for +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Number + text: "1" +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Number + text: "10" +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 24 + line: 1 + character: 25 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 24 + line: 1 + character: 25 + end_position: + bytes: 24 + line: 1 + character: 25 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..9a618d3f99a7ab68aeaf7b9afb275452ec7d86bd --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-1/ast.snap @@ -0,0 +1,54 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/paren-expression-1 +--- +nodes: + stmts: [] + last_stmt: + - Return: + token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + returns: + pairs: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-1/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-1/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..5f9ff840359585f180b2834ba66f96f7369dc937 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-1/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/paren-expression-1 +--- +"return " + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-1/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-1/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..3fbcc487cbe870129eab9f8a723607ae52650068 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-1/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/paren-expression-1 +--- +error[ast]: expected an expression after `(` + ┌─ source.lua:1:8 + │ +1 │ return ( + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-1/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-1/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..94c958e99652af787a390f1ee1da084a481d4adf --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-1/errors.snap @@ -0,0 +1,20 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/paren-expression-1 +--- +- AstError: + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: ( + additional: "expected an expression after `(`" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..498797ac04a166e7ad1493a94717c06c298da6ae --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-1/source.lua @@ -0,0 +1 @@ +return ( \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..17476f3c50561e57579303090097f0e0e8252a89 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-1/tokens.snap @@ -0,0 +1,50 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/paren-expression-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..a1bed51048e45062f9d295a25dba1f08ede2b82e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-2/ast.snap @@ -0,0 +1,143 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/paren-expression-2 +--- +nodes: + stmts: [] + last_stmt: + - Return: + token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + returns: + pairs: + - Punctuated: + - Parentheses: + contained: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + expression: + Number: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Number + text: "3" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Number + text: "4" + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-2/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-2/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..e6a440014723035f9019a233566e9d81dc6a9793 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-2/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/paren-expression-2 +--- +"return (3), 4" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-2/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-2/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..f9bdf54885876896bb0bb4a286e91d563b7bc8f2 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-2/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/paren-expression-2 +--- +error[ast]: expected `)` after expression + ┌─ source.lua:1:10 + │ +1 │ return (3, 4 + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-2/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-2/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..87e5d06e78b76386476905bb55b06a63c0460672 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-2/errors.snap @@ -0,0 +1,20 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/paren-expression-2 +--- +- AstError: + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "," + additional: "expected `)` after expression" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..b60c08d971161f7ea34fcf3c6010f325fc98b95c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-2/source.lua @@ -0,0 +1 @@ +return (3, 4 \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..055a1c059888f0dc27528a3a3f24b458acdc083b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-2/tokens.snap @@ -0,0 +1,94 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/paren-expression-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Number + text: "3" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Number + text: "4" +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-3/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-3/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..2729875cc27c3275854aa44ad62678f389df5fce --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-3/ast.snap @@ -0,0 +1,143 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/paren-expression-3 +--- +nodes: + stmts: [] + last_stmt: + - Return: + token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + returns: + pairs: + - Punctuated: + - Parentheses: + contained: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + expression: + Number: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Number + text: "3" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Number + text: "4" + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-3/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-3/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..38dd977ea46c485f7cd7165723e0d5549216c9f3 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-3/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/paren-expression-3 +--- +"return (3), 4" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-3/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-3/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..f71cc90fb8791c1a90c623ac391ae3b2138b8188 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-3/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/paren-expression-3 +--- +error[ast]: expected `)` after expression + ┌─ source.lua:1:10 + │ +1 │ return (3, 4, + │ ^ + +error[ast]: trailing commas are not allowed + ┌─ source.lua:1:13 + │ +1 │ return (3, 4, + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-3/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-3/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..39c04a7bd05ab74dec144e653260d3461adf6d52 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-3/errors.snap @@ -0,0 +1,34 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/paren-expression-3 +--- +- AstError: + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "," + additional: "expected `)` after expression" +- AstError: + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: "," + additional: trailing commas are not allowed + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-3/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-3/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..2ae24baed03959c0ca9de0fd002f71d3764ed63e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-3/source.lua @@ -0,0 +1 @@ +return (3, 4, \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-3/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-3/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..d2b2f69d943c07f7edd26e534706803cfad1d899 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-3/tokens.snap @@ -0,0 +1,105 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/paren-expression-3 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Number + text: "3" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Number + text: "4" +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-4/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-4/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..81bfc7d2ee38be6c0882f92eb0525823a81870ec --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-4/ast.snap @@ -0,0 +1,54 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/paren-expression-4 +--- +nodes: + stmts: [] + last_stmt: + - Return: + token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + returns: + pairs: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-4/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-4/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..dfbce515b4887f49d571400de8d35fe5048cae48 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-4/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/paren-expression-4 +--- +"return " + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-4/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-4/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..0651705c1c3d29e7eb6648fc4b276cc22ce1a931 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-4/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/paren-expression-4 +--- +error[ast]: expected an expression after `(` + ┌─ source.lua:1:8 + │ +1 │ return () + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:9 + │ +1 │ return () + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-4/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-4/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..a8953076c6518f6beab303a4ae8a35b0535816b5 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-4/errors.snap @@ -0,0 +1,34 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/paren-expression-4 +--- +- AstError: + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: ( + additional: "expected an expression after `(`" +- AstError: + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: ) + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-4/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-4/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..008b3d5c1754cc3a974a74173d94a8cb875b4234 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-4/source.lua @@ -0,0 +1 @@ +return () \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-4/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-4/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..52735c2fb88d146af927b97eb35cec4d0f1f6338 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-4/tokens.snap @@ -0,0 +1,61 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/paren-expression-4 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-5/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-5/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..19f591f1d212fc7bcf0368c35fb1094fa3740fb4 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-5/ast.snap @@ -0,0 +1,54 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/paren-expression-5 +--- +nodes: + stmts: [] + last_stmt: + - Return: + token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + returns: + pairs: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-5/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-5/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..e7b4acaa691f9bb8182f04c5049640f8a25304b0 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-5/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/paren-expression-5 +--- +"return " + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-5/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-5/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..f0a08736463530507f1be6c8bcef51944831b0aa --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-5/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/paren-expression-5 +--- +error[ast]: expected an expression after `(` + ┌─ source.lua:1:8 + │ +1 │ return (until) + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:9 + │ +1 │ return (until) + │ ^^^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-5/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-5/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..7d3f51798633c48d41cb83ee1d29e7ec49b16131 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-5/errors.snap @@ -0,0 +1,34 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/paren-expression-5 +--- +- AstError: + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: ( + additional: "expected an expression after `(`" +- AstError: + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: until + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-5/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-5/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..91e91af97cbe67bfee5ba7660010d2f98ad3b387 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-5/source.lua @@ -0,0 +1 @@ +return (until) \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-5/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-5/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..a227c80b0d4d11dd34db8d61d3aa3924f2e84c00 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/paren-expression-5/tokens.snap @@ -0,0 +1,72 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/paren-expression-5 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: until +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..f387c3cd64d3b74623bc681288d28d6c332c8823 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-1/ast.snap @@ -0,0 +1,79 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/repeat-until-1 +--- +nodes: + stmts: + - - Do: + do_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 3 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: [] + end_token: + leading_trivia: + - start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 1 + line: 2 + character: 1 + end_position: + bytes: 4 + line: 2 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-1/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-1/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..a2fdc4329f1d0de76f8756bce0a07042f53d29bd --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-1/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/repeat-until-1 +--- +"do\n\nend" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-1/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-1/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..bbc3c0f3678b525a1ecf1ffdf66c6229f14e592a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-1/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/repeat-until-1 +--- +error[ast]: expected `until` after block + ┌─ source.lua:1:7 + │ +1 │ repeat + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-1/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-1/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..f9d9c70617d767fc8b33c905ce3cdcef9c920f39 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-1/errors.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/repeat-until-1 +--- +- AstError: + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Eof + additional: "expected `until` after block" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..04611be224fef867cb214f0ed7d7b6646edd8d08 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-1/source.lua @@ -0,0 +1 @@ +repeat \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..8bba2cde2ad894837a0ac3900cd8d9f75397ef9f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-1/tokens.snap @@ -0,0 +1,28 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/repeat-until-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: repeat +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..49243233e777647aba7a53ac4100745d36716787 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-2/ast.snap @@ -0,0 +1,144 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/repeat-until-2 +--- +nodes: + stmts: + - - Do: + do_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 3 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 7 + line: 2 + character: 1 + end_position: + bytes: 8 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 8 + line: 2 + character: 2 + end_position: + bytes: 12 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 12 + line: 2 + character: 6 + end_position: + bytes: 13 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 13 + line: 2 + character: 7 + end_position: + bytes: 14 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: [] + - ~ + end_token: + leading_trivia: + - start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 1 + line: 2 + character: 1 + end_position: + bytes: 4 + line: 2 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 14 + line: 2 + character: 8 + end_position: + bytes: 14 + line: 2 + character: 8 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-2/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-2/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..ceaa951c773d733002bb3392ffe5378e30c35f59 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-2/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/repeat-until-2 +--- +"do\n\tcall()\nend" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-2/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-2/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..df4d7506b1d5d306e1c198649209d57ae5ee5774 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-2/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/repeat-until-2 +--- +error[ast]: expected `until` after block + ┌─ source.lua:2:8 + │ +2 │ call() + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-2/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-2/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..d3726ae89c85fd5d12efb3cd52fc03271e0de603 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-2/errors.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/repeat-until-2 +--- +- AstError: + token: + start_position: + bytes: 14 + line: 2 + character: 8 + end_position: + bytes: 14 + line: 2 + character: 8 + token_type: + type: Eof + additional: "expected `until` after block" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..a263ef25120f6849ff8a68fefd7fa4c399269741 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-2/source.lua @@ -0,0 +1,2 @@ +repeat + call() \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..a9c3341eb4023dfd9e3071ebf464df37299315d3 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-2/tokens.snap @@ -0,0 +1,83 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/repeat-until-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: repeat +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 7 + line: 2 + character: 1 + end_position: + bytes: 8 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 8 + line: 2 + character: 2 + end_position: + bytes: 12 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 12 + line: 2 + character: 6 + end_position: + bytes: 13 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 13 + line: 2 + character: 7 + end_position: + bytes: 14 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 14 + line: 2 + character: 8 + end_position: + bytes: 14 + line: 2 + character: 8 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-3/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-3/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..1ba3b873d16a0467e2c95ae7b32c9b3bcc585658 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-3/ast.snap @@ -0,0 +1,155 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/repeat-until-3 +--- +nodes: + stmts: + - - Do: + do_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 3 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 7 + line: 2 + character: 1 + end_position: + bytes: 8 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 8 + line: 2 + character: 2 + end_position: + bytes: 12 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 12 + line: 2 + character: 6 + end_position: + bytes: 13 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 13 + line: 2 + character: 7 + end_position: + bytes: 14 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 14 + line: 2 + character: 8 + end_position: + bytes: 15 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: [] + - ~ + end_token: + leading_trivia: + - start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 1 + line: 2 + character: 1 + end_position: + bytes: 4 + line: 2 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 20 + line: 3 + character: 6 + end_position: + bytes: 20 + line: 3 + character: 6 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-3/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-3/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..1ab5241a533b490de16de817e4eee34fc0805877 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-3/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/repeat-until-3 +--- +"do\n\tcall()\n\nend" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-3/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-3/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..d07697591a12ee00c23854efca45bf18533a7213 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-3/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/repeat-until-3 +--- +error[ast]: expected a condition after `until` + ┌─ source.lua:3:1 + │ +3 │ until + │ ^^^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-3/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-3/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..babdc5f4d1c3b5e0dbb46d7ee4bf38db4f16a6fe --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-3/errors.snap @@ -0,0 +1,20 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/repeat-until-3 +--- +- AstError: + token: + start_position: + bytes: 15 + line: 3 + character: 1 + end_position: + bytes: 20 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: until + additional: "expected a condition after `until`" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-3/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-3/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..e13a9379c33b6de3e5a9e53593d5717187c87945 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-3/source.lua @@ -0,0 +1,3 @@ +repeat + call() +until \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-3/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-3/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..b9d2db4c3b783291464a5b991724885b08b12ae0 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-3/tokens.snap @@ -0,0 +1,105 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/repeat-until-3 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: repeat +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 7 + line: 2 + character: 1 + end_position: + bytes: 8 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 8 + line: 2 + character: 2 + end_position: + bytes: 12 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 12 + line: 2 + character: 6 + end_position: + bytes: 13 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 13 + line: 2 + character: 7 + end_position: + bytes: 14 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 14 + line: 2 + character: 8 + end_position: + bytes: 15 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 15 + line: 3 + character: 1 + end_position: + bytes: 20 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: until +- start_position: + bytes: 20 + line: 3 + character: 6 + end_position: + bytes: 20 + line: 3 + character: 6 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-4/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-4/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..6e35709d3b5b0b65a5027ef733003570aa25fb5e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-4/ast.snap @@ -0,0 +1,155 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/repeat-until-4 +--- +nodes: + stmts: + - - Do: + do_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 3 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 7 + line: 2 + character: 1 + end_position: + bytes: 8 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 8 + line: 2 + character: 2 + end_position: + bytes: 12 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 12 + line: 2 + character: 6 + end_position: + bytes: 13 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 13 + line: 2 + character: 7 + end_position: + bytes: 14 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 14 + line: 2 + character: 8 + end_position: + bytes: 15 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: [] + - ~ + end_token: + leading_trivia: + - start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 1 + line: 2 + character: 1 + end_position: + bytes: 4 + line: 2 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 24 + line: 3 + character: 10 + end_position: + bytes: 24 + line: 3 + character: 10 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-4/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-4/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..ee53670a33222e14400beee8e2a18652aeaa6132 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-4/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/repeat-until-4 +--- +"do\n\tcall()\n\nend" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-4/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-4/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..39b0e1663830895286f6b54d02cb5ad00b564cd3 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-4/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/repeat-until-4 +--- +error[ast]: expected a condition after `until` + ┌─ source.lua:3:1 + │ +3 │ until end + │ ^^^^^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:3:7 + │ +3 │ until end + │ ^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-4/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-4/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..03319562d5faa0e83bda7bf8cc1a4172c46d9b46 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-4/errors.snap @@ -0,0 +1,34 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/repeat-until-4 +--- +- AstError: + token: + start_position: + bytes: 15 + line: 3 + character: 1 + end_position: + bytes: 20 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: until + additional: "expected a condition after `until`" +- AstError: + token: + start_position: + bytes: 21 + line: 3 + character: 7 + end_position: + bytes: 24 + line: 3 + character: 10 + token_type: + type: Symbol + symbol: end + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-4/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-4/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..56da3c666b500639484c86504cf7c8d3df93000d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-4/source.lua @@ -0,0 +1,3 @@ +repeat + call() +until end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-4/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-4/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..4195eacb22b12b4c66c8ee996ab994c94ebaa6bf --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/repeat-until-4/tokens.snap @@ -0,0 +1,127 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/repeat-until-4 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: repeat +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 7 + line: 2 + character: 1 + end_position: + bytes: 8 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 8 + line: 2 + character: 2 + end_position: + bytes: 12 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 12 + line: 2 + character: 6 + end_position: + bytes: 13 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 13 + line: 2 + character: 7 + end_position: + bytes: 14 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 14 + line: 2 + character: 8 + end_position: + bytes: 15 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 15 + line: 3 + character: 1 + end_position: + bytes: 20 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: until +- start_position: + bytes: 20 + line: 3 + character: 6 + end_position: + bytes: 21 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 21 + line: 3 + character: 7 + end_position: + bytes: 24 + line: 3 + character: 10 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 24 + line: 3 + character: 10 + end_position: + bytes: 24 + line: 3 + character: 10 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..58b9d344c90c15a8d78570e505e6c23c278346a6 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-1/ast.snap @@ -0,0 +1,88 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/table-1 +--- +nodes: + stmts: [] + last_stmt: + - Return: + token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + returns: + pairs: + - End: + TableConstructor: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: [] + fields: + pairs: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-1/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-1/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..73f5712f05caef0778bf9e61cc8b89d497ff87ee --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-1/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/table-1 +--- +"return {}" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-1/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-1/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..7ad52e5fddf0cb40d5fd94828e0fea41c498b4ef --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-1/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/table-1 +--- +error[ast]: expected a field + ┌─ source.lua:1:8 + │ +1 │ return { + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-1/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-1/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..77ace4f119a7a346dafbc77ea780f2cd76c1d017 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-1/errors.snap @@ -0,0 +1,20 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/table-1 +--- +- AstError: + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "{" + additional: expected a field + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..23e3e4f4a44d0b8e23e11dcee2f72965ec8f80a7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-1/source.lua @@ -0,0 +1 @@ +return { \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..e1e72060143c6796ffc9460b3be6b7b764f8d793 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-1/tokens.snap @@ -0,0 +1,50 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/table-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..3a606172ae648f5a2c26074ca3d1e5d77d3bcf1a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-2/ast.snap @@ -0,0 +1,194 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/table-2 +--- +nodes: + stmts: [] + last_stmt: + - Return: + token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + returns: + pairs: + - End: + TableConstructor: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: "\n" + - leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: [] + fields: + pairs: + - Punctuated: + - NameKey: + key: + leading_trivia: + - start_position: + bytes: 9 + line: 2 + character: 1 + end_position: + bytes: 10 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 10 + line: 2 + character: 2 + end_position: + bytes: 11 + line: 2 + character: 3 + token_type: + type: Identifier + identifier: a + trailing_trivia: + - start_position: + bytes: 11 + line: 2 + character: 3 + end_position: + bytes: 12 + line: 2 + character: 4 + token_type: + type: Whitespace + characters: " " + equal: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 2 + character: 4 + end_position: + bytes: 13 + line: 2 + character: 5 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 13 + line: 2 + character: 5 + end_position: + bytes: 14 + line: 2 + character: 6 + token_type: + type: Whitespace + characters: " " + value: + Number: + leading_trivia: [] + token: + start_position: + bytes: 14 + line: 2 + character: 6 + end_position: + bytes: 15 + line: 2 + character: 7 + token_type: + type: Number + text: "1" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 15 + line: 2 + character: 7 + end_position: + bytes: 16 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: "," + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 16 + line: 2 + character: 8 + end_position: + bytes: 16 + line: 2 + character: 8 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-2/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-2/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..16718b2051f3bce4ef3d471291ba55c0691a4f8f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-2/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/table-2 +--- +"return {\n\ta = 1,}" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-2/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-2/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..0951cb021ebd32ebd3808e9d59c14975e1abb5fe --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-2/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/table-2 +--- +error[ast]: expected a field + ┌─ source.lua:2:6 + │ +2 │ a = 1, + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-2/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-2/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..2f301a96175fc5e8a411ac5d140c4a309cb7c3bf --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-2/errors.snap @@ -0,0 +1,20 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/table-2 +--- +- AstError: + token: + start_position: + bytes: 14 + line: 2 + character: 6 + end_position: + bytes: 15 + line: 2 + character: 7 + token_type: + type: Number + text: "1" + additional: expected a field + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..99c33b1255e42dfc14bf426566df0959f1e3c26f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-2/source.lua @@ -0,0 +1,2 @@ +return { + a = 1, \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..f27fdbae858d6fafae90c6e31569282728688d21 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-2/tokens.snap @@ -0,0 +1,138 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/table-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 9 + line: 2 + character: 1 + end_position: + bytes: 10 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 10 + line: 2 + character: 2 + end_position: + bytes: 11 + line: 2 + character: 3 + token_type: + type: Identifier + identifier: a +- start_position: + bytes: 11 + line: 2 + character: 3 + end_position: + bytes: 12 + line: 2 + character: 4 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 12 + line: 2 + character: 4 + end_position: + bytes: 13 + line: 2 + character: 5 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 13 + line: 2 + character: 5 + end_position: + bytes: 14 + line: 2 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 14 + line: 2 + character: 6 + end_position: + bytes: 15 + line: 2 + character: 7 + token_type: + type: Number + text: "1" +- start_position: + bytes: 15 + line: 2 + character: 7 + end_position: + bytes: 16 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 16 + line: 2 + character: 8 + end_position: + bytes: 16 + line: 2 + character: 8 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-3/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-3/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..89fa71520f8abf8291df817462991c8b22fb69ec --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-3/ast.snap @@ -0,0 +1,99 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/table-3 +--- +nodes: + stmts: [] + last_stmt: + - Return: + token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + returns: + pairs: + - End: + TableConstructor: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: "\n" + - leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: [] + fields: + pairs: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 13 + line: 2 + character: 5 + end_position: + bytes: 13 + line: 2 + character: 5 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-3/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-3/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..0748551eecad33113d7055ff322419b02f97b005 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-3/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/table-3 +--- +"return {\n}" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-3/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-3/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..7608225a6545832e5ff697e256a1eb645a72ef77 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-3/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/table-3 +--- +error[ast]: expected an expression after `=` + ┌─ source.lua:2:4 + │ +2 │ a = + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-3/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-3/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..8374a65d1e316809f8123c905679d94e028bf1c3 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-3/errors.snap @@ -0,0 +1,20 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/table-3 +--- +- AstError: + token: + start_position: + bytes: 12 + line: 2 + character: 4 + end_position: + bytes: 13 + line: 2 + character: 5 + token_type: + type: Symbol + symbol: "=" + additional: "expected an expression after `=`" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-3/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-3/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..f34b20b0f12d551429bc8329adb28ed803a05695 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-3/source.lua @@ -0,0 +1,2 @@ +return { + a = \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-3/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-3/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..53557b98526d9cef380f3b65d87aa068e692a841 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-3/tokens.snap @@ -0,0 +1,105 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/table-3 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 9 + line: 2 + character: 1 + end_position: + bytes: 10 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 10 + line: 2 + character: 2 + end_position: + bytes: 11 + line: 2 + character: 3 + token_type: + type: Identifier + identifier: a +- start_position: + bytes: 11 + line: 2 + character: 3 + end_position: + bytes: 12 + line: 2 + character: 4 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 12 + line: 2 + character: 4 + end_position: + bytes: 13 + line: 2 + character: 5 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 13 + line: 2 + character: 5 + end_position: + bytes: 13 + line: 2 + character: 5 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-4/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-4/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..d96f796a6b36283ce1a5e536f77fc355eac1589e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-4/ast.snap @@ -0,0 +1,99 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/table-4 +--- +nodes: + stmts: [] + last_stmt: + - Return: + token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + returns: + pairs: + - End: + TableConstructor: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " + - leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: [] + fields: + pairs: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-4/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-4/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..d66c4a495bc2049a7012dedc4ca71f358f35bd52 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-4/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/table-4 +--- +"return { }" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-4/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-4/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..7b15952565bdffacf06bd7c1d7b424ba87d018eb --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-4/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/table-4 +--- +error[ast]: expected a field + ┌─ source.lua:1:8 + │ +1 │ return { until } + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:10 + │ +1 │ return { until } + │ ^^^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-4/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-4/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..f33beb1a658d9bfd907517ae19d5f0b2f853a695 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-4/errors.snap @@ -0,0 +1,34 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/table-4 +--- +- AstError: + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "{" + additional: expected a field +- AstError: + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: until + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-4/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-4/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..163261ba2ec127ede84677dd4a750f8e4f94cbdd --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-4/source.lua @@ -0,0 +1 @@ +return { until } \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-4/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-4/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..b6df8acc73d9ae769953cd6eff07744a6fb4640c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-4/tokens.snap @@ -0,0 +1,94 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/table-4 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: until +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-5/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-5/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..9cf4e57029cde470090dcdd52454501aecd44817 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-5/ast.snap @@ -0,0 +1,99 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/table-5 +--- +nodes: + stmts: [] + last_stmt: + - Return: + token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + returns: + pairs: + - End: + TableConstructor: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: "\n" + - leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: [] + fields: + pairs: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 22 + line: 3 + character: 2 + end_position: + bytes: 22 + line: 3 + character: 2 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-5/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-5/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..3be3249a283d196494c6999f4ef6ee3af6bb320e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-5/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/table-5 +--- +"return {\n}" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-5/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-5/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..121aee3cbd74aba8bb3f6ce913b387e7e7dc1da7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-5/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/table-5 +--- +error[ast]: expected a field + ┌─ source.lua:1:8 + │ +1 │ return { + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:2:2 + │ +2 │ until = 1, + │ ^^^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-5/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-5/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..5d2d3d61b8c558c477dcdf7c088805b842d9ee85 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-5/errors.snap @@ -0,0 +1,34 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/table-5 +--- +- AstError: + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "{" + additional: expected a field +- AstError: + token: + start_position: + bytes: 10 + line: 2 + character: 2 + end_position: + bytes: 15 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: until + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-5/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-5/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..d7ba7765a03064e897d5f1d4b9571923479c7cb5 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-5/source.lua @@ -0,0 +1,3 @@ +return { + until = 1, +} \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-5/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-5/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..58c636e30d72b098d4b63ee175e3585cf6f67e4f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-5/tokens.snap @@ -0,0 +1,160 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/table-5 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 9 + line: 2 + character: 1 + end_position: + bytes: 10 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 10 + line: 2 + character: 2 + end_position: + bytes: 15 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: until +- start_position: + bytes: 15 + line: 2 + character: 7 + end_position: + bytes: 16 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 16 + line: 2 + character: 8 + end_position: + bytes: 17 + line: 2 + character: 9 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 17 + line: 2 + character: 9 + end_position: + bytes: 18 + line: 2 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 18 + line: 2 + character: 10 + end_position: + bytes: 19 + line: 2 + character: 11 + token_type: + type: Number + text: "1" +- start_position: + bytes: 19 + line: 2 + character: 11 + end_position: + bytes: 20 + line: 2 + character: 12 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 20 + line: 2 + character: 12 + end_position: + bytes: 21 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 21 + line: 3 + character: 1 + end_position: + bytes: 22 + line: 3 + character: 2 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 22 + line: 3 + character: 2 + end_position: + bytes: 22 + line: 3 + character: 2 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-6/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-6/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..4505fdafda2d18a7b52ef0b82952ede07f431cbf --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-6/ast.snap @@ -0,0 +1,99 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/table-6 +--- +nodes: + stmts: [] + last_stmt: + - Return: + token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + returns: + pairs: + - End: + TableConstructor: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: "\n" + - leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: [] + fields: + pairs: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 22 + line: 3 + character: 2 + end_position: + bytes: 22 + line: 3 + character: 2 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-6/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-6/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..40491c210d9bb9e96a2cd24b8a440bcb0264e007 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-6/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/table-6 +--- +"return {\n}" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-6/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-6/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..286e8f6f5c41396b36e67f058b76ed22ef46fc7f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-6/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/table-6 +--- +error[ast]: expected an expression after `=` + ┌─ source.lua:2:4 + │ +2 │ x = until, + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:2:6 + │ +2 │ x = until, + │ ^^^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-6/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-6/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..e553ca921bd77e99dc40695efec867e809ffa4ad --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-6/errors.snap @@ -0,0 +1,34 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/table-6 +--- +- AstError: + token: + start_position: + bytes: 12 + line: 2 + character: 4 + end_position: + bytes: 13 + line: 2 + character: 5 + token_type: + type: Symbol + symbol: "=" + additional: "expected an expression after `=`" +- AstError: + token: + start_position: + bytes: 14 + line: 2 + character: 6 + end_position: + bytes: 19 + line: 2 + character: 11 + token_type: + type: Symbol + symbol: until + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-6/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-6/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..38575b34630233f6a286b83df777f8c8dd600f85 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-6/source.lua @@ -0,0 +1,3 @@ +return { + x = until, +} \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-6/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-6/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..e4e88c08aadf1d22db11e15591b6723fefb3362c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-6/tokens.snap @@ -0,0 +1,160 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/table-6 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 9 + line: 2 + character: 1 + end_position: + bytes: 10 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 10 + line: 2 + character: 2 + end_position: + bytes: 11 + line: 2 + character: 3 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 11 + line: 2 + character: 3 + end_position: + bytes: 12 + line: 2 + character: 4 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 12 + line: 2 + character: 4 + end_position: + bytes: 13 + line: 2 + character: 5 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 13 + line: 2 + character: 5 + end_position: + bytes: 14 + line: 2 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 14 + line: 2 + character: 6 + end_position: + bytes: 19 + line: 2 + character: 11 + token_type: + type: Symbol + symbol: until +- start_position: + bytes: 19 + line: 2 + character: 11 + end_position: + bytes: 20 + line: 2 + character: 12 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 20 + line: 2 + character: 12 + end_position: + bytes: 21 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 21 + line: 3 + character: 1 + end_position: + bytes: 22 + line: 3 + character: 2 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 22 + line: 3 + character: 2 + end_position: + bytes: 22 + line: 3 + character: 2 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-7/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-7/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..b243fc3cdbf077fd191e9d91b346e39d0689b7da --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-7/ast.snap @@ -0,0 +1,99 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/table-7 +--- +nodes: + stmts: [] + last_stmt: + - Return: + token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + returns: + pairs: + - End: + TableConstructor: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: "\n" + - leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: [] + fields: + pairs: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 27 + line: 3 + character: 2 + end_position: + bytes: 27 + line: 3 + character: 2 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-7/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-7/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..b1cb6febc11aaeb5c90d791f8e6673df78fbe6d4 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-7/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/table-7 +--- +"return {\n}" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-7/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-7/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..cc620248de909f1c0ae8dce440e94bc6a6244969 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-7/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/table-7 +--- +error[ast]: expected an expression after `[` + ┌─ source.lua:2:2 + │ +2 │ [until] = true, + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:2:3 + │ +2 │ [until] = true, + │ ^^^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-7/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-7/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..b83763dc2319048cc047bd8d787043db6e550196 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-7/errors.snap @@ -0,0 +1,34 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/table-7 +--- +- AstError: + token: + start_position: + bytes: 10 + line: 2 + character: 2 + end_position: + bytes: 11 + line: 2 + character: 3 + token_type: + type: Symbol + symbol: "[" + additional: "expected an expression after `[`" +- AstError: + token: + start_position: + bytes: 11 + line: 2 + character: 3 + end_position: + bytes: 16 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: until + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-7/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-7/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..aca8efbfb43a780520b13d32bffd72724c828c61 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-7/source.lua @@ -0,0 +1,3 @@ +return { + [until] = true, +} \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-7/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-7/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..2bf7f49d5c3e65fa73fea177300a337402406be1 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-7/tokens.snap @@ -0,0 +1,182 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/table-7 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 9 + line: 2 + character: 1 + end_position: + bytes: 10 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 10 + line: 2 + character: 2 + end_position: + bytes: 11 + line: 2 + character: 3 + token_type: + type: Symbol + symbol: "[" +- start_position: + bytes: 11 + line: 2 + character: 3 + end_position: + bytes: 16 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: until +- start_position: + bytes: 16 + line: 2 + character: 8 + end_position: + bytes: 17 + line: 2 + character: 9 + token_type: + type: Symbol + symbol: "]" +- start_position: + bytes: 17 + line: 2 + character: 9 + end_position: + bytes: 18 + line: 2 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 18 + line: 2 + character: 10 + end_position: + bytes: 19 + line: 2 + character: 11 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 19 + line: 2 + character: 11 + end_position: + bytes: 20 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 20 + line: 2 + character: 12 + end_position: + bytes: 24 + line: 2 + character: 16 + token_type: + type: Symbol + symbol: "true" +- start_position: + bytes: 24 + line: 2 + character: 16 + end_position: + bytes: 25 + line: 2 + character: 17 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 25 + line: 2 + character: 17 + end_position: + bytes: 26 + line: 2 + character: 17 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 26 + line: 3 + character: 1 + end_position: + bytes: 27 + line: 3 + character: 2 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 27 + line: 3 + character: 2 + end_position: + bytes: 27 + line: 3 + character: 2 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-8/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-8/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..0f781755cc5556f04cb6048e05cc9e8c7852c7be --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-8/ast.snap @@ -0,0 +1,99 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/table-8 +--- +nodes: + stmts: [] + last_stmt: + - Return: + token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + returns: + pairs: + - End: + TableConstructor: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: "\n" + - leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: [] + fields: + pairs: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 19 + line: 3 + character: 2 + end_position: + bytes: 19 + line: 3 + character: 2 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-8/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-8/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..286760f98405fa9d83e8c6751f53b551744588cb --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-8/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/table-8 +--- +"return {\n}" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-8/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-8/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..bc85e288320e2652f8bbfc122a70c430c21e52e1 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-8/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/table-8 +--- +error[ast]: expected an expression after `[` + ┌─ source.lua:2:2 + │ +2 │ [] = 1, + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:2:3 + │ +2 │ [] = 1, + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-8/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-8/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..c7358df81a649c51a03ffe7440aa48d58d5a0095 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-8/errors.snap @@ -0,0 +1,34 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/table-8 +--- +- AstError: + token: + start_position: + bytes: 10 + line: 2 + character: 2 + end_position: + bytes: 11 + line: 2 + character: 3 + token_type: + type: Symbol + symbol: "[" + additional: "expected an expression after `[`" +- AstError: + token: + start_position: + bytes: 11 + line: 2 + character: 3 + end_position: + bytes: 12 + line: 2 + character: 4 + token_type: + type: Symbol + symbol: "]" + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-8/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-8/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..0f02f728ee11d7e80272ef188b3e23a5f350f8ce --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-8/source.lua @@ -0,0 +1,3 @@ +return { + [] = 1, +} \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-8/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-8/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..52a393608d7cd88e76a0a1adb63c8a86f9c5a6ed --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-8/tokens.snap @@ -0,0 +1,171 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/table-8 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 9 + line: 2 + character: 1 + end_position: + bytes: 10 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 10 + line: 2 + character: 2 + end_position: + bytes: 11 + line: 2 + character: 3 + token_type: + type: Symbol + symbol: "[" +- start_position: + bytes: 11 + line: 2 + character: 3 + end_position: + bytes: 12 + line: 2 + character: 4 + token_type: + type: Symbol + symbol: "]" +- start_position: + bytes: 12 + line: 2 + character: 4 + end_position: + bytes: 13 + line: 2 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 13 + line: 2 + character: 5 + end_position: + bytes: 14 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 14 + line: 2 + character: 6 + end_position: + bytes: 15 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 15 + line: 2 + character: 7 + end_position: + bytes: 16 + line: 2 + character: 8 + token_type: + type: Number + text: "1" +- start_position: + bytes: 16 + line: 2 + character: 8 + end_position: + bytes: 17 + line: 2 + character: 9 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 17 + line: 2 + character: 9 + end_position: + bytes: 18 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 18 + line: 3 + character: 1 + end_position: + bytes: 19 + line: 3 + character: 2 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 19 + line: 3 + character: 2 + end_position: + bytes: 19 + line: 3 + character: 2 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-9/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-9/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..9aa867fc8463bf8768e3dcd3e1622f5bcdb25ba8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-9/ast.snap @@ -0,0 +1,152 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 23 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/table-9 +--- +nodes: + stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + TableConstructor: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: "\n" + - leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: [] + fields: + pairs: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 28 + line: 4 + character: 1 + end_position: + bytes: 28 + line: 4 + character: 1 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-9/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-9/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..f4d3d21b6b2b2889e5cc66c4c07fb2a90cc51d68 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-9/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 28 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/table-9 +--- +"local x = {\n}" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-9/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-9/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..72573f05b44ec8aed63804162a81e8ee7a36ba5d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-9/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/table-9 +--- +error[ast]: expected `]` after expression + ┌─ source.lua:2:2 + │ +2 │ [a.b.c = 10, + │ ^^^^^^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:2:9 + │ +2 │ [a.b.c = 10, + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-9/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-9/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..ccf239f322fdd863c8fd3b7068225c10268ef9e6 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-9/errors.snap @@ -0,0 +1,41 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/table-9 +--- +- AstError: + token: + start_position: + bytes: 20 + line: 2 + character: 9 + end_position: + bytes: 21 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: "=" + additional: "expected `]` after expression" + range: + - bytes: 13 + line: 2 + character: 2 + - bytes: 19 + line: 2 + character: 8 +- AstError: + token: + start_position: + bytes: 20 + line: 2 + character: 9 + end_position: + bytes: 21 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: "=" + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-9/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-9/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..6542bbab62394aced99ed3abb2c57037e6336c60 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-9/source.lua @@ -0,0 +1,3 @@ +local x = { + [a.b.c = 10, +} diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-9/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-9/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..7306243126c607f398898388a96e7dcc47ba9352 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/table-9/tokens.snap @@ -0,0 +1,270 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 68 +expression: tokens +input_file: full-moon/tests/cases/fail/parser/table-9 +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 12 + line: 2 + character: 1 + end_position: + bytes: 13 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 13 + line: 2 + character: 2 + end_position: + bytes: 14 + line: 2 + character: 3 + token_type: + type: Symbol + symbol: "[" +- start_position: + bytes: 14 + line: 2 + character: 3 + end_position: + bytes: 15 + line: 2 + character: 4 + token_type: + type: Identifier + identifier: a +- start_position: + bytes: 15 + line: 2 + character: 4 + end_position: + bytes: 16 + line: 2 + character: 5 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 16 + line: 2 + character: 5 + end_position: + bytes: 17 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: b +- start_position: + bytes: 17 + line: 2 + character: 6 + end_position: + bytes: 18 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 18 + line: 2 + character: 7 + end_position: + bytes: 19 + line: 2 + character: 8 + token_type: + type: Identifier + identifier: c +- start_position: + bytes: 19 + line: 2 + character: 8 + end_position: + bytes: 20 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 20 + line: 2 + character: 9 + end_position: + bytes: 21 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 21 + line: 2 + character: 10 + end_position: + bytes: 22 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 22 + line: 2 + character: 11 + end_position: + bytes: 24 + line: 2 + character: 13 + token_type: + type: Number + text: "10" +- start_position: + bytes: 24 + line: 2 + character: 13 + end_position: + bytes: 25 + line: 2 + character: 14 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 25 + line: 2 + character: 14 + end_position: + bytes: 26 + line: 2 + character: 14 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 26 + line: 3 + character: 1 + end_position: + bytes: 27 + line: 3 + character: 2 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 27 + line: 3 + character: 2 + end_position: + bytes: 28 + line: 3 + character: 2 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 28 + line: 4 + character: 1 + end_position: + bytes: 28 + line: 4 + character: 1 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..5d28823ba8aa156295ceb22ab1a2287d8b4b1d4c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-1/ast.snap @@ -0,0 +1,54 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/un-op-1 +--- +nodes: + stmts: [] + last_stmt: + - Return: + token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + returns: + pairs: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-1/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-1/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..b01c7ca56ab392f3d49b9c8a475fd2122b6e2f9c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-1/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/un-op-1 +--- +"return " + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-1/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-1/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..f2790f9856fac0fc44b73fc3a46ab25c9946afe0 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-1/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/un-op-1 +--- +error[ast]: expected an expression after not + ┌─ source.lua:1:8 + │ +1 │ return not + │ ^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-1/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-1/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..859b418dd43169cacca7e30d7cfa65b42398096a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-1/errors.snap @@ -0,0 +1,20 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/un-op-1 +--- +- AstError: + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: not + additional: expected an expression after not + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..92bfc95a4957b0839528f49827ac804f9cff9253 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-1/source.lua @@ -0,0 +1 @@ +return not \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..83a4ac560708daec8e0b374d2884e67f22e1b235 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-1/tokens.snap @@ -0,0 +1,50 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/un-op-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: not +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..d2570e5fdf184056ce243204b7377f76b9915d13 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-2/ast.snap @@ -0,0 +1,54 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/un-op-2 +--- +nodes: + stmts: [] + last_stmt: + - Return: + token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + returns: + pairs: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-2/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-2/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..eecaca40929b001fbefd11e3b17d7c3eb49eab8b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-2/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/un-op-2 +--- +"return " + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-2/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-2/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..dd20efda5a19a13c3eec5e076f058a7da1a1e723 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-2/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/un-op-2 +--- +error[ast]: expected an expression after not + ┌─ source.lua:1:8 + │ +1 │ return not end + │ ^^^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:12 + │ +1 │ return not end + │ ^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-2/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-2/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..c08fea06f96c03e5701f35cf779f6b81fc4e4617 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-2/errors.snap @@ -0,0 +1,34 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/un-op-2 +--- +- AstError: + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: not + additional: expected an expression after not +- AstError: + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: end + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..064ff24c1f91859e0ea8d3ebbbb0885fc6251802 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-2/source.lua @@ -0,0 +1 @@ +return not end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..db794b31dce283e2ed468a01f18a62d7e85ee217 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/un-op-2/tokens.snap @@ -0,0 +1,72 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/un-op-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: not +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..6a48f01de7ef713ec89e1a0458041c4c201eaf34 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-1/ast.snap @@ -0,0 +1,23 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/while-1 +--- +nodes: + stmts: [] +eof: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-1/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-1/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..18ec32b5045e7a111a0315b8e43a793c9352f44b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-1/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/while-1 +--- +"" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-1/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-1/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..48e07b49681a0521c6979838b9456d8fefe6965b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-1/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/while-1 +--- +error[ast]: expected a condition after `while` + ┌─ source.lua:1:1 + │ +1 │ while + │ ^^^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-1/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-1/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..d8515702d5bc40efc9b37f800dca0ee73b3e30a6 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-1/errors.snap @@ -0,0 +1,20 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/while-1 +--- +- AstError: + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: while + additional: "expected a condition after `while`" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..2da15dcd359064e1dfd7d2e70b7a24a56908d0b5 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-1/source.lua @@ -0,0 +1 @@ +while \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..31d74a441f1d538d85658e0bbe9c8ab78a3aa5e7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-1/tokens.snap @@ -0,0 +1,28 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/while-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: while +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..adaf1c40548e16c64c72a624c1366f24d53aa971 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-2/ast.snap @@ -0,0 +1,68 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/while-2 +--- +nodes: + stmts: + - - Do: + do_token: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " + block: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-2/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-2/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..2c8c9bda1a31060f62be77756cae0f30c167e968 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-2/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/while-2 +--- +do end + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-2/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-2/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..e9620dbd5cc1eb3a8d81ba6d7a4d1accd482243e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-2/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/while-2 +--- +error[ast]: expected a condition after `while` + ┌─ source.lua:1:1 + │ +1 │ while until do end + │ ^^^^^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:7 + │ +1 │ while until do end + │ ^^^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-2/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-2/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..b7c0b69f9a054bc137ea07ae0d4a2237a09c6e6f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-2/errors.snap @@ -0,0 +1,34 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/while-2 +--- +- AstError: + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: while + additional: "expected a condition after `while`" +- AstError: + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: until + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..14f3bb405379754967d8c617543fd8d1634cb8f7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-2/source.lua @@ -0,0 +1 @@ +while until do end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..fb92dc20713bf7f950751ef420b696b291004751 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-2/tokens.snap @@ -0,0 +1,94 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/while-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: while +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: until +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-3/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-3/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..b7c92c2e4fa48386b4df62a70053fb7a2e5e09e0 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-3/ast.snap @@ -0,0 +1,186 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/while-3 +--- +nodes: + stmts: + - - While: + while_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: while + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + condition: + Symbol: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "true" + trailing_trivia: + - start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " + do_token: + leading_trivia: [] + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 14 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 14 + line: 2 + character: 1 + end_position: + bytes: 15 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 15 + line: 2 + character: 2 + end_position: + bytes: 19 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 19 + line: 2 + character: 6 + end_position: + bytes: 20 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 20 + line: 2 + character: 7 + end_position: + bytes: 21 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: [] + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 21 + line: 2 + character: 8 + end_position: + bytes: 21 + line: 2 + character: 8 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-3/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-3/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..3eadd26171060d96433f0f1ae5de3a241ccc827e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-3/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/while-3 +--- +"while true do\n\tcall()end" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-3/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-3/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..ded292d9df001d4f50f2509347e226e32503bcf6 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-3/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/while-3 +--- +error[ast]: expected `end` to close while loop block + ┌─ source.lua:2:2 + │ +2 │ call() + │ ^^^^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-3/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-3/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..772a07f7596dbca6f1b3ceba5678af911fbcdc55 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-3/errors.snap @@ -0,0 +1,26 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/while-3 +--- +- AstError: + token: + start_position: + bytes: 21 + line: 2 + character: 8 + end_position: + bytes: 21 + line: 2 + character: 8 + token_type: + type: Eof + additional: "expected `end` to close while loop block" + range: + - bytes: 15 + line: 2 + character: 2 + - bytes: 21 + line: 2 + character: 8 + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-3/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-3/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..7c04dad3743f7c4d828e36488f66661944e5e9b3 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-3/source.lua @@ -0,0 +1,2 @@ +while true do + call() \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-3/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-3/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..c8818f4ac8e824b5cde786530eec6a49b0c6a460 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-3/tokens.snap @@ -0,0 +1,127 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/while-3 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: while +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "true" +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 14 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 14 + line: 2 + character: 1 + end_position: + bytes: 15 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 15 + line: 2 + character: 2 + end_position: + bytes: 19 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 19 + line: 2 + character: 6 + end_position: + bytes: 20 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 20 + line: 2 + character: 7 + end_position: + bytes: 21 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 21 + line: 2 + character: 8 + end_position: + bytes: 21 + line: 2 + character: 8 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-4/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-4/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..1333b843adbdd5304433fec05822e7679757d34b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-4/ast.snap @@ -0,0 +1,219 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 27 +expression: result.ast +input_file: full-moon/tests/cases/fail/parser/while-4 +--- +nodes: + stmts: + - - While: + while_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: while + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + condition: + Symbol: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "true" + trailing_trivia: + - start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: "\n" + do_token: + leading_trivia: + - start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Whitespace + characters: " " + token: + start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 4 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 4 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 11 + line: 2 + character: 1 + end_position: + bytes: 12 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 12 + line: 2 + character: 2 + end_position: + bytes: 16 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 16 + line: 2 + character: 6 + end_position: + bytes: 17 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 17 + line: 2 + character: 7 + end_position: + bytes: 18 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 18 + line: 2 + character: 8 + end_position: + bytes: 19 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 22 + line: 3 + character: 4 + end_position: + bytes: 22 + line: 3 + character: 4 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-4/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-4/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..0879fc7bbbd405f81a173e1c5b5f54c5432ef364 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-4/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 30 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/parser/while-4 +--- +"while true\n do\nend\n\tcall()\n" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-4/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-4/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..db15cbd6320fb103e31cafd44f1737956f024ca0 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-4/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/parser/while-4 +--- +error[ast]: expected `do` after condition + ┌─ source.lua:2:2 + │ +2 │ call() + │ ^^^^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:3:1 + │ +3 │ end + │ ^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-4/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-4/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..65f224700d7604b03316199d1e900cefa0dea3c8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-4/errors.snap @@ -0,0 +1,34 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/parser/while-4 +--- +- AstError: + token: + start_position: + bytes: 12 + line: 2 + character: 2 + end_position: + bytes: 16 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call + additional: "expected `do` after condition" +- AstError: + token: + start_position: + bytes: 19 + line: 3 + character: 1 + end_position: + bytes: 22 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-4/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-4/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..0d39995bffe3031f836c494515fb6f6df5c03ae4 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-4/source.lua @@ -0,0 +1,3 @@ +while true + call() +end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-4/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-4/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..26f8e428452a6a66f8f8d8fc8076b46dd35b10c0 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/parser/while-4/tokens.snap @@ -0,0 +1,127 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/cases/fail/parser/while-4 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: while +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "true" +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 11 + line: 2 + character: 1 + end_position: + bytes: 12 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 12 + line: 2 + character: 2 + end_position: + bytes: 16 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 16 + line: 2 + character: 6 + end_position: + bytes: 17 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 17 + line: 2 + character: 7 + end_position: + bytes: 18 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 18 + line: 2 + character: 8 + end_position: + bytes: 19 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 19 + line: 3 + character: 1 + end_position: + bytes: 22 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 22 + line: 3 + character: 4 + end_position: + bytes: 22 + line: 3 + character: 4 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/bad-numbers-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/bad-numbers-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..b453902a7b5c6f347c270750f3faf79a92b20670 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/bad-numbers-1/ast.snap @@ -0,0 +1,98 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 19 +expression: result.ast +input_file: full-moon/tests/cases/fail/tokenizer/bad-numbers-1 +--- +nodes: + stmts: + - - Assignment: + var_list: + pairs: + - End: + Name: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Identifier + identifier: _ + trailing_trivia: + - start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Number + text: 1edoge + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/bad-numbers-1/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/bad-numbers-1/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..62feedb15b23df2ea5eacaf2898b656b5b21b46c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/bad-numbers-1/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 22 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/tokenizer/bad-numbers-1 +--- +_ = 1edoge + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/bad-numbers-1/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/bad-numbers-1/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..b61cd5824476b8209daf3023309aad85cd773ef5 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/bad-numbers-1/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/tokenizer/bad-numbers-1 +--- +error[tokenizer]: invalid number (1:5 to 1:11) + ┌─ source.lua:1:5 + │ +1 │ _ = 1edoge + │ ^^^^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/bad-numbers-1/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/bad-numbers-1/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..0f3c48c8b71fd5afa424086e3966cfd7a12b01d0 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/bad-numbers-1/errors.snap @@ -0,0 +1,16 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 15 +expression: result.errors +input_file: full-moon/tests/cases/fail/tokenizer/bad-numbers-1 +--- +- TokenizerError: + error: InvalidNumber + range: + - bytes: 4 + line: 1 + character: 5 + - bytes: 10 + line: 1 + character: 11 + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/bad-numbers-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/bad-numbers-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..56135fcbea6a4dcb0f3e2e24864514e6a3dd802c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/bad-numbers-1/source.lua @@ -0,0 +1 @@ +_ = 1edoge \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/bad-numbers-1/tokens_result.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/bad-numbers-1/tokens_result.snap new file mode 100644 index 0000000000000000000000000000000000000000..b0e88e720db509628eed1fbe36e5d0b6d17e1dc0 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/bad-numbers-1/tokens_result.snap @@ -0,0 +1,81 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 42 +expression: tokens +input_file: full-moon/tests/cases/fail/tokenizer/bad-numbers-1 +--- +Recovered: + - - start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Identifier + identifier: _ + - start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Whitespace + characters: " " + - start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: "=" + - start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " + - start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Number + text: 1edoge + - start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Eof + - - error: InvalidNumber + range: + - bytes: 4 + line: 1 + character: 5 + - bytes: 10 + line: 1 + character: 11 + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-comment-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-comment-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..2acc2d98b279758bb87d0adaf33df908dce56085 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-comment-1/ast.snap @@ -0,0 +1,35 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 19 +expression: result.ast +input_file: full-moon/tests/cases/fail/tokenizer/unclosed-comment-1 +--- +nodes: + stmts: [] +eof: + leading_trivia: + - start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: MultiLineComment + blocks: 0 + comment: "" + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-comment-1/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-comment-1/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..2f2e2bc7578cc38a6fc573aa80a77e5d50e9f13b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-comment-1/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 22 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/tokenizer/unclosed-comment-1 +--- +"--[[]]" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-comment-1/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-comment-1/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..55c576c7bfd25719079787618225b7f22c42112c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-comment-1/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/tokenizer/unclosed-comment-1 +--- +error[tokenizer]: unclosed comment (1:1 to 1:5) + ┌─ source.lua:1:1 + │ +1 │ --[[ + │ ^^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-comment-1/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-comment-1/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..d9190a80820fcb6d76afa1e55867bfad10535d3b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-comment-1/errors.snap @@ -0,0 +1,16 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 15 +expression: result.errors +input_file: full-moon/tests/cases/fail/tokenizer/unclosed-comment-1 +--- +- TokenizerError: + error: UnclosedComment + range: + - bytes: 0 + line: 1 + character: 1 + - bytes: 4 + line: 1 + character: 5 + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-comment-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-comment-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..3238c3ae1e7a11b0866225dabc011b8b59f21121 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-comment-1/source.lua @@ -0,0 +1 @@ +--[[ \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-comment-1/tokens_result.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-comment-1/tokens_result.snap new file mode 100644 index 0000000000000000000000000000000000000000..7fa651a6441093bf1dbd245d080bbf708d569e65 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-comment-1/tokens_result.snap @@ -0,0 +1,38 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 42 +expression: tokens +input_file: full-moon/tests/cases/fail/tokenizer/unclosed-comment-1 +--- +Recovered: + - - start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: MultiLineComment + blocks: 0 + comment: "" + - start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Eof + - - error: UnclosedComment + range: + - bytes: 0 + line: 1 + character: 1 + - bytes: 4 + line: 1 + character: 5 + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..000f99807e5fb8071a15053660c70df8e7c2aa3e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-1/ast.snap @@ -0,0 +1,124 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 19 +expression: result.ast +input_file: full-moon/tests/cases/fail/tokenizer/unclosed-string-1 +--- +nodes: + stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: StringLiteral + literal: hello + quote_type: Double + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-1/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-1/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..3c4c30da964cd81cac9e99a73758a34da4813953 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-1/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 22 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/tokenizer/unclosed-string-1 +--- +"local x = \"hello\"" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-1/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-1/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..a9aee9e141b20154792487d550bf023a27af62d8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-1/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/tokenizer/unclosed-string-1 +--- +error[tokenizer]: unclosed string (1:11 to 1:17) + ┌─ source.lua:1:11 + │ +1 │ local x = "hello + │ ^^^^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-1/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-1/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..3b7b839d637f9acdb268d5dd03ecae96e2a15421 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-1/errors.snap @@ -0,0 +1,16 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 15 +expression: result.errors +input_file: full-moon/tests/cases/fail/tokenizer/unclosed-string-1 +--- +- TokenizerError: + error: UnclosedString + range: + - bytes: 10 + line: 1 + character: 11 + - bytes: 16 + line: 1 + character: 17 + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..9dca219fc7f74c602fbd3a7814464cc99930f686 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-1/source.lua @@ -0,0 +1 @@ +local x = "hello \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-1/tokens_result.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-1/tokens_result.snap new file mode 100644 index 0000000000000000000000000000000000000000..ca212c3902db082f60288e4070197976ebd56855 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-1/tokens_result.snap @@ -0,0 +1,104 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 42 +expression: tokens +input_file: full-moon/tests/cases/fail/tokenizer/unclosed-string-1 +--- +Recovered: + - - start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + - start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: StringLiteral + literal: hello + quote_type: Double + - start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Eof + - - error: UnclosedString + range: + - bytes: 10 + line: 1 + character: 11 + - bytes: 16 + line: 1 + character: 17 + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..364ec714bd880fd769d15a3d7823475d98ffd62e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-2/ast.snap @@ -0,0 +1,124 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 19 +expression: result.ast +input_file: full-moon/tests/cases/fail/tokenizer/unclosed-string-2 +--- +nodes: + stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: StringLiteral + literal: hello + quote_type: Single + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-2/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-2/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..42c8f44fe88eb61878b0a8a3b60343143062b548 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-2/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 22 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/tokenizer/unclosed-string-2 +--- +"local x = 'hello'" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-2/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-2/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..b082d0e2540d3e13f12d8aced41b2b7f2fb6d023 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-2/error_display.snap @@ -0,0 +1,13 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/tokenizer/unclosed-string-2 +--- +error[tokenizer]: unclosed string (1:11 to 1:17) + ┌─ source.lua:1:11 + │ +1 │ local x = 'hello + │ ^^^^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-2/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-2/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..3a8b885fd0f1079061f7079154ff02a14b31e0bf --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-2/errors.snap @@ -0,0 +1,16 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 15 +expression: result.errors +input_file: full-moon/tests/cases/fail/tokenizer/unclosed-string-2 +--- +- TokenizerError: + error: UnclosedString + range: + - bytes: 10 + line: 1 + character: 11 + - bytes: 16 + line: 1 + character: 17 + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..c6f7c89c615c9e2f6bce60ee7b22d154d069e6b3 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-2/source.lua @@ -0,0 +1 @@ +local x = 'hello \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-2/tokens_result.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-2/tokens_result.snap new file mode 100644 index 0000000000000000000000000000000000000000..32fb822d29728e50288efe2dcc0d2091977f223e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-2/tokens_result.snap @@ -0,0 +1,104 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 42 +expression: tokens +input_file: full-moon/tests/cases/fail/tokenizer/unclosed-string-2 +--- +Recovered: + - - start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + - start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: StringLiteral + literal: hello + quote_type: Single + - start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Eof + - - error: UnclosedString + range: + - bytes: 10 + line: 1 + character: 11 + - bytes: 16 + line: 1 + character: 17 + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-3/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-3/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..3a413e5961f8c9a9af1e0e9939f33b6d4c0351dd --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-3/ast.snap @@ -0,0 +1,122 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.ast +--- +nodes: + stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 23 + line: 2 + character: 6 + token_type: + type: StringLiteral + literal: "hello\nworld" + quote_type: Brackets + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 23 + line: 2 + character: 6 + end_position: + bytes: 23 + line: 2 + character: 6 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-3/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-3/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..d0bd99b2a9caa5730480547908ec44ef6204e0d5 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-3/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 22 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/tokenizer/unclosed-string-3 +--- +"local x = [[hello\nworld]]" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-3/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-3/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..6621bcaf61d7b91235cd9bfc270ebd00429f87aa --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-3/error_display.snap @@ -0,0 +1,15 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/tokenizer/unclosed-string-3 +--- +error[tokenizer]: unclosed string (1:11 to 2:6) + ┌─ source.lua:1:11 + │ +1 │ local x = [[hello + │ â•───────────^ +2 │ │ world + │ ╰─────^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-3/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-3/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..8abe8a49ccf0fbf3fe806d4b053a4080a6e79b45 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-3/errors.snap @@ -0,0 +1,16 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 15 +expression: result.errors +input_file: full-moon/tests/cases/fail/tokenizer/unclosed-string-3 +--- +- TokenizerError: + error: UnclosedString + range: + - bytes: 10 + line: 1 + character: 11 + - bytes: 23 + line: 2 + character: 6 + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-3/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-3/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..87cc2e0c63f89b830b4509b4691d930bbecd99d4 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-3/source.lua @@ -0,0 +1,2 @@ +local x = [[hello +world \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-3/tokens_result.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-3/tokens_result.snap new file mode 100644 index 0000000000000000000000000000000000000000..515ed292a8e2cbc7e96ef0e1b7258a43bc7cdd51 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-3/tokens_result.snap @@ -0,0 +1,102 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +--- +Recovered: + - - start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + - start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 23 + line: 2 + character: 6 + token_type: + type: StringLiteral + literal: "hello\nworld" + quote_type: Brackets + - start_position: + bytes: 23 + line: 2 + character: 6 + end_position: + bytes: 23 + line: 2 + character: 6 + token_type: + type: Eof + - - error: UnclosedString + range: + - bytes: 10 + line: 1 + character: 11 + - bytes: 23 + line: 2 + character: 6 + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-4/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-4/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..ee77f72cd2290d7373eab748b6ca52fa507e1cb2 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-4/ast.snap @@ -0,0 +1,134 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 16 +expression: result.ast +input_file: full-moon/tests/cases/fail/tokenizer/unclosed-string-4 +--- +nodes: + stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 2 + character: 1 + end_position: + bytes: 14 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 14 + line: 2 + character: 6 + end_position: + bytes: 15 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 15 + line: 2 + character: 7 + end_position: + bytes: 16 + line: 2 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 16 + line: 2 + character: 8 + end_position: + bytes: 17 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 17 + line: 2 + character: 9 + end_position: + bytes: 18 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 18 + line: 2 + character: 10 + end_position: + bytes: 19 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 19 + line: 2 + character: 11 + end_position: + bytes: 20 + line: 2 + character: 12 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 20 + line: 2 + character: 12 + end_position: + bytes: 21 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: "\n" + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 21 + line: 3 + character: 1 + end_position: + bytes: 21 + line: 3 + character: 1 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-4/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-4/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..ea8fc21312d22e6265db5038e0e7093a41d35ec0 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-4/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 19 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/tokenizer/unclosed-string-4 +--- +"local x = 1\n" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-4/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-4/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..8f4a56d88981f5e76af309ff0b922ec3f1ba668e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-4/error_display.snap @@ -0,0 +1,21 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/tokenizer/unclosed-string-4 +--- +error[tokenizer]: unclosed string (1:1 to 2:1) + ┌─ source.lua:1:1 + │ +1 │ â• "recover +2 │ │ local x = 1 + │ â•°^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:1 + │ +1 │ â• "recover +2 │ │ local x = 1 + │ â•°^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-4/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-4/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..3e25c8d00b80a577cab7d578633bf194b236cb0d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-4/errors.snap @@ -0,0 +1,30 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/tokenizer/unclosed-string-4 +--- +- TokenizerError: + error: UnclosedString + range: + - bytes: 0 + line: 1 + character: 1 + - bytes: 9 + line: 2 + character: 1 +- AstError: + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 9 + line: 2 + character: 1 + token_type: + type: StringLiteral + literal: recover + quote_type: Double + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-4/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-4/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..743fa914328a16a24abbfa962638e80ed5caddf1 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-4/source.lua @@ -0,0 +1,2 @@ +"recover +local x = 1 diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-4/tokens_result.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-4/tokens_result.snap new file mode 100644 index 0000000000000000000000000000000000000000..be8a9872d72915e1daa2ec57d9a4e5bc8c73481a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unclosed-string-4/tokens_result.snap @@ -0,0 +1,126 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 42 +expression: tokens +input_file: full-moon/tests/cases/fail/tokenizer/unclosed-string-4 +--- +Recovered: + - - start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 9 + line: 2 + character: 1 + token_type: + type: StringLiteral + literal: recover + quote_type: Double + - start_position: + bytes: 9 + line: 2 + character: 1 + end_position: + bytes: 14 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local + - start_position: + bytes: 14 + line: 2 + character: 6 + end_position: + bytes: 15 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " + - start_position: + bytes: 15 + line: 2 + character: 7 + end_position: + bytes: 16 + line: 2 + character: 8 + token_type: + type: Identifier + identifier: x + - start_position: + bytes: 16 + line: 2 + character: 8 + end_position: + bytes: 17 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " + - start_position: + bytes: 17 + line: 2 + character: 9 + end_position: + bytes: 18 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: "=" + - start_position: + bytes: 18 + line: 2 + character: 10 + end_position: + bytes: 19 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: " " + - start_position: + bytes: 19 + line: 2 + character: 11 + end_position: + bytes: 20 + line: 2 + character: 12 + token_type: + type: Number + text: "1" + - start_position: + bytes: 20 + line: 2 + character: 12 + end_position: + bytes: 21 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: "\n" + - start_position: + bytes: 21 + line: 3 + character: 1 + end_position: + bytes: 21 + line: 3 + character: 1 + token_type: + type: Eof + - - error: UnclosedString + range: + - bytes: 0 + line: 1 + character: 1 + - bytes: 9 + line: 2 + character: 1 + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unexpected-character/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unexpected-character/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..1c975d698b604d958c5aff606423e5ced9f6492f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unexpected-character/ast.snap @@ -0,0 +1,107 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 19 +expression: result.ast +input_file: full-moon/tests/cases/fail/tokenizer/unexpected-character +--- +nodes: + stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 14 + line: 1 + character: 12 + end_position: + bytes: 14 + line: 1 + character: 12 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unexpected-character/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unexpected-character/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..8278fb831f916bdb512fdc1d4956239edbab2be4 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unexpected-character/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 22 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/tokenizer/unexpected-character +--- +"local x = " + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unexpected-character/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unexpected-character/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..651118bb0a8ef47649a5d076cef45956b7ebf617 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unexpected-character/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/tokenizer/unexpected-character +--- +error[ast]: expected an expression + ┌─ source.lua:1:9 + │ +1 │ local x = 🤔 + │ ^ + +error[tokenizer]: unexpected character 🤔 (1:11 to 1:12) + ┌─ source.lua:1:11 + │ +1 │ local x = 🤔 + │ ^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unexpected-character/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unexpected-character/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..3c99633f67482b95e7e1e7efd75c118c6fac9697 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unexpected-character/errors.snap @@ -0,0 +1,30 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/tokenizer/unexpected-character +--- +- AstError: + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + additional: expected an expression +- TokenizerError: + error: + UnexpectedToken: 🤔 + range: + - bytes: 10 + line: 1 + character: 11 + - bytes: 14 + line: 1 + character: 12 + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unexpected-character/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unexpected-character/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..e02637d243c99245a66d50f0fd5cf64abba3e289 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unexpected-character/source.lua @@ -0,0 +1 @@ +local x = 🤔 \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unexpected-character/tokens_result.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unexpected-character/tokens_result.snap new file mode 100644 index 0000000000000000000000000000000000000000..b7d68acf01fa6ac8639bc1c784b96e0ed1e1cbe1 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/unexpected-character/tokens_result.snap @@ -0,0 +1,93 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 42 +expression: tokens +input_file: full-moon/tests/cases/fail/tokenizer/unexpected-character +--- +Recovered: + - - start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + - start_position: + bytes: 14 + line: 1 + character: 12 + end_position: + bytes: 14 + line: 1 + character: 12 + token_type: + type: Eof + - - error: + UnexpectedToken: 🤔 + range: + - bytes: 10 + line: 1 + character: 11 + - bytes: 14 + line: 1 + character: 12 + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/wrong-place-shebang/ast.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/wrong-place-shebang/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..8e9236e85630d738e2033c9ddf7aad74390c47a1 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/wrong-place-shebang/ast.snap @@ -0,0 +1,129 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 19 +expression: result.ast +input_file: full-moon/tests/cases/fail/tokenizer/wrong-place-shebang +--- +nodes: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 23 + line: 3 + character: 1 + end_position: + bytes: 24 + line: 3 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 24 + line: 4 + character: 1 + end_position: + bytes: 29 + line: 4 + character: 6 + token_type: + type: Identifier + identifier: print + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 29 + line: 4 + character: 6 + end_position: + bytes: 30 + line: 4 + character: 7 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 37 + line: 4 + character: 14 + end_position: + bytes: 38 + line: 4 + character: 15 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 30 + line: 4 + character: 7 + end_position: + bytes: 37 + line: 4 + character: 14 + token_type: + type: StringLiteral + literal: hello + quote_type: Double + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 38 + line: 4 + character: 15 + end_position: + bytes: 39 + line: 4 + character: 16 + token_type: + type: Symbol + symbol: ; + trailing_trivia: + - start_position: + bytes: 39 + line: 4 + character: 16 + end_position: + bytes: 40 + line: 4 + character: 16 + token_type: + type: Whitespace + characters: "\n" +eof: + leading_trivia: [] + token: + start_position: + bytes: 40 + line: 5 + character: 1 + end_position: + bytes: 40 + line: 5 + character: 1 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/wrong-place-shebang/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/wrong-place-shebang/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..618ae30a9057df482362fd293a87cb9851a7da6e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/wrong-place-shebang/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 22 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/cases/fail/tokenizer/wrong-place-shebang +--- +"\nprint(\"hello\");\n" + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/wrong-place-shebang/error_display.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/wrong-place-shebang/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..bf153f55db073c8dfc6381d9f676468eac9e94a8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/wrong-place-shebang/error_display.snap @@ -0,0 +1,61 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/cases/fail/tokenizer/wrong-place-shebang +--- +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:2:1 + │ +2 │ #!/usr/bin/env luajit + │ ^ + +error[tokenizer]: unexpected character ! (2:2 to 2:3) + ┌─ source.lua:2:2 + │ +2 │ #!/usr/bin/env luajit + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:2:3 + │ +2 │ #!/usr/bin/env luajit + │ ^ + +error[ast]: unexpected expression when looking for a statement + ┌─ source.lua:2:7 + │ +2 │ #!/usr/bin/env luajit + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:2:7 + │ +2 │ #!/usr/bin/env luajit + │ ^ + +error[ast]: unexpected expression when looking for a statement + ┌─ source.lua:2:11 + │ +2 │ #!/usr/bin/env luajit + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:2:11 + │ +2 │ #!/usr/bin/env luajit + │ ^ + +error[ast]: unexpected expression when looking for a statement + ┌─ source.lua:2:16 + │ +2 │ #!/usr/bin/env luajit + │ ^^^^^^ + +error[ast]: unexpected expression when looking for a statement + ┌─ source.lua:4:1 + │ +4 │ print("hello"); + │ ^^^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/wrong-place-shebang/errors.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/wrong-place-shebang/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..e4ebedfe1b9cd924a86aab088a7bfea88338c128 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/wrong-place-shebang/errors.snap @@ -0,0 +1,128 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/cases/fail/tokenizer/wrong-place-shebang +--- +- AstError: + token: + start_position: + bytes: 1 + line: 2 + character: 1 + end_position: + bytes: 2 + line: 2 + character: 2 + token_type: + type: Symbol + symbol: "#" + additional: "unexpected token, this needs to be a statement" +- TokenizerError: + error: + UnexpectedToken: "!" + range: + - bytes: 2 + line: 2 + character: 2 + - bytes: 3 + line: 2 + character: 3 +- AstError: + token: + start_position: + bytes: 3 + line: 2 + character: 3 + end_position: + bytes: 4 + line: 2 + character: 4 + token_type: + type: Symbol + symbol: / + additional: "unexpected token, this needs to be a statement" +- AstError: + token: + start_position: + bytes: 7 + line: 2 + character: 7 + end_position: + bytes: 8 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: / + additional: unexpected expression when looking for a statement +- AstError: + token: + start_position: + bytes: 7 + line: 2 + character: 7 + end_position: + bytes: 8 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: / + additional: "unexpected token, this needs to be a statement" +- AstError: + token: + start_position: + bytes: 11 + line: 2 + character: 11 + end_position: + bytes: 12 + line: 2 + character: 12 + token_type: + type: Symbol + symbol: / + additional: unexpected expression when looking for a statement +- AstError: + token: + start_position: + bytes: 11 + line: 2 + character: 11 + end_position: + bytes: 12 + line: 2 + character: 12 + token_type: + type: Symbol + symbol: / + additional: "unexpected token, this needs to be a statement" +- AstError: + token: + start_position: + bytes: 16 + line: 2 + character: 16 + end_position: + bytes: 22 + line: 2 + character: 22 + token_type: + type: Identifier + identifier: luajit + additional: unexpected expression when looking for a statement +- AstError: + token: + start_position: + bytes: 24 + line: 4 + character: 1 + end_position: + bytes: 29 + line: 4 + character: 6 + token_type: + type: Identifier + identifier: print + additional: unexpected expression when looking for a statement + diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/wrong-place-shebang/source.lua b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/wrong-place-shebang/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..5bd6f605818907ca6924e03c233eecfb45b39984 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/wrong-place-shebang/source.lua @@ -0,0 +1,4 @@ + +#!/usr/bin/env luajit + +print("hello"); diff --git a/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/wrong-place-shebang/tokens_result.snap b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/wrong-place-shebang/tokens_result.snap new file mode 100644 index 0000000000000000000000000000000000000000..57db51e304fbe4030649030ae8160b2d62d66f83 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/fail/tokenizer/wrong-place-shebang/tokens_result.snap @@ -0,0 +1,226 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 42 +expression: tokens +input_file: full-moon/tests/cases/fail/tokenizer/wrong-place-shebang +--- +Recovered: + - - start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 1 + token_type: + type: Whitespace + characters: "\n" + - start_position: + bytes: 1 + line: 2 + character: 1 + end_position: + bytes: 2 + line: 2 + character: 2 + token_type: + type: Symbol + symbol: "#" + - start_position: + bytes: 3 + line: 2 + character: 3 + end_position: + bytes: 4 + line: 2 + character: 4 + token_type: + type: Symbol + symbol: / + - start_position: + bytes: 4 + line: 2 + character: 4 + end_position: + bytes: 7 + line: 2 + character: 7 + token_type: + type: Identifier + identifier: usr + - start_position: + bytes: 7 + line: 2 + character: 7 + end_position: + bytes: 8 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: / + - start_position: + bytes: 8 + line: 2 + character: 8 + end_position: + bytes: 11 + line: 2 + character: 11 + token_type: + type: Identifier + identifier: bin + - start_position: + bytes: 11 + line: 2 + character: 11 + end_position: + bytes: 12 + line: 2 + character: 12 + token_type: + type: Symbol + symbol: / + - start_position: + bytes: 12 + line: 2 + character: 12 + end_position: + bytes: 15 + line: 2 + character: 15 + token_type: + type: Identifier + identifier: env + - start_position: + bytes: 15 + line: 2 + character: 15 + end_position: + bytes: 16 + line: 2 + character: 16 + token_type: + type: Whitespace + characters: " " + - start_position: + bytes: 16 + line: 2 + character: 16 + end_position: + bytes: 22 + line: 2 + character: 22 + token_type: + type: Identifier + identifier: luajit + - start_position: + bytes: 22 + line: 2 + character: 22 + end_position: + bytes: 23 + line: 2 + character: 22 + token_type: + type: Whitespace + characters: "\n" + - start_position: + bytes: 23 + line: 3 + character: 1 + end_position: + bytes: 24 + line: 3 + character: 1 + token_type: + type: Whitespace + characters: "\n" + - start_position: + bytes: 24 + line: 4 + character: 1 + end_position: + bytes: 29 + line: 4 + character: 6 + token_type: + type: Identifier + identifier: print + - start_position: + bytes: 29 + line: 4 + character: 6 + end_position: + bytes: 30 + line: 4 + character: 7 + token_type: + type: Symbol + symbol: ( + - start_position: + bytes: 30 + line: 4 + character: 7 + end_position: + bytes: 37 + line: 4 + character: 14 + token_type: + type: StringLiteral + literal: hello + quote_type: Double + - start_position: + bytes: 37 + line: 4 + character: 14 + end_position: + bytes: 38 + line: 4 + character: 15 + token_type: + type: Symbol + symbol: ) + - start_position: + bytes: 38 + line: 4 + character: 15 + end_position: + bytes: 39 + line: 4 + character: 16 + token_type: + type: Symbol + symbol: ; + - start_position: + bytes: 39 + line: 4 + character: 16 + end_position: + bytes: 40 + line: 4 + character: 16 + token_type: + type: Whitespace + characters: "\n" + - start_position: + bytes: 40 + line: 5 + character: 1 + end_position: + bytes: 40 + line: 5 + character: 1 + token_type: + type: Eof + - - error: + UnexpectedToken: "!" + range: + - bytes: 2 + line: 2 + character: 2 + - bytes: 3 + line: 2 + character: 3 + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..09ba8f1983ebc60a5447f1c8dc57d40dee1c490c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-1/ast.snap @@ -0,0 +1,271 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/anonymous-functions-1 +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Function: + - leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: function + trailing_trivia: [] + - parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 21 + line: 1 + character: 21 + token_type: + type: Whitespace + characters: "\n" + parameters: + pairs: [] + block: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 21 + line: 2 + character: 1 + end_position: + bytes: 22 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 22 + line: 2 + character: 2 + end_position: + bytes: 26 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 26 + line: 2 + character: 6 + end_position: + bytes: 27 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 28 + line: 2 + character: 8 + end_position: + bytes: 29 + line: 2 + character: 9 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 29 + line: 2 + character: 9 + end_position: + bytes: 30 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 27 + line: 2 + character: 7 + end_position: + bytes: 28 + line: 2 + character: 8 + token_type: + type: Number + text: "1" + trailing_trivia: [] + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 30 + line: 3 + character: 1 + end_position: + bytes: 33 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 33 + line: 3 + character: 4 + end_position: + bytes: 34 + line: 3 + character: 4 + token_type: + type: Whitespace + characters: "\n" + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..ddc145a2d9ff9392cbbedef014d05ac9f9398da3 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-1/source.lua @@ -0,0 +1,3 @@ +local x = function() + call(1) +end diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..00d3ace0f6af6112cc2beec5cf0b3ff7bc0e7447 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-1/tokens.snap @@ -0,0 +1,215 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/anonymous-functions-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 21 + line: 1 + character: 21 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 21 + line: 2 + character: 1 + end_position: + bytes: 22 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 22 + line: 2 + character: 2 + end_position: + bytes: 26 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 26 + line: 2 + character: 6 + end_position: + bytes: 27 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 27 + line: 2 + character: 7 + end_position: + bytes: 28 + line: 2 + character: 8 + token_type: + type: Number + text: "1" +- start_position: + bytes: 28 + line: 2 + character: 8 + end_position: + bytes: 29 + line: 2 + character: 9 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 29 + line: 2 + character: 9 + end_position: + bytes: 30 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 30 + line: 3 + character: 1 + end_position: + bytes: 33 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 33 + line: 3 + character: 4 + end_position: + bytes: 34 + line: 3 + character: 4 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 34 + line: 4 + character: 1 + end_position: + bytes: 34 + line: 4 + character: 1 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..7d5f15821c1fae771e693062e7327a2150867243 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-2/ast.snap @@ -0,0 +1,232 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 48 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/anonymous-functions-2 +--- +stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 31 + line: 3 + character: 4 + end_position: + bytes: 32 + line: 3 + character: 5 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: + - End: + Function: + - leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: function + trailing_trivia: [] + - generics: ~ + parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: "\n" + parameters: + pairs: [] + type_specifiers: [] + block: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 16 + line: 2 + character: 1 + end_position: + bytes: 17 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 17 + line: 2 + character: 2 + end_position: + bytes: 20 + line: 2 + character: 5 + token_type: + type: Identifier + identifier: foo + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 20 + line: 2 + character: 5 + end_position: + bytes: 21 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 26 + line: 2 + character: 11 + end_position: + bytes: 27 + line: 2 + character: 12 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 27 + line: 2 + character: 12 + end_position: + bytes: 28 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 21 + line: 2 + character: 6 + end_position: + bytes: 26 + line: 2 + character: 11 + token_type: + type: StringLiteral + literal: bar + quote_type: Double + trailing_trivia: [] + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 28 + line: 3 + character: 1 + end_position: + bytes: 31 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..20df3976a5e4cad8117fa73a14f11d4ba346de2b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-2/source.lua @@ -0,0 +1,3 @@ +call(function() + foo("bar") +end) \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..731b65834956013391421f22856f2d9d9f315829 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-2/tokens.snap @@ -0,0 +1,172 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/anonymous-functions-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 16 + line: 2 + character: 1 + end_position: + bytes: 17 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 17 + line: 2 + character: 2 + end_position: + bytes: 20 + line: 2 + character: 5 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 20 + line: 2 + character: 5 + end_position: + bytes: 21 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 21 + line: 2 + character: 6 + end_position: + bytes: 26 + line: 2 + character: 11 + token_type: + type: StringLiteral + literal: bar + quote_type: Double +- start_position: + bytes: 26 + line: 2 + character: 11 + end_position: + bytes: 27 + line: 2 + character: 12 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 27 + line: 2 + character: 12 + end_position: + bytes: 28 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 28 + line: 3 + character: 1 + end_position: + bytes: 31 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 31 + line: 3 + character: 4 + end_position: + bytes: 32 + line: 3 + character: 5 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 32 + line: 3 + character: 5 + end_position: + bytes: 32 + line: 3 + character: 5 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-3/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-3/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..0db3a00b242a71a0e0eb49f9c8bff29a707468ce --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-3/ast.snap @@ -0,0 +1,184 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/anonymous-functions-3 +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Function: + - leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: function + trailing_trivia: [] + - parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 22 + line: 1 + character: 23 + end_position: + bytes: 23 + line: 1 + character: 24 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 23 + line: 1 + character: 24 + end_position: + bytes: 24 + line: 1 + character: 25 + token_type: + type: Whitespace + characters: " " + parameters: + pairs: + - End: + Ellipse: + leading_trivia: [] + token: + start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Symbol + symbol: "..." + trailing_trivia: [] + block: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 24 + line: 1 + character: 25 + end_position: + bytes: 27 + line: 1 + character: 28 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-3/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-3/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..567ee735fe4c15263f5d3bdfc82ed6fa38bc61b4 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-3/source.lua @@ -0,0 +1 @@ +local x = function(...) end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-3/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-3/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..8b9972f2777e326096588e9794c2f38e62254cb9 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-3/tokens.snap @@ -0,0 +1,149 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/anonymous-functions-3 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Symbol + symbol: "..." +- start_position: + bytes: 22 + line: 1 + character: 23 + end_position: + bytes: 23 + line: 1 + character: 24 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 23 + line: 1 + character: 24 + end_position: + bytes: 24 + line: 1 + character: 25 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 24 + line: 1 + character: 25 + end_position: + bytes: 27 + line: 1 + character: 28 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 27 + line: 1 + character: 28 + end_position: + bytes: 27 + line: 1 + character: 28 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-4/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-4/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..0163437fe5385cdc159b2bae2d78ba6f925d56b2 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-4/ast.snap @@ -0,0 +1,266 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/anonymous-functions-4 +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Function: + - leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: function + trailing_trivia: [] + - parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 28 + line: 1 + character: 29 + end_position: + bytes: 29 + line: 1 + character: 30 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 29 + line: 1 + character: 30 + end_position: + bytes: 30 + line: 1 + character: 31 + token_type: + type: Whitespace + characters: " " + parameters: + pairs: + - Punctuated: + - Name: + leading_trivia: [] + token: + start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Identifier + identifier: a + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Whitespace + characters: " " + - Punctuated: + - Name: + leading_trivia: [] + token: + start_position: + bytes: 22 + line: 1 + character: 23 + end_position: + bytes: 23 + line: 1 + character: 24 + token_type: + type: Identifier + identifier: b + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 23 + line: 1 + character: 24 + end_position: + bytes: 24 + line: 1 + character: 25 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 24 + line: 1 + character: 25 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Whitespace + characters: " " + - End: + Ellipse: + leading_trivia: [] + token: + start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 28 + line: 1 + character: 29 + token_type: + type: Symbol + symbol: "..." + trailing_trivia: [] + block: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 30 + line: 1 + character: 31 + end_position: + bytes: 33 + line: 1 + character: 34 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-4/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-4/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..566d1999ed3d2f0444b3f810cf6a908c45f738f4 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-4/source.lua @@ -0,0 +1 @@ +local x = function(a, b, ...) end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-4/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-4/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..b23833aec85e903c307c3577416b4b89d5b96d6d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/anonymous-functions-4/tokens.snap @@ -0,0 +1,215 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/anonymous-functions-4 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Identifier + identifier: a +- start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 22 + line: 1 + character: 23 + end_position: + bytes: 23 + line: 1 + character: 24 + token_type: + type: Identifier + identifier: b +- start_position: + bytes: 23 + line: 1 + character: 24 + end_position: + bytes: 24 + line: 1 + character: 25 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 24 + line: 1 + character: 25 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 28 + line: 1 + character: 29 + token_type: + type: Symbol + symbol: "..." +- start_position: + bytes: 28 + line: 1 + character: 29 + end_position: + bytes: 29 + line: 1 + character: 30 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 29 + line: 1 + character: 30 + end_position: + bytes: 30 + line: 1 + character: 31 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 30 + line: 1 + character: 31 + end_position: + bytes: 33 + line: 1 + character: 34 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 33 + line: 1 + character: 34 + end_position: + bytes: 33 + line: 1 + character: 34 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/assignment-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..e2c733e50567420c980384be16f5c72c6028cde7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-1/ast.snap @@ -0,0 +1,83 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/assignment-1 +--- +stmts: + - - Assignment: + var_list: + pairs: + - End: + Name: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Number + text: "1" + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/assignment-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..3d2b4b14efe535966493ee555dd7faa81063a251 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-1/source.lua @@ -0,0 +1 @@ +x = 1 \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/assignment-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..24cb47eb8474ebe7b97e8e90189e3e51395a4acc --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-1/tokens.snap @@ -0,0 +1,72 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/assignment-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Number + text: "1" +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/assignment-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..3ee1a2ffeee20d113c5ff84025d066f98c76f025 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-2/ast.snap @@ -0,0 +1,165 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/assignment-2 +--- +stmts: + - - Assignment: + var_list: + pairs: + - Punctuated: + - Name: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Identifier + identifier: a + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Whitespace + characters: " " + - End: + Name: + leading_trivia: [] + token: + start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: b + trailing_trivia: + - start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - Punctuated: + - Number: + leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Number + text: "1" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + - End: + Symbol: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: "true" + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/assignment-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..8b162b6742b1034d6716dd5c0c4702c054ef421b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-2/source.lua @@ -0,0 +1 @@ +a, b = 1, true \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/assignment-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..83fb8d0e94d236ed8135c916e960ca6b9e7eb12d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-2/tokens.snap @@ -0,0 +1,138 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/assignment-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Identifier + identifier: a +- start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: b +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Number + text: "1" +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: "true" +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/assignment-3/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-3/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..cb4e5f48bc045d177cf5c98be471a2be8aa2cdd7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-3/ast.snap @@ -0,0 +1,829 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/assignment-3 +--- +stmts: + - - Assignment: + var_list: + pairs: + - Punctuated: + - Name: + leading_trivia: + - start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 48 + line: 1 + character: 49 + token_type: + type: SingleLineComment + comment: " Crazy assignment code from AmaranthineCodices" + - start_position: + bytes: 48 + line: 1 + character: 49 + end_position: + bytes: 49 + line: 1 + character: 49 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 49 + line: 2 + character: 1 + end_position: + bytes: 50 + line: 2 + character: 2 + token_type: + type: Identifier + identifier: a + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 50 + line: 2 + character: 2 + end_position: + bytes: 51 + line: 2 + character: 3 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 51 + line: 2 + character: 3 + end_position: + bytes: 52 + line: 2 + character: 4 + token_type: + type: Whitespace + characters: " " + - Punctuated: + - Name: + leading_trivia: [] + token: + start_position: + bytes: 52 + line: 2 + character: 4 + end_position: + bytes: 53 + line: 2 + character: 5 + token_type: + type: Identifier + identifier: b + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 53 + line: 2 + character: 5 + end_position: + bytes: 54 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 54 + line: 2 + character: 6 + end_position: + bytes: 55 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " + - Punctuated: + - Expression: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 55 + line: 2 + character: 7 + end_position: + bytes: 56 + line: 2 + character: 8 + token_type: + type: Identifier + identifier: c + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 56 + line: 2 + character: 8 + end_position: + bytes: 57 + line: 2 + character: 9 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 57 + line: 2 + character: 9 + end_position: + bytes: 58 + line: 2 + character: 10 + token_type: + type: Identifier + identifier: d + trailing_trivia: [] + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 58 + line: 2 + character: 10 + end_position: + bytes: 59 + line: 2 + character: 11 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 59 + line: 2 + character: 11 + end_position: + bytes: 60 + line: 2 + character: 12 + token_type: + type: Identifier + identifier: e + trailing_trivia: [] + - Index: + Brackets: + brackets: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 60 + line: 2 + character: 12 + end_position: + bytes: 61 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: "[" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 62 + line: 2 + character: 14 + end_position: + bytes: 63 + line: 2 + character: 15 + token_type: + type: Symbol + symbol: "]" + trailing_trivia: [] + expression: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 61 + line: 2 + character: 13 + end_position: + bytes: 62 + line: 2 + character: 14 + token_type: + type: Identifier + identifier: f + trailing_trivia: [] + - Index: + Brackets: + brackets: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 63 + line: 2 + character: 15 + end_position: + bytes: 64 + line: 2 + character: 16 + token_type: + type: Symbol + symbol: "[" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 65 + line: 2 + character: 17 + end_position: + bytes: 66 + line: 2 + character: 18 + token_type: + type: Symbol + symbol: "]" + trailing_trivia: [] + expression: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 64 + line: 2 + character: 16 + end_position: + bytes: 65 + line: 2 + character: 17 + token_type: + type: Identifier + identifier: g + trailing_trivia: [] + - Index: + Brackets: + brackets: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 66 + line: 2 + character: 18 + end_position: + bytes: 67 + line: 2 + character: 19 + token_type: + type: Symbol + symbol: "[" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 68 + line: 2 + character: 20 + end_position: + bytes: 69 + line: 2 + character: 21 + token_type: + type: Symbol + symbol: "]" + trailing_trivia: [] + expression: + Number: + leading_trivia: [] + token: + start_position: + bytes: 67 + line: 2 + character: 19 + end_position: + bytes: 68 + line: 2 + character: 20 + token_type: + type: Number + text: "1" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 69 + line: 2 + character: 21 + end_position: + bytes: 70 + line: 2 + character: 22 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 70 + line: 2 + character: 22 + end_position: + bytes: 71 + line: 2 + character: 23 + token_type: + type: Whitespace + characters: " " + - End: + Expression: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 71 + line: 2 + character: 23 + end_position: + bytes: 72 + line: 2 + character: 24 + token_type: + type: Identifier + identifier: h + trailing_trivia: [] + suffixes: + - Call: + MethodCall: + colon_token: + leading_trivia: [] + token: + start_position: + bytes: 72 + line: 2 + character: 24 + end_position: + bytes: 73 + line: 2 + character: 25 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 73 + line: 2 + character: 25 + end_position: + bytes: 74 + line: 2 + character: 26 + token_type: + type: Identifier + identifier: i + trailing_trivia: [] + args: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 74 + line: 2 + character: 26 + end_position: + bytes: 75 + line: 2 + character: 27 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 75 + line: 2 + character: 27 + end_position: + bytes: 76 + line: 2 + character: 28 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: [] + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 76 + line: 2 + character: 28 + end_position: + bytes: 77 + line: 2 + character: 29 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 77 + line: 2 + character: 29 + end_position: + bytes: 78 + line: 2 + character: 30 + token_type: + type: Identifier + identifier: j + trailing_trivia: [] + - Index: + Brackets: + brackets: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 78 + line: 2 + character: 30 + end_position: + bytes: 79 + line: 2 + character: 31 + token_type: + type: Symbol + symbol: "[" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 80 + line: 2 + character: 32 + end_position: + bytes: 81 + line: 2 + character: 33 + token_type: + type: Symbol + symbol: "]" + trailing_trivia: [] + expression: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 79 + line: 2 + character: 31 + end_position: + bytes: 80 + line: 2 + character: 32 + token_type: + type: Identifier + identifier: k + trailing_trivia: [] + - Call: + MethodCall: + colon_token: + leading_trivia: [] + token: + start_position: + bytes: 81 + line: 2 + character: 33 + end_position: + bytes: 82 + line: 2 + character: 34 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 82 + line: 2 + character: 34 + end_position: + bytes: 83 + line: 2 + character: 35 + token_type: + type: Identifier + identifier: l + trailing_trivia: [] + args: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 83 + line: 2 + character: 35 + end_position: + bytes: 84 + line: 2 + character: 36 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 84 + line: 2 + character: 36 + end_position: + bytes: 85 + line: 2 + character: 37 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: [] + - Index: + Brackets: + brackets: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 85 + line: 2 + character: 37 + end_position: + bytes: 86 + line: 2 + character: 38 + token_type: + type: Symbol + symbol: "[" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 87 + line: 2 + character: 39 + end_position: + bytes: 88 + line: 2 + character: 40 + token_type: + type: Symbol + symbol: "]" + trailing_trivia: + - start_position: + bytes: 88 + line: 2 + character: 40 + end_position: + bytes: 89 + line: 2 + character: 41 + token_type: + type: Whitespace + characters: " " + expression: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 86 + line: 2 + character: 38 + end_position: + bytes: 87 + line: 2 + character: 39 + token_type: + type: Identifier + identifier: m + trailing_trivia: [] + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 89 + line: 2 + character: 41 + end_position: + bytes: 90 + line: 2 + character: 42 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 90 + line: 2 + character: 42 + end_position: + bytes: 91 + line: 2 + character: 43 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - Punctuated: + - Symbol: + leading_trivia: [] + token: + start_position: + bytes: 91 + line: 2 + character: 43 + end_position: + bytes: 95 + line: 2 + character: 47 + token_type: + type: Symbol + symbol: "true" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 95 + line: 2 + character: 47 + end_position: + bytes: 96 + line: 2 + character: 48 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 96 + line: 2 + character: 48 + end_position: + bytes: 97 + line: 2 + character: 49 + token_type: + type: Whitespace + characters: " " + - Punctuated: + - Symbol: + leading_trivia: [] + token: + start_position: + bytes: 97 + line: 2 + character: 49 + end_position: + bytes: 102 + line: 2 + character: 54 + token_type: + type: Symbol + symbol: "false" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 102 + line: 2 + character: 54 + end_position: + bytes: 103 + line: 2 + character: 55 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 103 + line: 2 + character: 55 + end_position: + bytes: 104 + line: 2 + character: 56 + token_type: + type: Whitespace + characters: " " + - Punctuated: + - Number: + leading_trivia: [] + token: + start_position: + bytes: 104 + line: 2 + character: 56 + end_position: + bytes: 105 + line: 2 + character: 57 + token_type: + type: Number + text: "1" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 105 + line: 2 + character: 57 + end_position: + bytes: 106 + line: 2 + character: 58 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 106 + line: 2 + character: 58 + end_position: + bytes: 107 + line: 2 + character: 59 + token_type: + type: Whitespace + characters: " " + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 107 + line: 2 + character: 59 + end_position: + bytes: 108 + line: 2 + character: 60 + token_type: + type: Number + text: "4" + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/assignment-3/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-3/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..fab2edb95048bddece94016d2e1ab2846a05395e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-3/source.lua @@ -0,0 +1,2 @@ +-- Crazy assignment code from AmaranthineCodices +a, b, c.d.e[f][g][1], h:i().j[k]:l()[m] = true, false, 1, 4 \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/assignment-3/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-3/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..a3be75e09074b145440e6086617749c5e82269c0 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-3/tokens.snap @@ -0,0 +1,611 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/assignment-3 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 48 + line: 1 + character: 49 + token_type: + type: SingleLineComment + comment: " Crazy assignment code from AmaranthineCodices" +- start_position: + bytes: 48 + line: 1 + character: 49 + end_position: + bytes: 49 + line: 1 + character: 49 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 49 + line: 2 + character: 1 + end_position: + bytes: 50 + line: 2 + character: 2 + token_type: + type: Identifier + identifier: a +- start_position: + bytes: 50 + line: 2 + character: 2 + end_position: + bytes: 51 + line: 2 + character: 3 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 51 + line: 2 + character: 3 + end_position: + bytes: 52 + line: 2 + character: 4 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 52 + line: 2 + character: 4 + end_position: + bytes: 53 + line: 2 + character: 5 + token_type: + type: Identifier + identifier: b +- start_position: + bytes: 53 + line: 2 + character: 5 + end_position: + bytes: 54 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 54 + line: 2 + character: 6 + end_position: + bytes: 55 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 55 + line: 2 + character: 7 + end_position: + bytes: 56 + line: 2 + character: 8 + token_type: + type: Identifier + identifier: c +- start_position: + bytes: 56 + line: 2 + character: 8 + end_position: + bytes: 57 + line: 2 + character: 9 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 57 + line: 2 + character: 9 + end_position: + bytes: 58 + line: 2 + character: 10 + token_type: + type: Identifier + identifier: d +- start_position: + bytes: 58 + line: 2 + character: 10 + end_position: + bytes: 59 + line: 2 + character: 11 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 59 + line: 2 + character: 11 + end_position: + bytes: 60 + line: 2 + character: 12 + token_type: + type: Identifier + identifier: e +- start_position: + bytes: 60 + line: 2 + character: 12 + end_position: + bytes: 61 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: "[" +- start_position: + bytes: 61 + line: 2 + character: 13 + end_position: + bytes: 62 + line: 2 + character: 14 + token_type: + type: Identifier + identifier: f +- start_position: + bytes: 62 + line: 2 + character: 14 + end_position: + bytes: 63 + line: 2 + character: 15 + token_type: + type: Symbol + symbol: "]" +- start_position: + bytes: 63 + line: 2 + character: 15 + end_position: + bytes: 64 + line: 2 + character: 16 + token_type: + type: Symbol + symbol: "[" +- start_position: + bytes: 64 + line: 2 + character: 16 + end_position: + bytes: 65 + line: 2 + character: 17 + token_type: + type: Identifier + identifier: g +- start_position: + bytes: 65 + line: 2 + character: 17 + end_position: + bytes: 66 + line: 2 + character: 18 + token_type: + type: Symbol + symbol: "]" +- start_position: + bytes: 66 + line: 2 + character: 18 + end_position: + bytes: 67 + line: 2 + character: 19 + token_type: + type: Symbol + symbol: "[" +- start_position: + bytes: 67 + line: 2 + character: 19 + end_position: + bytes: 68 + line: 2 + character: 20 + token_type: + type: Number + text: "1" +- start_position: + bytes: 68 + line: 2 + character: 20 + end_position: + bytes: 69 + line: 2 + character: 21 + token_type: + type: Symbol + symbol: "]" +- start_position: + bytes: 69 + line: 2 + character: 21 + end_position: + bytes: 70 + line: 2 + character: 22 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 70 + line: 2 + character: 22 + end_position: + bytes: 71 + line: 2 + character: 23 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 71 + line: 2 + character: 23 + end_position: + bytes: 72 + line: 2 + character: 24 + token_type: + type: Identifier + identifier: h +- start_position: + bytes: 72 + line: 2 + character: 24 + end_position: + bytes: 73 + line: 2 + character: 25 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 73 + line: 2 + character: 25 + end_position: + bytes: 74 + line: 2 + character: 26 + token_type: + type: Identifier + identifier: i +- start_position: + bytes: 74 + line: 2 + character: 26 + end_position: + bytes: 75 + line: 2 + character: 27 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 75 + line: 2 + character: 27 + end_position: + bytes: 76 + line: 2 + character: 28 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 76 + line: 2 + character: 28 + end_position: + bytes: 77 + line: 2 + character: 29 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 77 + line: 2 + character: 29 + end_position: + bytes: 78 + line: 2 + character: 30 + token_type: + type: Identifier + identifier: j +- start_position: + bytes: 78 + line: 2 + character: 30 + end_position: + bytes: 79 + line: 2 + character: 31 + token_type: + type: Symbol + symbol: "[" +- start_position: + bytes: 79 + line: 2 + character: 31 + end_position: + bytes: 80 + line: 2 + character: 32 + token_type: + type: Identifier + identifier: k +- start_position: + bytes: 80 + line: 2 + character: 32 + end_position: + bytes: 81 + line: 2 + character: 33 + token_type: + type: Symbol + symbol: "]" +- start_position: + bytes: 81 + line: 2 + character: 33 + end_position: + bytes: 82 + line: 2 + character: 34 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 82 + line: 2 + character: 34 + end_position: + bytes: 83 + line: 2 + character: 35 + token_type: + type: Identifier + identifier: l +- start_position: + bytes: 83 + line: 2 + character: 35 + end_position: + bytes: 84 + line: 2 + character: 36 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 84 + line: 2 + character: 36 + end_position: + bytes: 85 + line: 2 + character: 37 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 85 + line: 2 + character: 37 + end_position: + bytes: 86 + line: 2 + character: 38 + token_type: + type: Symbol + symbol: "[" +- start_position: + bytes: 86 + line: 2 + character: 38 + end_position: + bytes: 87 + line: 2 + character: 39 + token_type: + type: Identifier + identifier: m +- start_position: + bytes: 87 + line: 2 + character: 39 + end_position: + bytes: 88 + line: 2 + character: 40 + token_type: + type: Symbol + symbol: "]" +- start_position: + bytes: 88 + line: 2 + character: 40 + end_position: + bytes: 89 + line: 2 + character: 41 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 89 + line: 2 + character: 41 + end_position: + bytes: 90 + line: 2 + character: 42 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 90 + line: 2 + character: 42 + end_position: + bytes: 91 + line: 2 + character: 43 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 91 + line: 2 + character: 43 + end_position: + bytes: 95 + line: 2 + character: 47 + token_type: + type: Symbol + symbol: "true" +- start_position: + bytes: 95 + line: 2 + character: 47 + end_position: + bytes: 96 + line: 2 + character: 48 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 96 + line: 2 + character: 48 + end_position: + bytes: 97 + line: 2 + character: 49 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 97 + line: 2 + character: 49 + end_position: + bytes: 102 + line: 2 + character: 54 + token_type: + type: Symbol + symbol: "false" +- start_position: + bytes: 102 + line: 2 + character: 54 + end_position: + bytes: 103 + line: 2 + character: 55 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 103 + line: 2 + character: 55 + end_position: + bytes: 104 + line: 2 + character: 56 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 104 + line: 2 + character: 56 + end_position: + bytes: 105 + line: 2 + character: 57 + token_type: + type: Number + text: "1" +- start_position: + bytes: 105 + line: 2 + character: 57 + end_position: + bytes: 106 + line: 2 + character: 58 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 106 + line: 2 + character: 58 + end_position: + bytes: 107 + line: 2 + character: 59 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 107 + line: 2 + character: 59 + end_position: + bytes: 108 + line: 2 + character: 60 + token_type: + type: Number + text: "4" +- start_position: + bytes: 108 + line: 2 + character: 60 + end_position: + bytes: 108 + line: 2 + character: 60 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/assignment-4/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-4/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..2dae33e58c296f0a0590803bec31226f78742dfc --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-4/ast.snap @@ -0,0 +1,180 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 54 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/assignment-4 +--- +stmts: + - - Assignment: + var_list: + pairs: + - End: + Name: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Identifier + identifier: a + trailing_trivia: + - start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - Assignment: + var_list: + pairs: + - End: + Name: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 2 + character: 1 + end_position: + bytes: 7 + line: 2 + character: 2 + token_type: + type: Identifier + identifier: b + trailing_trivia: + - start_position: + bytes: 7 + line: 2 + character: 2 + end_position: + bytes: 8 + line: 2 + character: 3 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 2 + character: 3 + end_position: + bytes: 9 + line: 2 + character: 4 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 2 + character: 4 + end_position: + bytes: 10 + line: 2 + character: 5 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 2 + character: 5 + end_position: + bytes: 11 + line: 2 + character: 6 + token_type: + type: Number + text: "2" + trailing_trivia: + - start_position: + bytes: 11 + line: 2 + character: 6 + end_position: + bytes: 12 + line: 2 + character: 6 + token_type: + type: Whitespace + characters: "\n" + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/assignment-4/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-4/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..223ca50d99502c4cf15a026d366965225e573961 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-4/source.lua @@ -0,0 +1,2 @@ +a = 1 +b = 2 diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/assignment-4/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-4/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..afabdf98095ce5fd180dd3aeeba89805dcf03212 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-4/tokens.snap @@ -0,0 +1,149 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 40 +expression: tokens +input_file: full-moon/tests/cases/pass/assignment-4 +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Identifier + identifier: a +- start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Number + text: "1" +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 6 + line: 2 + character: 1 + end_position: + bytes: 7 + line: 2 + character: 2 + token_type: + type: Identifier + identifier: b +- start_position: + bytes: 7 + line: 2 + character: 2 + end_position: + bytes: 8 + line: 2 + character: 3 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 2 + character: 3 + end_position: + bytes: 9 + line: 2 + character: 4 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 2 + character: 4 + end_position: + bytes: 10 + line: 2 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 2 + character: 5 + end_position: + bytes: 11 + line: 2 + character: 6 + token_type: + type: Number + text: "2" +- start_position: + bytes: 11 + line: 2 + character: 6 + end_position: + bytes: 12 + line: 2 + character: 6 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 12 + line: 3 + character: 1 + end_position: + bytes: 12 + line: 3 + character: 1 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/assignment-5/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-5/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..a97a907a0af26704d583ebb10b1ac7d7532f1dc1 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-5/ast.snap @@ -0,0 +1,338 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 47 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/assignment-5 +--- +stmts: + - - Assignment: + var_list: + pairs: + - End: + Expression: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Identifier + identifier: gui + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Identifier + identifier: Label + trailing_trivia: [] + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Identifier + identifier: Text + trailing_trivia: + - start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + BinaryOperator: + lhs: + String: + leading_trivia: [] + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 31 + line: 1 + character: 32 + token_type: + type: StringLiteral + literal: LOADING DATA + quote_type: Double + trailing_trivia: + - start_position: + bytes: 31 + line: 1 + character: 32 + end_position: + bytes: 32 + line: 1 + character: 33 + token_type: + type: Whitespace + characters: " " + binop: + TwoDots: + leading_trivia: [] + token: + start_position: + bytes: 32 + line: 1 + character: 33 + end_position: + bytes: 34 + line: 1 + character: 35 + token_type: + type: Symbol + symbol: ".." + trailing_trivia: + - start_position: + bytes: 34 + line: 1 + character: 35 + end_position: + bytes: 35 + line: 1 + character: 36 + token_type: + type: Whitespace + characters: " " + rhs: + FunctionCall: + prefix: + Expression: + Parentheses: + contained: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 35 + line: 1 + character: 36 + end_position: + bytes: 36 + line: 1 + character: 37 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 39 + line: 1 + character: 40 + end_position: + bytes: 40 + line: 1 + character: 41 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + expression: + String: + leading_trivia: [] + token: + start_position: + bytes: 36 + line: 1 + character: 37 + end_position: + bytes: 39 + line: 1 + character: 40 + token_type: + type: StringLiteral + literal: "." + quote_type: Double + trailing_trivia: [] + suffixes: + - Call: + MethodCall: + colon_token: + leading_trivia: [] + token: + start_position: + bytes: 40 + line: 1 + character: 41 + end_position: + bytes: 41 + line: 1 + character: 42 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 41 + line: 1 + character: 42 + end_position: + bytes: 44 + line: 1 + character: 45 + token_type: + type: Identifier + identifier: rep + trailing_trivia: [] + args: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 44 + line: 1 + character: 45 + end_position: + bytes: 45 + line: 1 + character: 46 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 53 + line: 1 + character: 54 + end_position: + bytes: 54 + line: 1 + character: 55 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 54 + line: 1 + character: 55 + end_position: + bytes: 55 + line: 1 + character: 55 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 45 + line: 1 + character: 46 + end_position: + bytes: 53 + line: 1 + character: 54 + token_type: + type: Identifier + identifier: dotCount + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/assignment-5/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-5/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..8a751ba08eed9e7e9747ec0dbc760109ae37dc45 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-5/source.lua @@ -0,0 +1 @@ +gui.Label.Text = "LOADING DATA" .. ("."):rep(dotCount) diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/assignment-5/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-5/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..7006f66c9350088dfb3e448f56d919393eaf65aa --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/assignment-5/tokens.snap @@ -0,0 +1,250 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 40 +expression: tokens +input_file: full-moon/tests/cases/pass/assignment-5 +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Identifier + identifier: gui +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Identifier + identifier: Label +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Identifier + identifier: Text +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 31 + line: 1 + character: 32 + token_type: + type: StringLiteral + literal: LOADING DATA + quote_type: Double +- start_position: + bytes: 31 + line: 1 + character: 32 + end_position: + bytes: 32 + line: 1 + character: 33 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 32 + line: 1 + character: 33 + end_position: + bytes: 34 + line: 1 + character: 35 + token_type: + type: Symbol + symbol: ".." +- start_position: + bytes: 34 + line: 1 + character: 35 + end_position: + bytes: 35 + line: 1 + character: 36 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 35 + line: 1 + character: 36 + end_position: + bytes: 36 + line: 1 + character: 37 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 36 + line: 1 + character: 37 + end_position: + bytes: 39 + line: 1 + character: 40 + token_type: + type: StringLiteral + literal: "." + quote_type: Double +- start_position: + bytes: 39 + line: 1 + character: 40 + end_position: + bytes: 40 + line: 1 + character: 41 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 40 + line: 1 + character: 41 + end_position: + bytes: 41 + line: 1 + character: 42 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 41 + line: 1 + character: 42 + end_position: + bytes: 44 + line: 1 + character: 45 + token_type: + type: Identifier + identifier: rep +- start_position: + bytes: 44 + line: 1 + character: 45 + end_position: + bytes: 45 + line: 1 + character: 46 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 45 + line: 1 + character: 46 + end_position: + bytes: 53 + line: 1 + character: 54 + token_type: + type: Identifier + identifier: dotCount +- start_position: + bytes: 53 + line: 1 + character: 54 + end_position: + bytes: 54 + line: 1 + character: 55 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 54 + line: 1 + character: 55 + end_position: + bytes: 55 + line: 1 + character: 55 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 55 + line: 2 + character: 1 + end_position: + bytes: 55 + line: 2 + character: 1 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/binops/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/binops/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..2a2b13a5b1472135dc4b81a3cab778f946c37be6 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/binops/ast.snap @@ -0,0 +1,1840 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/binops +--- +stmts: + - - Assignment: + var_list: + pairs: + - End: + Name: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Identifier + identifier: a + trailing_trivia: + - start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + BinaryOperator: + lhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: foo + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + binop: + And: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: and + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Identifier + identifier: bar + trailing_trivia: + - start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - Assignment: + var_list: + pairs: + - End: + Name: + leading_trivia: [] + token: + start_position: + bytes: 16 + line: 2 + character: 1 + end_position: + bytes: 17 + line: 2 + character: 2 + token_type: + type: Identifier + identifier: b + trailing_trivia: + - start_position: + bytes: 17 + line: 2 + character: 2 + end_position: + bytes: 18 + line: 2 + character: 3 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 18 + line: 2 + character: 3 + end_position: + bytes: 19 + line: 2 + character: 4 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 19 + line: 2 + character: 4 + end_position: + bytes: 20 + line: 2 + character: 5 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + BinaryOperator: + lhs: + BinaryOperator: + lhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 20 + line: 2 + character: 5 + end_position: + bytes: 23 + line: 2 + character: 8 + token_type: + type: Identifier + identifier: foo + trailing_trivia: + - start_position: + bytes: 23 + line: 2 + character: 8 + end_position: + bytes: 24 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " + binop: + And: + leading_trivia: [] + token: + start_position: + bytes: 24 + line: 2 + character: 9 + end_position: + bytes: 27 + line: 2 + character: 12 + token_type: + type: Symbol + symbol: and + trailing_trivia: + - start_position: + bytes: 27 + line: 2 + character: 12 + end_position: + bytes: 28 + line: 2 + character: 13 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 28 + line: 2 + character: 13 + end_position: + bytes: 31 + line: 2 + character: 16 + token_type: + type: Identifier + identifier: bar + trailing_trivia: + - start_position: + bytes: 31 + line: 2 + character: 16 + end_position: + bytes: 32 + line: 2 + character: 17 + token_type: + type: Whitespace + characters: " " + binop: + Or: + leading_trivia: [] + token: + start_position: + bytes: 32 + line: 2 + character: 17 + end_position: + bytes: 34 + line: 2 + character: 19 + token_type: + type: Symbol + symbol: or + trailing_trivia: + - start_position: + bytes: 34 + line: 2 + character: 19 + end_position: + bytes: 35 + line: 2 + character: 20 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 35 + line: 2 + character: 20 + end_position: + bytes: 38 + line: 2 + character: 23 + token_type: + type: Identifier + identifier: baz + trailing_trivia: + - start_position: + bytes: 38 + line: 2 + character: 23 + end_position: + bytes: 39 + line: 2 + character: 23 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - Assignment: + var_list: + pairs: + - End: + Name: + leading_trivia: [] + token: + start_position: + bytes: 39 + line: 3 + character: 1 + end_position: + bytes: 40 + line: 3 + character: 2 + token_type: + type: Identifier + identifier: c + trailing_trivia: + - start_position: + bytes: 40 + line: 3 + character: 2 + end_position: + bytes: 41 + line: 3 + character: 3 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 41 + line: 3 + character: 3 + end_position: + bytes: 42 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 42 + line: 3 + character: 4 + end_position: + bytes: 43 + line: 3 + character: 5 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + BinaryOperator: + lhs: + BinaryOperator: + lhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 43 + line: 3 + character: 5 + end_position: + bytes: 44 + line: 3 + character: 6 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 44 + line: 3 + character: 6 + end_position: + bytes: 45 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " + binop: + Plus: + leading_trivia: [] + token: + start_position: + bytes: 45 + line: 3 + character: 7 + end_position: + bytes: 46 + line: 3 + character: 8 + token_type: + type: Symbol + symbol: + + trailing_trivia: + - start_position: + bytes: 46 + line: 3 + character: 8 + end_position: + bytes: 47 + line: 3 + character: 9 + token_type: + type: Whitespace + characters: " " + rhs: + BinaryOperator: + lhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 47 + line: 3 + character: 9 + end_position: + bytes: 48 + line: 3 + character: 10 + token_type: + type: Number + text: "2" + trailing_trivia: + - start_position: + bytes: 48 + line: 3 + character: 10 + end_position: + bytes: 49 + line: 3 + character: 11 + token_type: + type: Whitespace + characters: " " + binop: + Star: + leading_trivia: [] + token: + start_position: + bytes: 49 + line: 3 + character: 11 + end_position: + bytes: 50 + line: 3 + character: 12 + token_type: + type: Symbol + symbol: "*" + trailing_trivia: + - start_position: + bytes: 50 + line: 3 + character: 12 + end_position: + bytes: 51 + line: 3 + character: 13 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 51 + line: 3 + character: 13 + end_position: + bytes: 52 + line: 3 + character: 14 + token_type: + type: Number + text: "3" + trailing_trivia: + - start_position: + bytes: 52 + line: 3 + character: 14 + end_position: + bytes: 53 + line: 3 + character: 15 + token_type: + type: Whitespace + characters: " " + binop: + Minus: + leading_trivia: [] + token: + start_position: + bytes: 53 + line: 3 + character: 15 + end_position: + bytes: 54 + line: 3 + character: 16 + token_type: + type: Symbol + symbol: "-" + trailing_trivia: + - start_position: + bytes: 54 + line: 3 + character: 16 + end_position: + bytes: 55 + line: 3 + character: 17 + token_type: + type: Whitespace + characters: " " + rhs: + BinaryOperator: + lhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 55 + line: 3 + character: 17 + end_position: + bytes: 56 + line: 3 + character: 18 + token_type: + type: Number + text: "4" + trailing_trivia: + - start_position: + bytes: 56 + line: 3 + character: 18 + end_position: + bytes: 57 + line: 3 + character: 19 + token_type: + type: Whitespace + characters: " " + binop: + Caret: + leading_trivia: [] + token: + start_position: + bytes: 57 + line: 3 + character: 19 + end_position: + bytes: 58 + line: 3 + character: 20 + token_type: + type: Symbol + symbol: ^ + trailing_trivia: + - start_position: + bytes: 58 + line: 3 + character: 20 + end_position: + bytes: 59 + line: 3 + character: 21 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 59 + line: 3 + character: 21 + end_position: + bytes: 60 + line: 3 + character: 22 + token_type: + type: Number + text: "2" + trailing_trivia: + - start_position: + bytes: 60 + line: 3 + character: 22 + end_position: + bytes: 61 + line: 3 + character: 22 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - Assignment: + var_list: + pairs: + - End: + Name: + leading_trivia: [] + token: + start_position: + bytes: 61 + line: 4 + character: 1 + end_position: + bytes: 62 + line: 4 + character: 2 + token_type: + type: Identifier + identifier: d + trailing_trivia: + - start_position: + bytes: 62 + line: 4 + character: 2 + end_position: + bytes: 63 + line: 4 + character: 3 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 63 + line: 4 + character: 3 + end_position: + bytes: 64 + line: 4 + character: 4 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 64 + line: 4 + character: 4 + end_position: + bytes: 65 + line: 4 + character: 5 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + BinaryOperator: + lhs: + BinaryOperator: + lhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 65 + line: 4 + character: 5 + end_position: + bytes: 66 + line: 4 + character: 6 + token_type: + type: Identifier + identifier: a + trailing_trivia: + - start_position: + bytes: 66 + line: 4 + character: 6 + end_position: + bytes: 67 + line: 4 + character: 7 + token_type: + type: Whitespace + characters: " " + binop: + Plus: + leading_trivia: [] + token: + start_position: + bytes: 67 + line: 4 + character: 7 + end_position: + bytes: 68 + line: 4 + character: 8 + token_type: + type: Symbol + symbol: + + trailing_trivia: + - start_position: + bytes: 68 + line: 4 + character: 8 + end_position: + bytes: 69 + line: 4 + character: 9 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 69 + line: 4 + character: 9 + end_position: + bytes: 70 + line: 4 + character: 10 + token_type: + type: Identifier + identifier: i + trailing_trivia: + - start_position: + bytes: 70 + line: 4 + character: 10 + end_position: + bytes: 71 + line: 4 + character: 11 + token_type: + type: Whitespace + characters: " " + binop: + LessThan: + leading_trivia: [] + token: + start_position: + bytes: 71 + line: 4 + character: 11 + end_position: + bytes: 72 + line: 4 + character: 12 + token_type: + type: Symbol + symbol: "<" + trailing_trivia: + - start_position: + bytes: 72 + line: 4 + character: 12 + end_position: + bytes: 73 + line: 4 + character: 13 + token_type: + type: Whitespace + characters: " " + rhs: + BinaryOperator: + lhs: + BinaryOperator: + lhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 73 + line: 4 + character: 13 + end_position: + bytes: 74 + line: 4 + character: 14 + token_type: + type: Identifier + identifier: b + trailing_trivia: + - start_position: + bytes: 74 + line: 4 + character: 14 + end_position: + bytes: 75 + line: 4 + character: 15 + token_type: + type: Whitespace + characters: " " + binop: + Slash: + leading_trivia: [] + token: + start_position: + bytes: 75 + line: 4 + character: 15 + end_position: + bytes: 76 + line: 4 + character: 16 + token_type: + type: Symbol + symbol: / + trailing_trivia: + - start_position: + bytes: 76 + line: 4 + character: 16 + end_position: + bytes: 77 + line: 4 + character: 17 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 77 + line: 4 + character: 17 + end_position: + bytes: 78 + line: 4 + character: 18 + token_type: + type: Number + text: "2" + trailing_trivia: + - start_position: + bytes: 78 + line: 4 + character: 18 + end_position: + bytes: 79 + line: 4 + character: 19 + token_type: + type: Whitespace + characters: " " + binop: + Plus: + leading_trivia: [] + token: + start_position: + bytes: 79 + line: 4 + character: 19 + end_position: + bytes: 80 + line: 4 + character: 20 + token_type: + type: Symbol + symbol: + + trailing_trivia: + - start_position: + bytes: 80 + line: 4 + character: 20 + end_position: + bytes: 81 + line: 4 + character: 21 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 81 + line: 4 + character: 21 + end_position: + bytes: 82 + line: 4 + character: 22 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 82 + line: 4 + character: 22 + end_position: + bytes: 83 + line: 4 + character: 22 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - Assignment: + var_list: + pairs: + - End: + Name: + leading_trivia: [] + token: + start_position: + bytes: 83 + line: 5 + character: 1 + end_position: + bytes: 84 + line: 5 + character: 2 + token_type: + type: Identifier + identifier: e + trailing_trivia: + - start_position: + bytes: 84 + line: 5 + character: 2 + end_position: + bytes: 85 + line: 5 + character: 3 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 85 + line: 5 + character: 3 + end_position: + bytes: 86 + line: 5 + character: 4 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 86 + line: 5 + character: 4 + end_position: + bytes: 87 + line: 5 + character: 5 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + BinaryOperator: + lhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 87 + line: 5 + character: 5 + end_position: + bytes: 88 + line: 5 + character: 6 + token_type: + type: Number + text: "5" + trailing_trivia: + - start_position: + bytes: 88 + line: 5 + character: 6 + end_position: + bytes: 89 + line: 5 + character: 7 + token_type: + type: Whitespace + characters: " " + binop: + Plus: + leading_trivia: [] + token: + start_position: + bytes: 89 + line: 5 + character: 7 + end_position: + bytes: 90 + line: 5 + character: 8 + token_type: + type: Symbol + symbol: + + trailing_trivia: + - start_position: + bytes: 90 + line: 5 + character: 8 + end_position: + bytes: 91 + line: 5 + character: 9 + token_type: + type: Whitespace + characters: " " + rhs: + BinaryOperator: + lhs: + BinaryOperator: + lhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 91 + line: 5 + character: 9 + end_position: + bytes: 92 + line: 5 + character: 10 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 92 + line: 5 + character: 10 + end_position: + bytes: 93 + line: 5 + character: 11 + token_type: + type: Whitespace + characters: " " + binop: + Caret: + leading_trivia: [] + token: + start_position: + bytes: 93 + line: 5 + character: 11 + end_position: + bytes: 94 + line: 5 + character: 12 + token_type: + type: Symbol + symbol: ^ + trailing_trivia: + - start_position: + bytes: 94 + line: 5 + character: 12 + end_position: + bytes: 95 + line: 5 + character: 13 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 95 + line: 5 + character: 13 + end_position: + bytes: 96 + line: 5 + character: 14 + token_type: + type: Number + text: "2" + trailing_trivia: + - start_position: + bytes: 96 + line: 5 + character: 14 + end_position: + bytes: 97 + line: 5 + character: 15 + token_type: + type: Whitespace + characters: " " + binop: + Star: + leading_trivia: [] + token: + start_position: + bytes: 97 + line: 5 + character: 15 + end_position: + bytes: 98 + line: 5 + character: 16 + token_type: + type: Symbol + symbol: "*" + trailing_trivia: + - start_position: + bytes: 98 + line: 5 + character: 16 + end_position: + bytes: 99 + line: 5 + character: 17 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 99 + line: 5 + character: 17 + end_position: + bytes: 100 + line: 5 + character: 18 + token_type: + type: Number + text: "8" + trailing_trivia: + - start_position: + bytes: 100 + line: 5 + character: 18 + end_position: + bytes: 101 + line: 5 + character: 18 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - Assignment: + var_list: + pairs: + - End: + Name: + leading_trivia: [] + token: + start_position: + bytes: 101 + line: 6 + character: 1 + end_position: + bytes: 102 + line: 6 + character: 2 + token_type: + type: Identifier + identifier: f + trailing_trivia: + - start_position: + bytes: 102 + line: 6 + character: 2 + end_position: + bytes: 103 + line: 6 + character: 3 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 103 + line: 6 + character: 3 + end_position: + bytes: 104 + line: 6 + character: 4 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 104 + line: 6 + character: 4 + end_position: + bytes: 105 + line: 6 + character: 5 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + BinaryOperator: + lhs: + BinaryOperator: + lhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 105 + line: 6 + character: 5 + end_position: + bytes: 106 + line: 6 + character: 6 + token_type: + type: Identifier + identifier: a + trailing_trivia: + - start_position: + bytes: 106 + line: 6 + character: 6 + end_position: + bytes: 107 + line: 6 + character: 7 + token_type: + type: Whitespace + characters: " " + binop: + LessThan: + leading_trivia: [] + token: + start_position: + bytes: 107 + line: 6 + character: 7 + end_position: + bytes: 108 + line: 6 + character: 8 + token_type: + type: Symbol + symbol: "<" + trailing_trivia: + - start_position: + bytes: 108 + line: 6 + character: 8 + end_position: + bytes: 109 + line: 6 + character: 9 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 109 + line: 6 + character: 9 + end_position: + bytes: 110 + line: 6 + character: 10 + token_type: + type: Identifier + identifier: y + trailing_trivia: + - start_position: + bytes: 110 + line: 6 + character: 10 + end_position: + bytes: 111 + line: 6 + character: 11 + token_type: + type: Whitespace + characters: " " + binop: + And: + leading_trivia: [] + token: + start_position: + bytes: 111 + line: 6 + character: 11 + end_position: + bytes: 114 + line: 6 + character: 14 + token_type: + type: Symbol + symbol: and + trailing_trivia: + - start_position: + bytes: 114 + line: 6 + character: 14 + end_position: + bytes: 115 + line: 6 + character: 15 + token_type: + type: Whitespace + characters: " " + rhs: + BinaryOperator: + lhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 115 + line: 6 + character: 15 + end_position: + bytes: 116 + line: 6 + character: 16 + token_type: + type: Identifier + identifier: y + trailing_trivia: + - start_position: + bytes: 116 + line: 6 + character: 16 + end_position: + bytes: 117 + line: 6 + character: 17 + token_type: + type: Whitespace + characters: " " + binop: + LessThanEqual: + leading_trivia: [] + token: + start_position: + bytes: 117 + line: 6 + character: 17 + end_position: + bytes: 119 + line: 6 + character: 19 + token_type: + type: Symbol + symbol: "<=" + trailing_trivia: + - start_position: + bytes: 119 + line: 6 + character: 19 + end_position: + bytes: 120 + line: 6 + character: 20 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 120 + line: 6 + character: 20 + end_position: + bytes: 121 + line: 6 + character: 21 + token_type: + type: Identifier + identifier: z + trailing_trivia: + - start_position: + bytes: 121 + line: 6 + character: 21 + end_position: + bytes: 122 + line: 6 + character: 21 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - Assignment: + var_list: + pairs: + - End: + Name: + leading_trivia: [] + token: + start_position: + bytes: 122 + line: 7 + character: 1 + end_position: + bytes: 123 + line: 7 + character: 2 + token_type: + type: Identifier + identifier: g + trailing_trivia: + - start_position: + bytes: 123 + line: 7 + character: 2 + end_position: + bytes: 124 + line: 7 + character: 3 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 124 + line: 7 + character: 3 + end_position: + bytes: 125 + line: 7 + character: 4 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 125 + line: 7 + character: 4 + end_position: + bytes: 126 + line: 7 + character: 5 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + UnaryOperator: + unop: + Minus: + leading_trivia: [] + token: + start_position: + bytes: 126 + line: 7 + character: 5 + end_position: + bytes: 127 + line: 7 + character: 6 + token_type: + type: Symbol + symbol: "-" + trailing_trivia: [] + expression: + BinaryOperator: + lhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 127 + line: 7 + character: 6 + end_position: + bytes: 128 + line: 7 + character: 7 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 128 + line: 7 + character: 7 + end_position: + bytes: 129 + line: 7 + character: 8 + token_type: + type: Whitespace + characters: " " + binop: + Caret: + leading_trivia: [] + token: + start_position: + bytes: 129 + line: 7 + character: 8 + end_position: + bytes: 130 + line: 7 + character: 9 + token_type: + type: Symbol + symbol: ^ + trailing_trivia: + - start_position: + bytes: 130 + line: 7 + character: 9 + end_position: + bytes: 131 + line: 7 + character: 10 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 131 + line: 7 + character: 10 + end_position: + bytes: 132 + line: 7 + character: 11 + token_type: + type: Number + text: "2" + trailing_trivia: + - start_position: + bytes: 132 + line: 7 + character: 11 + end_position: + bytes: 133 + line: 7 + character: 11 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - Assignment: + var_list: + pairs: + - End: + Name: + leading_trivia: [] + token: + start_position: + bytes: 133 + line: 8 + character: 1 + end_position: + bytes: 134 + line: 8 + character: 2 + token_type: + type: Identifier + identifier: h + trailing_trivia: + - start_position: + bytes: 134 + line: 8 + character: 2 + end_position: + bytes: 135 + line: 8 + character: 3 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 135 + line: 8 + character: 3 + end_position: + bytes: 136 + line: 8 + character: 4 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 136 + line: 8 + character: 4 + end_position: + bytes: 137 + line: 8 + character: 5 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + BinaryOperator: + lhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 137 + line: 8 + character: 5 + end_position: + bytes: 138 + line: 8 + character: 6 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 138 + line: 8 + character: 6 + end_position: + bytes: 139 + line: 8 + character: 7 + token_type: + type: Whitespace + characters: " " + binop: + Caret: + leading_trivia: [] + token: + start_position: + bytes: 139 + line: 8 + character: 7 + end_position: + bytes: 140 + line: 8 + character: 8 + token_type: + type: Symbol + symbol: ^ + trailing_trivia: + - start_position: + bytes: 140 + line: 8 + character: 8 + end_position: + bytes: 141 + line: 8 + character: 9 + token_type: + type: Whitespace + characters: " " + rhs: + BinaryOperator: + lhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 141 + line: 8 + character: 9 + end_position: + bytes: 142 + line: 8 + character: 10 + token_type: + type: Identifier + identifier: y + trailing_trivia: + - start_position: + bytes: 142 + line: 8 + character: 10 + end_position: + bytes: 143 + line: 8 + character: 11 + token_type: + type: Whitespace + characters: " " + binop: + Caret: + leading_trivia: [] + token: + start_position: + bytes: 143 + line: 8 + character: 11 + end_position: + bytes: 144 + line: 8 + character: 12 + token_type: + type: Symbol + symbol: ^ + trailing_trivia: + - start_position: + bytes: 144 + line: 8 + character: 12 + end_position: + bytes: 145 + line: 8 + character: 13 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 145 + line: 8 + character: 13 + end_position: + bytes: 146 + line: 8 + character: 14 + token_type: + type: Identifier + identifier: z + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/binops/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/binops/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..5397e71ca3f52252f542990ea76bfc7eba1e4ad3 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/binops/source.lua @@ -0,0 +1,8 @@ +a = foo and bar +b = foo and bar or baz +c = 1 + 2 * 3 - 4 ^ 2 +d = a + i < b / 2 + 1 +e = 5 + x ^ 2 * 8 +f = a < y and y <= z +g = -x ^ 2 +h = x ^ y ^ z \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/binops/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/binops/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..7d0e52d38df8b68e31d50e142d0f4ecf7c0b3a53 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/binops/tokens.snap @@ -0,0 +1,1425 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/binops + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Identifier + identifier: a +- start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: and +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Identifier + identifier: bar +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 16 + line: 2 + character: 1 + end_position: + bytes: 17 + line: 2 + character: 2 + token_type: + type: Identifier + identifier: b +- start_position: + bytes: 17 + line: 2 + character: 2 + end_position: + bytes: 18 + line: 2 + character: 3 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 18 + line: 2 + character: 3 + end_position: + bytes: 19 + line: 2 + character: 4 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 19 + line: 2 + character: 4 + end_position: + bytes: 20 + line: 2 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 20 + line: 2 + character: 5 + end_position: + bytes: 23 + line: 2 + character: 8 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 23 + line: 2 + character: 8 + end_position: + bytes: 24 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 24 + line: 2 + character: 9 + end_position: + bytes: 27 + line: 2 + character: 12 + token_type: + type: Symbol + symbol: and +- start_position: + bytes: 27 + line: 2 + character: 12 + end_position: + bytes: 28 + line: 2 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 28 + line: 2 + character: 13 + end_position: + bytes: 31 + line: 2 + character: 16 + token_type: + type: Identifier + identifier: bar +- start_position: + bytes: 31 + line: 2 + character: 16 + end_position: + bytes: 32 + line: 2 + character: 17 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 32 + line: 2 + character: 17 + end_position: + bytes: 34 + line: 2 + character: 19 + token_type: + type: Symbol + symbol: or +- start_position: + bytes: 34 + line: 2 + character: 19 + end_position: + bytes: 35 + line: 2 + character: 20 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 35 + line: 2 + character: 20 + end_position: + bytes: 38 + line: 2 + character: 23 + token_type: + type: Identifier + identifier: baz +- start_position: + bytes: 38 + line: 2 + character: 23 + end_position: + bytes: 39 + line: 2 + character: 23 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 39 + line: 3 + character: 1 + end_position: + bytes: 40 + line: 3 + character: 2 + token_type: + type: Identifier + identifier: c +- start_position: + bytes: 40 + line: 3 + character: 2 + end_position: + bytes: 41 + line: 3 + character: 3 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 41 + line: 3 + character: 3 + end_position: + bytes: 42 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 42 + line: 3 + character: 4 + end_position: + bytes: 43 + line: 3 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 43 + line: 3 + character: 5 + end_position: + bytes: 44 + line: 3 + character: 6 + token_type: + type: Number + text: "1" +- start_position: + bytes: 44 + line: 3 + character: 6 + end_position: + bytes: 45 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 45 + line: 3 + character: 7 + end_position: + bytes: 46 + line: 3 + character: 8 + token_type: + type: Symbol + symbol: + +- start_position: + bytes: 46 + line: 3 + character: 8 + end_position: + bytes: 47 + line: 3 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 47 + line: 3 + character: 9 + end_position: + bytes: 48 + line: 3 + character: 10 + token_type: + type: Number + text: "2" +- start_position: + bytes: 48 + line: 3 + character: 10 + end_position: + bytes: 49 + line: 3 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 49 + line: 3 + character: 11 + end_position: + bytes: 50 + line: 3 + character: 12 + token_type: + type: Symbol + symbol: "*" +- start_position: + bytes: 50 + line: 3 + character: 12 + end_position: + bytes: 51 + line: 3 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 51 + line: 3 + character: 13 + end_position: + bytes: 52 + line: 3 + character: 14 + token_type: + type: Number + text: "3" +- start_position: + bytes: 52 + line: 3 + character: 14 + end_position: + bytes: 53 + line: 3 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 53 + line: 3 + character: 15 + end_position: + bytes: 54 + line: 3 + character: 16 + token_type: + type: Symbol + symbol: "-" +- start_position: + bytes: 54 + line: 3 + character: 16 + end_position: + bytes: 55 + line: 3 + character: 17 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 55 + line: 3 + character: 17 + end_position: + bytes: 56 + line: 3 + character: 18 + token_type: + type: Number + text: "4" +- start_position: + bytes: 56 + line: 3 + character: 18 + end_position: + bytes: 57 + line: 3 + character: 19 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 57 + line: 3 + character: 19 + end_position: + bytes: 58 + line: 3 + character: 20 + token_type: + type: Symbol + symbol: ^ +- start_position: + bytes: 58 + line: 3 + character: 20 + end_position: + bytes: 59 + line: 3 + character: 21 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 59 + line: 3 + character: 21 + end_position: + bytes: 60 + line: 3 + character: 22 + token_type: + type: Number + text: "2" +- start_position: + bytes: 60 + line: 3 + character: 22 + end_position: + bytes: 61 + line: 3 + character: 22 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 61 + line: 4 + character: 1 + end_position: + bytes: 62 + line: 4 + character: 2 + token_type: + type: Identifier + identifier: d +- start_position: + bytes: 62 + line: 4 + character: 2 + end_position: + bytes: 63 + line: 4 + character: 3 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 63 + line: 4 + character: 3 + end_position: + bytes: 64 + line: 4 + character: 4 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 64 + line: 4 + character: 4 + end_position: + bytes: 65 + line: 4 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 65 + line: 4 + character: 5 + end_position: + bytes: 66 + line: 4 + character: 6 + token_type: + type: Identifier + identifier: a +- start_position: + bytes: 66 + line: 4 + character: 6 + end_position: + bytes: 67 + line: 4 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 67 + line: 4 + character: 7 + end_position: + bytes: 68 + line: 4 + character: 8 + token_type: + type: Symbol + symbol: + +- start_position: + bytes: 68 + line: 4 + character: 8 + end_position: + bytes: 69 + line: 4 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 69 + line: 4 + character: 9 + end_position: + bytes: 70 + line: 4 + character: 10 + token_type: + type: Identifier + identifier: i +- start_position: + bytes: 70 + line: 4 + character: 10 + end_position: + bytes: 71 + line: 4 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 71 + line: 4 + character: 11 + end_position: + bytes: 72 + line: 4 + character: 12 + token_type: + type: Symbol + symbol: "<" +- start_position: + bytes: 72 + line: 4 + character: 12 + end_position: + bytes: 73 + line: 4 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 73 + line: 4 + character: 13 + end_position: + bytes: 74 + line: 4 + character: 14 + token_type: + type: Identifier + identifier: b +- start_position: + bytes: 74 + line: 4 + character: 14 + end_position: + bytes: 75 + line: 4 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 75 + line: 4 + character: 15 + end_position: + bytes: 76 + line: 4 + character: 16 + token_type: + type: Symbol + symbol: / +- start_position: + bytes: 76 + line: 4 + character: 16 + end_position: + bytes: 77 + line: 4 + character: 17 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 77 + line: 4 + character: 17 + end_position: + bytes: 78 + line: 4 + character: 18 + token_type: + type: Number + text: "2" +- start_position: + bytes: 78 + line: 4 + character: 18 + end_position: + bytes: 79 + line: 4 + character: 19 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 79 + line: 4 + character: 19 + end_position: + bytes: 80 + line: 4 + character: 20 + token_type: + type: Symbol + symbol: + +- start_position: + bytes: 80 + line: 4 + character: 20 + end_position: + bytes: 81 + line: 4 + character: 21 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 81 + line: 4 + character: 21 + end_position: + bytes: 82 + line: 4 + character: 22 + token_type: + type: Number + text: "1" +- start_position: + bytes: 82 + line: 4 + character: 22 + end_position: + bytes: 83 + line: 4 + character: 22 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 83 + line: 5 + character: 1 + end_position: + bytes: 84 + line: 5 + character: 2 + token_type: + type: Identifier + identifier: e +- start_position: + bytes: 84 + line: 5 + character: 2 + end_position: + bytes: 85 + line: 5 + character: 3 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 85 + line: 5 + character: 3 + end_position: + bytes: 86 + line: 5 + character: 4 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 86 + line: 5 + character: 4 + end_position: + bytes: 87 + line: 5 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 87 + line: 5 + character: 5 + end_position: + bytes: 88 + line: 5 + character: 6 + token_type: + type: Number + text: "5" +- start_position: + bytes: 88 + line: 5 + character: 6 + end_position: + bytes: 89 + line: 5 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 89 + line: 5 + character: 7 + end_position: + bytes: 90 + line: 5 + character: 8 + token_type: + type: Symbol + symbol: + +- start_position: + bytes: 90 + line: 5 + character: 8 + end_position: + bytes: 91 + line: 5 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 91 + line: 5 + character: 9 + end_position: + bytes: 92 + line: 5 + character: 10 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 92 + line: 5 + character: 10 + end_position: + bytes: 93 + line: 5 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 93 + line: 5 + character: 11 + end_position: + bytes: 94 + line: 5 + character: 12 + token_type: + type: Symbol + symbol: ^ +- start_position: + bytes: 94 + line: 5 + character: 12 + end_position: + bytes: 95 + line: 5 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 95 + line: 5 + character: 13 + end_position: + bytes: 96 + line: 5 + character: 14 + token_type: + type: Number + text: "2" +- start_position: + bytes: 96 + line: 5 + character: 14 + end_position: + bytes: 97 + line: 5 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 97 + line: 5 + character: 15 + end_position: + bytes: 98 + line: 5 + character: 16 + token_type: + type: Symbol + symbol: "*" +- start_position: + bytes: 98 + line: 5 + character: 16 + end_position: + bytes: 99 + line: 5 + character: 17 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 99 + line: 5 + character: 17 + end_position: + bytes: 100 + line: 5 + character: 18 + token_type: + type: Number + text: "8" +- start_position: + bytes: 100 + line: 5 + character: 18 + end_position: + bytes: 101 + line: 5 + character: 18 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 101 + line: 6 + character: 1 + end_position: + bytes: 102 + line: 6 + character: 2 + token_type: + type: Identifier + identifier: f +- start_position: + bytes: 102 + line: 6 + character: 2 + end_position: + bytes: 103 + line: 6 + character: 3 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 103 + line: 6 + character: 3 + end_position: + bytes: 104 + line: 6 + character: 4 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 104 + line: 6 + character: 4 + end_position: + bytes: 105 + line: 6 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 105 + line: 6 + character: 5 + end_position: + bytes: 106 + line: 6 + character: 6 + token_type: + type: Identifier + identifier: a +- start_position: + bytes: 106 + line: 6 + character: 6 + end_position: + bytes: 107 + line: 6 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 107 + line: 6 + character: 7 + end_position: + bytes: 108 + line: 6 + character: 8 + token_type: + type: Symbol + symbol: "<" +- start_position: + bytes: 108 + line: 6 + character: 8 + end_position: + bytes: 109 + line: 6 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 109 + line: 6 + character: 9 + end_position: + bytes: 110 + line: 6 + character: 10 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 110 + line: 6 + character: 10 + end_position: + bytes: 111 + line: 6 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 111 + line: 6 + character: 11 + end_position: + bytes: 114 + line: 6 + character: 14 + token_type: + type: Symbol + symbol: and +- start_position: + bytes: 114 + line: 6 + character: 14 + end_position: + bytes: 115 + line: 6 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 115 + line: 6 + character: 15 + end_position: + bytes: 116 + line: 6 + character: 16 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 116 + line: 6 + character: 16 + end_position: + bytes: 117 + line: 6 + character: 17 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 117 + line: 6 + character: 17 + end_position: + bytes: 119 + line: 6 + character: 19 + token_type: + type: Symbol + symbol: "<=" +- start_position: + bytes: 119 + line: 6 + character: 19 + end_position: + bytes: 120 + line: 6 + character: 20 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 120 + line: 6 + character: 20 + end_position: + bytes: 121 + line: 6 + character: 21 + token_type: + type: Identifier + identifier: z +- start_position: + bytes: 121 + line: 6 + character: 21 + end_position: + bytes: 122 + line: 6 + character: 21 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 122 + line: 7 + character: 1 + end_position: + bytes: 123 + line: 7 + character: 2 + token_type: + type: Identifier + identifier: g +- start_position: + bytes: 123 + line: 7 + character: 2 + end_position: + bytes: 124 + line: 7 + character: 3 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 124 + line: 7 + character: 3 + end_position: + bytes: 125 + line: 7 + character: 4 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 125 + line: 7 + character: 4 + end_position: + bytes: 126 + line: 7 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 126 + line: 7 + character: 5 + end_position: + bytes: 127 + line: 7 + character: 6 + token_type: + type: Symbol + symbol: "-" +- start_position: + bytes: 127 + line: 7 + character: 6 + end_position: + bytes: 128 + line: 7 + character: 7 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 128 + line: 7 + character: 7 + end_position: + bytes: 129 + line: 7 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 129 + line: 7 + character: 8 + end_position: + bytes: 130 + line: 7 + character: 9 + token_type: + type: Symbol + symbol: ^ +- start_position: + bytes: 130 + line: 7 + character: 9 + end_position: + bytes: 131 + line: 7 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 131 + line: 7 + character: 10 + end_position: + bytes: 132 + line: 7 + character: 11 + token_type: + type: Number + text: "2" +- start_position: + bytes: 132 + line: 7 + character: 11 + end_position: + bytes: 133 + line: 7 + character: 11 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 133 + line: 8 + character: 1 + end_position: + bytes: 134 + line: 8 + character: 2 + token_type: + type: Identifier + identifier: h +- start_position: + bytes: 134 + line: 8 + character: 2 + end_position: + bytes: 135 + line: 8 + character: 3 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 135 + line: 8 + character: 3 + end_position: + bytes: 136 + line: 8 + character: 4 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 136 + line: 8 + character: 4 + end_position: + bytes: 137 + line: 8 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 137 + line: 8 + character: 5 + end_position: + bytes: 138 + line: 8 + character: 6 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 138 + line: 8 + character: 6 + end_position: + bytes: 139 + line: 8 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 139 + line: 8 + character: 7 + end_position: + bytes: 140 + line: 8 + character: 8 + token_type: + type: Symbol + symbol: ^ +- start_position: + bytes: 140 + line: 8 + character: 8 + end_position: + bytes: 141 + line: 8 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 141 + line: 8 + character: 9 + end_position: + bytes: 142 + line: 8 + character: 10 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 142 + line: 8 + character: 10 + end_position: + bytes: 143 + line: 8 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 143 + line: 8 + character: 11 + end_position: + bytes: 144 + line: 8 + character: 12 + token_type: + type: Symbol + symbol: ^ +- start_position: + bytes: 144 + line: 8 + character: 12 + end_position: + bytes: 145 + line: 8 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 145 + line: 8 + character: 13 + end_position: + bytes: 146 + line: 8 + character: 14 + token_type: + type: Identifier + identifier: z +- start_position: + bytes: 146 + line: 8 + character: 14 + end_position: + bytes: 146 + line: 8 + character: 14 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/body-with-spaces/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/body-with-spaces/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..46d33fda3558d53357ff7865cf888a586cb084c1 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/body-with-spaces/ast.snap @@ -0,0 +1,62 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +--- +stmts: + - - Do: + do_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 3 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: [] + end_token: + leading_trivia: + - start_position: + bytes: 3 + line: 2 + character: 1 + end_position: + bytes: 8 + line: 2 + character: 5 + token_type: + type: Whitespace + characters: " \n" + token: + start_position: + bytes: 8 + line: 3 + character: 1 + end_position: + bytes: 11 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/body-with-spaces/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/body-with-spaces/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..c0697c93e79c5121f4865f7cf3975d16f664d2e7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/body-with-spaces/source.lua @@ -0,0 +1,3 @@ +do + +end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/body-with-spaces/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/body-with-spaces/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..841093a4e3750a772830229b514b61bdd12d712e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/body-with-spaces/tokens.snap @@ -0,0 +1,59 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 3 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 3 + line: 2 + character: 1 + end_position: + bytes: 8 + line: 2 + character: 5 + token_type: + type: Whitespace + characters: " \n" +- start_position: + bytes: 8 + line: 3 + character: 1 + end_position: + bytes: 11 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 11 + line: 3 + character: 4 + end_position: + bytes: 11 + line: 3 + character: 4 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/call-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/call-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..f2b812e74ac11f5bb7ba27d6518b0cc8ca977254 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/call-1/ast.snap @@ -0,0 +1,265 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/call-1 +--- +stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: [] + - ~ + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 7 + line: 2 + character: 1 + end_position: + bytes: 11 + line: 2 + character: 5 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 11 + line: 2 + character: 5 + end_position: + bytes: 12 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 13 + line: 2 + character: 7 + end_position: + bytes: 14 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 14 + line: 2 + character: 8 + end_position: + bytes: 15 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 2 + character: 6 + end_position: + bytes: 13 + line: 2 + character: 7 + token_type: + type: Number + text: "1" + trailing_trivia: [] + - ~ + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 15 + line: 3 + character: 1 + end_position: + bytes: 19 + line: 3 + character: 5 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 19 + line: 3 + character: 5 + end_position: + bytes: 20 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 24 + line: 3 + character: 10 + end_position: + bytes: 25 + line: 3 + character: 11 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: + - Punctuated: + - Number: + leading_trivia: [] + token: + start_position: + bytes: 20 + line: 3 + character: 6 + end_position: + bytes: 21 + line: 3 + character: 7 + token_type: + type: Number + text: "1" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 21 + line: 3 + character: 7 + end_position: + bytes: 22 + line: 3 + character: 8 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 22 + line: 3 + character: 8 + end_position: + bytes: 23 + line: 3 + character: 9 + token_type: + type: Whitespace + characters: " " + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 23 + line: 3 + character: 9 + end_position: + bytes: 24 + line: 3 + character: 10 + token_type: + type: Number + text: "2" + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/call-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/call-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..42e66348fe513093fd7ad696b19cbf1e611eaaa5 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/call-1/source.lua @@ -0,0 +1,3 @@ +call() +call(1) +call(1, 2) \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/call-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/call-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..c0062d305767924a9fc6488f149fb1c78a548ea7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/call-1/tokens.snap @@ -0,0 +1,193 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/call-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 7 + line: 2 + character: 1 + end_position: + bytes: 11 + line: 2 + character: 5 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 11 + line: 2 + character: 5 + end_position: + bytes: 12 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 12 + line: 2 + character: 6 + end_position: + bytes: 13 + line: 2 + character: 7 + token_type: + type: Number + text: "1" +- start_position: + bytes: 13 + line: 2 + character: 7 + end_position: + bytes: 14 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 14 + line: 2 + character: 8 + end_position: + bytes: 15 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 15 + line: 3 + character: 1 + end_position: + bytes: 19 + line: 3 + character: 5 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 19 + line: 3 + character: 5 + end_position: + bytes: 20 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 20 + line: 3 + character: 6 + end_position: + bytes: 21 + line: 3 + character: 7 + token_type: + type: Number + text: "1" +- start_position: + bytes: 21 + line: 3 + character: 7 + end_position: + bytes: 22 + line: 3 + character: 8 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 22 + line: 3 + character: 8 + end_position: + bytes: 23 + line: 3 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 23 + line: 3 + character: 9 + end_position: + bytes: 24 + line: 3 + character: 10 + token_type: + type: Number + text: "2" +- start_position: + bytes: 24 + line: 3 + character: 10 + end_position: + bytes: 25 + line: 3 + character: 11 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 25 + line: 3 + character: 11 + end_position: + bytes: 25 + line: 3 + character: 11 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/call-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/call-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..f31d1a87458f5465c9dae744a9faded81eeabe33 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/call-2/ast.snap @@ -0,0 +1,224 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/call-2 +--- +stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Identifier + identifier: x + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Identifier + identifier: y + trailing_trivia: [] + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: StringLiteral + literal: a + quote_type: Double + trailing_trivia: [] + - ~ + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 2 + character: 1 + end_position: + bytes: 10 + line: 2 + character: 2 + token_type: + type: Identifier + identifier: x + trailing_trivia: [] + suffixes: + - Call: + MethodCall: + colon_token: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 2 + character: 2 + end_position: + bytes: 11 + line: 2 + character: 3 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 11 + line: 2 + character: 3 + end_position: + bytes: 12 + line: 2 + character: 4 + token_type: + type: Identifier + identifier: y + trailing_trivia: [] + args: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 12 + line: 2 + character: 4 + end_position: + bytes: 13 + line: 2 + character: 5 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 16 + line: 2 + character: 8 + end_position: + bytes: 17 + line: 2 + character: 9 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 13 + line: 2 + character: 5 + end_position: + bytes: 16 + line: 2 + character: 8 + token_type: + type: StringLiteral + literal: b + quote_type: Double + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/call-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/call-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..d65eca40075d346dbb1e1aa5b31efaa8d2602b07 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/call-2/source.lua @@ -0,0 +1,2 @@ +x.y("a") +x:y("b") \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/call-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/call-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..e265844d1a3fcc5562652722b79aa4f3f5069313 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/call-2/tokens.snap @@ -0,0 +1,162 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/call-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: StringLiteral + literal: a + quote_type: Double +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 9 + line: 2 + character: 1 + end_position: + bytes: 10 + line: 2 + character: 2 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 10 + line: 2 + character: 2 + end_position: + bytes: 11 + line: 2 + character: 3 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 11 + line: 2 + character: 3 + end_position: + bytes: 12 + line: 2 + character: 4 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 12 + line: 2 + character: 4 + end_position: + bytes: 13 + line: 2 + character: 5 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 13 + line: 2 + character: 5 + end_position: + bytes: 16 + line: 2 + character: 8 + token_type: + type: StringLiteral + literal: b + quote_type: Double +- start_position: + bytes: 16 + line: 2 + character: 8 + end_position: + bytes: 17 + line: 2 + character: 9 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 17 + line: 2 + character: 9 + end_position: + bytes: 17 + line: 2 + character: 9 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/do/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/do/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..68979cf55f46c3488ed43102b9e1b78ea18de42e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/do/ast.snap @@ -0,0 +1,129 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/do + +--- +stmts: + - - Do: + do_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 3 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 3 + line: 2 + character: 1 + end_position: + bytes: 4 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 4 + line: 2 + character: 2 + end_position: + bytes: 8 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 8 + line: 2 + character: 6 + end_position: + bytes: 9 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 9 + line: 2 + character: 7 + end_position: + bytes: 10 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 10 + line: 2 + character: 8 + end_position: + bytes: 11 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: [] + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 11 + line: 3 + character: 1 + end_position: + bytes: 14 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/do/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/do/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..634f506da21f2af245d13ad7af031bd5be45f55a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/do/source.lua @@ -0,0 +1,3 @@ +do + call() +end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/do/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/do/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..27870214b470fd8e121701cf7bbaa8414829db9e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/do/tokens.snap @@ -0,0 +1,105 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/do + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 3 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 3 + line: 2 + character: 1 + end_position: + bytes: 4 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 4 + line: 2 + character: 2 + end_position: + bytes: 8 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 8 + line: 2 + character: 6 + end_position: + bytes: 9 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 9 + line: 2 + character: 7 + end_position: + bytes: 10 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 10 + line: 2 + character: 8 + end_position: + bytes: 11 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 11 + line: 3 + character: 1 + end_position: + bytes: 14 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 14 + line: 3 + character: 4 + end_position: + bytes: 14 + line: 3 + character: 4 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/empty/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/empty/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..3bc4ce6b5a343a04773dc7bd3c20550bb9d60c2a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/empty/ast.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/empty + +--- +stmts: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/empty/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/empty/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/empty/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/empty/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..ede4fa88725e64d8b4e0a302f20ed2ac00dd9175 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/empty/tokens.snap @@ -0,0 +1,17 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/empty + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 0 + line: 1 + character: 1 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/exponents/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/exponents/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..1fd0d77fedcab23aa30196e1f7523b1032bb930a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/exponents/ast.snap @@ -0,0 +1,330 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/exponents +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Identifier + identifier: num + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Number + text: "1e5" + trailing_trivia: + - start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 16 + line: 2 + character: 1 + end_position: + bytes: 21 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 21 + line: 2 + character: 6 + end_position: + bytes: 22 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 22 + line: 2 + character: 7 + end_position: + bytes: 26 + line: 2 + character: 11 + token_type: + type: Identifier + identifier: num2 + trailing_trivia: + - start_position: + bytes: 26 + line: 2 + character: 11 + end_position: + bytes: 27 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 27 + line: 2 + character: 12 + end_position: + bytes: 28 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 28 + line: 2 + character: 13 + end_position: + bytes: 29 + line: 2 + character: 14 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 29 + line: 2 + character: 14 + end_position: + bytes: 33 + line: 2 + character: 18 + token_type: + type: Number + text: "1e-5" + trailing_trivia: + - start_position: + bytes: 33 + line: 2 + character: 18 + end_position: + bytes: 34 + line: 2 + character: 18 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 34 + line: 3 + character: 1 + end_position: + bytes: 39 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 39 + line: 3 + character: 6 + end_position: + bytes: 40 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 40 + line: 3 + character: 7 + end_position: + bytes: 44 + line: 3 + character: 11 + token_type: + type: Identifier + identifier: num3 + trailing_trivia: + - start_position: + bytes: 44 + line: 3 + character: 11 + end_position: + bytes: 45 + line: 3 + character: 12 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 45 + line: 3 + character: 12 + end_position: + bytes: 46 + line: 3 + character: 13 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 46 + line: 3 + character: 13 + end_position: + bytes: 47 + line: 3 + character: 14 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 47 + line: 3 + character: 14 + end_position: + bytes: 51 + line: 3 + character: 18 + token_type: + type: Number + text: "1e+5" + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/exponents/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/exponents/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..c4300642107175b907dda77053c70174e40a9cc1 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/exponents/source.lua @@ -0,0 +1,3 @@ +local num = 1e5 +local num2 = 1e-5 +local num3 = 1e+5 \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/exponents/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/exponents/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..f1489769e7a66dc9485d8f666f17512840e0f0c2 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/exponents/tokens.snap @@ -0,0 +1,270 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/exponents + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Identifier + identifier: num +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Number + text: "1e5" +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 16 + line: 2 + character: 1 + end_position: + bytes: 21 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 21 + line: 2 + character: 6 + end_position: + bytes: 22 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 22 + line: 2 + character: 7 + end_position: + bytes: 26 + line: 2 + character: 11 + token_type: + type: Identifier + identifier: num2 +- start_position: + bytes: 26 + line: 2 + character: 11 + end_position: + bytes: 27 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 27 + line: 2 + character: 12 + end_position: + bytes: 28 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 28 + line: 2 + character: 13 + end_position: + bytes: 29 + line: 2 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 29 + line: 2 + character: 14 + end_position: + bytes: 33 + line: 2 + character: 18 + token_type: + type: Number + text: "1e-5" +- start_position: + bytes: 33 + line: 2 + character: 18 + end_position: + bytes: 34 + line: 2 + character: 18 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 34 + line: 3 + character: 1 + end_position: + bytes: 39 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 39 + line: 3 + character: 6 + end_position: + bytes: 40 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 40 + line: 3 + character: 7 + end_position: + bytes: 44 + line: 3 + character: 11 + token_type: + type: Identifier + identifier: num3 +- start_position: + bytes: 44 + line: 3 + character: 11 + end_position: + bytes: 45 + line: 3 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 45 + line: 3 + character: 12 + end_position: + bytes: 46 + line: 3 + character: 13 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 46 + line: 3 + character: 13 + end_position: + bytes: 47 + line: 3 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 47 + line: 3 + character: 14 + end_position: + bytes: 51 + line: 3 + character: 18 + token_type: + type: Number + text: "1e+5" +- start_position: + bytes: 51 + line: 3 + character: 18 + end_position: + bytes: 51 + line: 3 + character: 18 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/fractional-numbers/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/fractional-numbers/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..01570051e5c78df39bed155cdd0844324f8ec07f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/fractional-numbers/ast.snap @@ -0,0 +1,563 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/fractional-numbers +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Identifier + identifier: num + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Number + text: "0.5" + trailing_trivia: + - start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 16 + line: 2 + character: 1 + end_position: + bytes: 21 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 21 + line: 2 + character: 6 + end_position: + bytes: 22 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 22 + line: 2 + character: 7 + end_position: + bytes: 26 + line: 2 + character: 11 + token_type: + type: Identifier + identifier: num2 + trailing_trivia: + - start_position: + bytes: 26 + line: 2 + character: 11 + end_position: + bytes: 27 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 27 + line: 2 + character: 12 + end_position: + bytes: 28 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 28 + line: 2 + character: 13 + end_position: + bytes: 29 + line: 2 + character: 14 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 29 + line: 2 + character: 14 + end_position: + bytes: 34 + line: 2 + character: 19 + token_type: + type: Number + text: "0.5e5" + trailing_trivia: + - start_position: + bytes: 34 + line: 2 + character: 19 + end_position: + bytes: 35 + line: 2 + character: 19 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 35 + line: 3 + character: 1 + end_position: + bytes: 40 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 40 + line: 3 + character: 6 + end_position: + bytes: 41 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 41 + line: 3 + character: 7 + end_position: + bytes: 45 + line: 3 + character: 11 + token_type: + type: Identifier + identifier: num3 + trailing_trivia: + - start_position: + bytes: 45 + line: 3 + character: 11 + end_position: + bytes: 46 + line: 3 + character: 12 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 46 + line: 3 + character: 12 + end_position: + bytes: 47 + line: 3 + character: 13 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 47 + line: 3 + character: 13 + end_position: + bytes: 48 + line: 3 + character: 14 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 48 + line: 3 + character: 14 + end_position: + bytes: 50 + line: 3 + character: 16 + token_type: + type: Number + text: ".5" + trailing_trivia: + - start_position: + bytes: 50 + line: 3 + character: 16 + end_position: + bytes: 51 + line: 3 + character: 16 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 51 + line: 4 + character: 1 + end_position: + bytes: 56 + line: 4 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 56 + line: 4 + character: 6 + end_position: + bytes: 57 + line: 4 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 57 + line: 4 + character: 7 + end_position: + bytes: 61 + line: 4 + character: 11 + token_type: + type: Identifier + identifier: num4 + trailing_trivia: + - start_position: + bytes: 61 + line: 4 + character: 11 + end_position: + bytes: 62 + line: 4 + character: 12 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 62 + line: 4 + character: 12 + end_position: + bytes: 63 + line: 4 + character: 13 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 63 + line: 4 + character: 13 + end_position: + bytes: 64 + line: 4 + character: 14 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 64 + line: 4 + character: 14 + end_position: + bytes: 68 + line: 4 + character: 18 + token_type: + type: Number + text: ".5e5" + trailing_trivia: + - start_position: + bytes: 68 + line: 4 + character: 18 + end_position: + bytes: 69 + line: 4 + character: 18 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 69 + line: 5 + character: 1 + end_position: + bytes: 74 + line: 5 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 74 + line: 5 + character: 6 + end_position: + bytes: 75 + line: 5 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 75 + line: 5 + character: 7 + end_position: + bytes: 79 + line: 5 + character: 11 + token_type: + type: Identifier + identifier: num5 + trailing_trivia: + - start_position: + bytes: 79 + line: 5 + character: 11 + end_position: + bytes: 80 + line: 5 + character: 12 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 80 + line: 5 + character: 12 + end_position: + bytes: 81 + line: 5 + character: 13 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 81 + line: 5 + character: 13 + end_position: + bytes: 82 + line: 5 + character: 14 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 82 + line: 5 + character: 14 + end_position: + bytes: 84 + line: 5 + character: 16 + token_type: + type: Number + text: "1." + trailing_trivia: + - start_position: + bytes: 84 + line: 5 + character: 16 + end_position: + bytes: 85 + line: 5 + character: 16 + token_type: + type: Whitespace + characters: "\n" + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/fractional-numbers/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/fractional-numbers/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..2b7574609527e43175ae0615aa8b076fafd2cc87 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/fractional-numbers/source.lua @@ -0,0 +1,5 @@ +local num = 0.5 +local num2 = 0.5e5 +local num3 = .5 +local num4 = .5e5 +local num5 = 1. diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/fractional-numbers/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/fractional-numbers/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..dffd1e4875390b4e7ee4b7997474bd14682cd334 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/fractional-numbers/tokens.snap @@ -0,0 +1,457 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/fractional-numbers + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Identifier + identifier: num +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Number + text: "0.5" +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 16 + line: 2 + character: 1 + end_position: + bytes: 21 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 21 + line: 2 + character: 6 + end_position: + bytes: 22 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 22 + line: 2 + character: 7 + end_position: + bytes: 26 + line: 2 + character: 11 + token_type: + type: Identifier + identifier: num2 +- start_position: + bytes: 26 + line: 2 + character: 11 + end_position: + bytes: 27 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 27 + line: 2 + character: 12 + end_position: + bytes: 28 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 28 + line: 2 + character: 13 + end_position: + bytes: 29 + line: 2 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 29 + line: 2 + character: 14 + end_position: + bytes: 34 + line: 2 + character: 19 + token_type: + type: Number + text: "0.5e5" +- start_position: + bytes: 34 + line: 2 + character: 19 + end_position: + bytes: 35 + line: 2 + character: 19 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 35 + line: 3 + character: 1 + end_position: + bytes: 40 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 40 + line: 3 + character: 6 + end_position: + bytes: 41 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 41 + line: 3 + character: 7 + end_position: + bytes: 45 + line: 3 + character: 11 + token_type: + type: Identifier + identifier: num3 +- start_position: + bytes: 45 + line: 3 + character: 11 + end_position: + bytes: 46 + line: 3 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 46 + line: 3 + character: 12 + end_position: + bytes: 47 + line: 3 + character: 13 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 47 + line: 3 + character: 13 + end_position: + bytes: 48 + line: 3 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 48 + line: 3 + character: 14 + end_position: + bytes: 50 + line: 3 + character: 16 + token_type: + type: Number + text: ".5" +- start_position: + bytes: 50 + line: 3 + character: 16 + end_position: + bytes: 51 + line: 3 + character: 16 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 51 + line: 4 + character: 1 + end_position: + bytes: 56 + line: 4 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 56 + line: 4 + character: 6 + end_position: + bytes: 57 + line: 4 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 57 + line: 4 + character: 7 + end_position: + bytes: 61 + line: 4 + character: 11 + token_type: + type: Identifier + identifier: num4 +- start_position: + bytes: 61 + line: 4 + character: 11 + end_position: + bytes: 62 + line: 4 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 62 + line: 4 + character: 12 + end_position: + bytes: 63 + line: 4 + character: 13 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 63 + line: 4 + character: 13 + end_position: + bytes: 64 + line: 4 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 64 + line: 4 + character: 14 + end_position: + bytes: 68 + line: 4 + character: 18 + token_type: + type: Number + text: ".5e5" +- start_position: + bytes: 68 + line: 4 + character: 18 + end_position: + bytes: 69 + line: 4 + character: 18 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 69 + line: 5 + character: 1 + end_position: + bytes: 74 + line: 5 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 74 + line: 5 + character: 6 + end_position: + bytes: 75 + line: 5 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 75 + line: 5 + character: 7 + end_position: + bytes: 79 + line: 5 + character: 11 + token_type: + type: Identifier + identifier: num5 +- start_position: + bytes: 79 + line: 5 + character: 11 + end_position: + bytes: 80 + line: 5 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 80 + line: 5 + character: 12 + end_position: + bytes: 81 + line: 5 + character: 13 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 81 + line: 5 + character: 13 + end_position: + bytes: 82 + line: 5 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 82 + line: 5 + character: 14 + end_position: + bytes: 84 + line: 5 + character: 16 + token_type: + type: Number + text: "1." +- start_position: + bytes: 84 + line: 5 + character: 16 + end_position: + bytes: 85 + line: 5 + character: 16 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 85 + line: 6 + character: 1 + end_position: + bytes: 85 + line: 6 + character: 1 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/function-declaration-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/function-declaration-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..5a8d4935473be5e07202ab087827ade3dcb09d0b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/function-declaration-1/ast.snap @@ -0,0 +1,192 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/function-declaration-1 + +--- +stmts: + - - FunctionDeclaration: + function_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: function + trailing_trivia: + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " + name: + names: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Identifier + identifier: x + trailing_trivia: [] + colon_name: ~ + body: + parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: "\n" + parameters: + pairs: [] + block: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 13 + line: 2 + character: 1 + end_position: + bytes: 14 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 14 + line: 2 + character: 2 + end_position: + bytes: 18 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 18 + line: 2 + character: 6 + end_position: + bytes: 19 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 19 + line: 2 + character: 7 + end_position: + bytes: 20 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 20 + line: 2 + character: 8 + end_position: + bytes: 21 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: [] + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 21 + line: 3 + character: 1 + end_position: + bytes: 24 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/function-declaration-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/function-declaration-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..a74feae4462f3510912990048f98f24b6210e5fa --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/function-declaration-1/source.lua @@ -0,0 +1,3 @@ +function x() + call() +end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/function-declaration-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/function-declaration-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..7527c1627e223d14629a4cabfb1dbb95fcb22a3a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/function-declaration-1/tokens.snap @@ -0,0 +1,149 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/function-declaration-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 13 + line: 2 + character: 1 + end_position: + bytes: 14 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 14 + line: 2 + character: 2 + end_position: + bytes: 18 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 18 + line: 2 + character: 6 + end_position: + bytes: 19 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 19 + line: 2 + character: 7 + end_position: + bytes: 20 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 20 + line: 2 + character: 8 + end_position: + bytes: 21 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 21 + line: 3 + character: 1 + end_position: + bytes: 24 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 24 + line: 3 + character: 4 + end_position: + bytes: 24 + line: 3 + character: 4 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/function-declaration-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/function-declaration-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..a3faef376476e98fd37733d50a6b51f50f6d0558 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/function-declaration-2/ast.snap @@ -0,0 +1,173 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/function-declaration-2 + +--- +stmts: + - - FunctionDeclaration: + function_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: function + trailing_trivia: + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " + name: + names: + pairs: + - Punctuated: + - leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Identifier + identifier: x + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + - End: + leading_trivia: [] + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Identifier + identifier: y + trailing_trivia: [] + colon_name: + - leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Identifier + identifier: z + trailing_trivia: [] + body: + parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Whitespace + characters: " " + parameters: + pairs: [] + block: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/function-declaration-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/function-declaration-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..b5b1dbc6707d6b4ffdb8c1589f1082e2606be175 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/function-declaration-2/source.lua @@ -0,0 +1 @@ +function x.y:z() end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/function-declaration-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/function-declaration-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..3b0d54490b3c851e2d92ffc33e68d98e7b44eee2 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/function-declaration-2/tokens.snap @@ -0,0 +1,138 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/function-declaration-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Identifier + identifier: z +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/function-shortcuts/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/function-shortcuts/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..07f5908d352dc8ab72e28973f8c021f90da6d5a7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/function-shortcuts/ast.snap @@ -0,0 +1,224 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/function-shortcuts +--- +stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: call + trailing_trivia: + - start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " + suffixes: + - Call: + AnonymousCall: + TableConstructor: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + - leading_trivia: [] + token: + start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: + - start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: "\n" + fields: + pairs: + - End: + NameKey: + key: + leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " + equal: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " + value: + Number: + leading_trivia: [] + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Whitespace + characters: " " + - ~ + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 15 + line: 2 + character: 1 + end_position: + bytes: 19 + line: 2 + character: 5 + token_type: + type: Identifier + identifier: call + trailing_trivia: + - start_position: + bytes: 19 + line: 2 + character: 5 + end_position: + bytes: 20 + line: 2 + character: 6 + token_type: + type: Whitespace + characters: " " + suffixes: + - Call: + AnonymousCall: + String: + leading_trivia: [] + token: + start_position: + bytes: 20 + line: 2 + character: 6 + end_position: + bytes: 27 + line: 2 + character: 13 + token_type: + type: StringLiteral + literal: hello + quote_type: Double + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/function-shortcuts/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/function-shortcuts/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..a41c8959f5ad3665143f5bd73920d3186ad4531b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/function-shortcuts/source.lua @@ -0,0 +1,2 @@ +call { x = 1 } +call "hello" \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/function-shortcuts/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/function-shortcuts/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..12032a0a36542d4aabf7a4ac610248ebac8ba459 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/function-shortcuts/tokens.snap @@ -0,0 +1,183 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/function-shortcuts + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Number + text: "1" +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 15 + line: 2 + character: 1 + end_position: + bytes: 19 + line: 2 + character: 5 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 19 + line: 2 + character: 5 + end_position: + bytes: 20 + line: 2 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 20 + line: 2 + character: 6 + end_position: + bytes: 27 + line: 2 + character: 13 + token_type: + type: StringLiteral + literal: hello + quote_type: Double +- start_position: + bytes: 27 + line: 2 + character: 13 + end_position: + bytes: 27 + line: 2 + character: 13 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/generic-for-loop-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/generic-for-loop-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..0a09d51f51d6572386c5627605f40df3ff11b2ba --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/generic-for-loop-1/ast.snap @@ -0,0 +1,392 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/generic-for-loop-1 +--- +stmts: + - - GenericFor: + for_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: for + trailing_trivia: + - start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " + names: + pairs: + - Punctuated: + - leading_trivia: [] + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Identifier + identifier: index + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " + - End: + leading_trivia: [] + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Identifier + identifier: value + trailing_trivia: + - start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Whitespace + characters: " " + in_token: + leading_trivia: [] + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: in + trailing_trivia: + - start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Identifier + identifier: pairs + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 26 + line: 1 + character: 27 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 30 + line: 1 + character: 31 + end_position: + bytes: 31 + line: 1 + character: 32 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 31 + line: 1 + character: 32 + end_position: + bytes: 32 + line: 1 + character: 33 + token_type: + type: Whitespace + characters: " " + arguments: + pairs: + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 26 + line: 1 + character: 27 + end_position: + bytes: 30 + line: 1 + character: 31 + token_type: + type: Identifier + identifier: list + trailing_trivia: [] + do_token: + leading_trivia: [] + token: + start_position: + bytes: 32 + line: 1 + character: 33 + end_position: + bytes: 34 + line: 1 + character: 35 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 34 + line: 1 + character: 35 + end_position: + bytes: 35 + line: 1 + character: 35 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 35 + line: 2 + character: 1 + end_position: + bytes: 36 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 36 + line: 2 + character: 2 + end_position: + bytes: 40 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 40 + line: 2 + character: 6 + end_position: + bytes: 41 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 53 + line: 2 + character: 19 + end_position: + bytes: 54 + line: 2 + character: 20 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 54 + line: 2 + character: 20 + end_position: + bytes: 55 + line: 2 + character: 20 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - Punctuated: + - Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 41 + line: 2 + character: 7 + end_position: + bytes: 46 + line: 2 + character: 12 + token_type: + type: Identifier + identifier: index + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 46 + line: 2 + character: 12 + end_position: + bytes: 47 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 47 + line: 2 + character: 13 + end_position: + bytes: 48 + line: 2 + character: 14 + token_type: + type: Whitespace + characters: " " + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 48 + line: 2 + character: 14 + end_position: + bytes: 53 + line: 2 + character: 19 + token_type: + type: Identifier + identifier: value + trailing_trivia: [] + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 55 + line: 3 + character: 1 + end_position: + bytes: 58 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/generic-for-loop-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/generic-for-loop-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..2838ff25df97b1b8b6d9c5c3e88e3851f8d0c542 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/generic-for-loop-1/source.lua @@ -0,0 +1,3 @@ +for index, value in pairs(list) do + call(index, value) +end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/generic-for-loop-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/generic-for-loop-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..28a515bace1226528ebf9a93de7acbc1c0cf3eb3 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/generic-for-loop-1/tokens.snap @@ -0,0 +1,303 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/generic-for-loop-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: for +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Identifier + identifier: index +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Identifier + identifier: value +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: in +- start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Identifier + identifier: pairs +- start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 26 + line: 1 + character: 27 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 26 + line: 1 + character: 27 + end_position: + bytes: 30 + line: 1 + character: 31 + token_type: + type: Identifier + identifier: list +- start_position: + bytes: 30 + line: 1 + character: 31 + end_position: + bytes: 31 + line: 1 + character: 32 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 31 + line: 1 + character: 32 + end_position: + bytes: 32 + line: 1 + character: 33 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 32 + line: 1 + character: 33 + end_position: + bytes: 34 + line: 1 + character: 35 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 34 + line: 1 + character: 35 + end_position: + bytes: 35 + line: 1 + character: 35 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 35 + line: 2 + character: 1 + end_position: + bytes: 36 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 36 + line: 2 + character: 2 + end_position: + bytes: 40 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 40 + line: 2 + character: 6 + end_position: + bytes: 41 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 41 + line: 2 + character: 7 + end_position: + bytes: 46 + line: 2 + character: 12 + token_type: + type: Identifier + identifier: index +- start_position: + bytes: 46 + line: 2 + character: 12 + end_position: + bytes: 47 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 47 + line: 2 + character: 13 + end_position: + bytes: 48 + line: 2 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 48 + line: 2 + character: 14 + end_position: + bytes: 53 + line: 2 + character: 19 + token_type: + type: Identifier + identifier: value +- start_position: + bytes: 53 + line: 2 + character: 19 + end_position: + bytes: 54 + line: 2 + character: 20 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 54 + line: 2 + character: 20 + end_position: + bytes: 55 + line: 2 + character: 20 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 55 + line: 3 + character: 1 + end_position: + bytes: 58 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 58 + line: 3 + character: 4 + end_position: + bytes: 58 + line: 3 + character: 4 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/generic-for-loop-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/generic-for-loop-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..5f58a2c809aa9f3006134b24335d3cf0734a803e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/generic-for-loop-2/ast.snap @@ -0,0 +1,380 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/generic-for-loop-2 +--- +stmts: + - - GenericFor: + for_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: for + trailing_trivia: + - start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " + names: + pairs: + - Punctuated: + - leading_trivia: [] + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Identifier + identifier: index + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " + - End: + leading_trivia: [] + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Identifier + identifier: value + trailing_trivia: + - start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Whitespace + characters: " " + in_token: + leading_trivia: [] + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: in + trailing_trivia: + - start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - Punctuated: + - Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 24 + line: 1 + character: 25 + token_type: + type: Identifier + identifier: next + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 24 + line: 1 + character: 25 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 26 + line: 1 + character: 27 + token_type: + type: Whitespace + characters: " " + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 26 + line: 1 + character: 27 + end_position: + bytes: 30 + line: 1 + character: 31 + token_type: + type: Identifier + identifier: list + trailing_trivia: + - start_position: + bytes: 30 + line: 1 + character: 31 + end_position: + bytes: 31 + line: 1 + character: 32 + token_type: + type: Whitespace + characters: " " + do_token: + leading_trivia: [] + token: + start_position: + bytes: 31 + line: 1 + character: 32 + end_position: + bytes: 33 + line: 1 + character: 34 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 33 + line: 1 + character: 34 + end_position: + bytes: 34 + line: 1 + character: 34 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 34 + line: 2 + character: 1 + end_position: + bytes: 35 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 35 + line: 2 + character: 2 + end_position: + bytes: 39 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 39 + line: 2 + character: 6 + end_position: + bytes: 40 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 52 + line: 2 + character: 19 + end_position: + bytes: 53 + line: 2 + character: 20 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 53 + line: 2 + character: 20 + end_position: + bytes: 54 + line: 2 + character: 20 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - Punctuated: + - Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 40 + line: 2 + character: 7 + end_position: + bytes: 45 + line: 2 + character: 12 + token_type: + type: Identifier + identifier: index + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 45 + line: 2 + character: 12 + end_position: + bytes: 46 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 46 + line: 2 + character: 13 + end_position: + bytes: 47 + line: 2 + character: 14 + token_type: + type: Whitespace + characters: " " + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 47 + line: 2 + character: 14 + end_position: + bytes: 52 + line: 2 + character: 19 + token_type: + type: Identifier + identifier: value + trailing_trivia: [] + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 54 + line: 3 + character: 1 + end_position: + bytes: 57 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/generic-for-loop-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/generic-for-loop-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..2ddbbb6a02921f691ca17e9ec948a499005895d9 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/generic-for-loop-2/source.lua @@ -0,0 +1,3 @@ +for index, value in next, list do + call(index, value) +end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/generic-for-loop-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/generic-for-loop-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..9e07f1b1437586c592bc6f0d492da30d95941b76 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/generic-for-loop-2/tokens.snap @@ -0,0 +1,303 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/generic-for-loop-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: for +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Identifier + identifier: index +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Identifier + identifier: value +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: in +- start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 24 + line: 1 + character: 25 + token_type: + type: Identifier + identifier: next +- start_position: + bytes: 24 + line: 1 + character: 25 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 26 + line: 1 + character: 27 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 26 + line: 1 + character: 27 + end_position: + bytes: 30 + line: 1 + character: 31 + token_type: + type: Identifier + identifier: list +- start_position: + bytes: 30 + line: 1 + character: 31 + end_position: + bytes: 31 + line: 1 + character: 32 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 31 + line: 1 + character: 32 + end_position: + bytes: 33 + line: 1 + character: 34 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 33 + line: 1 + character: 34 + end_position: + bytes: 34 + line: 1 + character: 34 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 34 + line: 2 + character: 1 + end_position: + bytes: 35 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 35 + line: 2 + character: 2 + end_position: + bytes: 39 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 39 + line: 2 + character: 6 + end_position: + bytes: 40 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 40 + line: 2 + character: 7 + end_position: + bytes: 45 + line: 2 + character: 12 + token_type: + type: Identifier + identifier: index +- start_position: + bytes: 45 + line: 2 + character: 12 + end_position: + bytes: 46 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 46 + line: 2 + character: 13 + end_position: + bytes: 47 + line: 2 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 47 + line: 2 + character: 14 + end_position: + bytes: 52 + line: 2 + character: 19 + token_type: + type: Identifier + identifier: value +- start_position: + bytes: 52 + line: 2 + character: 19 + end_position: + bytes: 53 + line: 2 + character: 20 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 53 + line: 2 + character: 20 + end_position: + bytes: 54 + line: 2 + character: 20 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 54 + line: 3 + character: 1 + end_position: + bytes: 57 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 57 + line: 3 + character: 4 + end_position: + bytes: 57 + line: 3 + character: 4 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/goto-as-identifier/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/goto-as-identifier/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..59278e6044173812e88588dc5bed1ba54abae926 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/goto-as-identifier/ast.snap @@ -0,0 +1,133 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/goto-as-identifier +--- +stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 48 + line: 1 + character: 49 + token_type: + type: SingleLineComment + comment: " goto as an identifier is permitted in lua 5.1" + - start_position: + bytes: 48 + line: 1 + character: 49 + end_position: + bytes: 49 + line: 1 + character: 49 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 49 + line: 2 + character: 1 + end_position: + bytes: 53 + line: 2 + character: 5 + token_type: + type: Identifier + identifier: self + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 53 + line: 2 + character: 5 + end_position: + bytes: 54 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 54 + line: 2 + character: 6 + end_position: + bytes: 58 + line: 2 + character: 10 + token_type: + type: Identifier + identifier: goto + trailing_trivia: [] + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 58 + line: 2 + character: 10 + end_position: + bytes: 59 + line: 2 + character: 11 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 64 + line: 2 + character: 16 + end_position: + bytes: 65 + line: 2 + character: 17 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 59 + line: 2 + character: 11 + end_position: + bytes: 64 + line: 2 + character: 16 + token_type: + type: StringLiteral + literal: foo + quote_type: Double + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/goto-as-identifier/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/goto-as-identifier/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..4a6afecf5b602012e68e4fdbd72340eca7334f1e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/goto-as-identifier/source.lua @@ -0,0 +1,2 @@ +-- goto as an identifier is permitted in lua 5.1 +self.goto("foo") \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/goto-as-identifier/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/goto-as-identifier/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..793591ea2a192dba63cc58cf45d493afbb39c1fb --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/goto-as-identifier/tokens.snap @@ -0,0 +1,105 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 48 + line: 1 + character: 49 + token_type: + type: SingleLineComment + comment: " goto as an identifier is permitted in lua 5.1" +- start_position: + bytes: 48 + line: 1 + character: 49 + end_position: + bytes: 49 + line: 1 + character: 49 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 49 + line: 2 + character: 1 + end_position: + bytes: 53 + line: 2 + character: 5 + token_type: + type: Identifier + identifier: self +- start_position: + bytes: 53 + line: 2 + character: 5 + end_position: + bytes: 54 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 54 + line: 2 + character: 6 + end_position: + bytes: 58 + line: 2 + character: 10 + token_type: + type: Identifier + identifier: goto +- start_position: + bytes: 58 + line: 2 + character: 10 + end_position: + bytes: 59 + line: 2 + character: 11 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 59 + line: 2 + character: 11 + end_position: + bytes: 64 + line: 2 + character: 16 + token_type: + type: StringLiteral + literal: foo + quote_type: Double +- start_position: + bytes: 64 + line: 2 + character: 16 + end_position: + bytes: 65 + line: 2 + character: 17 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 65 + line: 2 + character: 17 + end_position: + bytes: 65 + line: 2 + character: 17 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/gt-lt/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/gt-lt/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..c93c7d18aef1473d521c16e5ec7a2b4c7ceafd59 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/gt-lt/ast.snap @@ -0,0 +1,684 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/gt-lt +--- +stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - End: + BinaryOperator: + lhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + binop: + LessThan: + leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "<" + trailing_trivia: + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Number + text: "2" + trailing_trivia: [] + - ~ + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 2 + character: 1 + end_position: + bytes: 16 + line: 2 + character: 5 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 16 + line: 2 + character: 5 + end_position: + bytes: 17 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 23 + line: 2 + character: 12 + end_position: + bytes: 24 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 24 + line: 2 + character: 13 + end_position: + bytes: 25 + line: 2 + character: 13 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - End: + BinaryOperator: + lhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 17 + line: 2 + character: 6 + end_position: + bytes: 18 + line: 2 + character: 7 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 18 + line: 2 + character: 7 + end_position: + bytes: 19 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: " " + binop: + LessThanEqual: + leading_trivia: [] + token: + start_position: + bytes: 19 + line: 2 + character: 8 + end_position: + bytes: 21 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: "<=" + trailing_trivia: + - start_position: + bytes: 21 + line: 2 + character: 10 + end_position: + bytes: 22 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 22 + line: 2 + character: 11 + end_position: + bytes: 23 + line: 2 + character: 12 + token_type: + type: Number + text: "2" + trailing_trivia: [] + - ~ + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 25 + line: 3 + character: 1 + end_position: + bytes: 29 + line: 3 + character: 5 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 29 + line: 3 + character: 5 + end_position: + bytes: 30 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 35 + line: 3 + character: 11 + end_position: + bytes: 36 + line: 3 + character: 12 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 36 + line: 3 + character: 12 + end_position: + bytes: 37 + line: 3 + character: 12 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - End: + BinaryOperator: + lhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 30 + line: 3 + character: 6 + end_position: + bytes: 31 + line: 3 + character: 7 + token_type: + type: Number + text: "2" + trailing_trivia: + - start_position: + bytes: 31 + line: 3 + character: 7 + end_position: + bytes: 32 + line: 3 + character: 8 + token_type: + type: Whitespace + characters: " " + binop: + GreaterThan: + leading_trivia: [] + token: + start_position: + bytes: 32 + line: 3 + character: 8 + end_position: + bytes: 33 + line: 3 + character: 9 + token_type: + type: Symbol + symbol: ">" + trailing_trivia: + - start_position: + bytes: 33 + line: 3 + character: 9 + end_position: + bytes: 34 + line: 3 + character: 10 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 34 + line: 3 + character: 10 + end_position: + bytes: 35 + line: 3 + character: 11 + token_type: + type: Number + text: "1" + trailing_trivia: [] + - ~ + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 37 + line: 4 + character: 1 + end_position: + bytes: 41 + line: 4 + character: 5 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 41 + line: 4 + character: 5 + end_position: + bytes: 42 + line: 4 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 48 + line: 4 + character: 12 + end_position: + bytes: 49 + line: 4 + character: 13 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 49 + line: 4 + character: 13 + end_position: + bytes: 50 + line: 4 + character: 13 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - End: + BinaryOperator: + lhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 42 + line: 4 + character: 6 + end_position: + bytes: 43 + line: 4 + character: 7 + token_type: + type: Number + text: "2" + trailing_trivia: + - start_position: + bytes: 43 + line: 4 + character: 7 + end_position: + bytes: 44 + line: 4 + character: 8 + token_type: + type: Whitespace + characters: " " + binop: + GreaterThanEqual: + leading_trivia: [] + token: + start_position: + bytes: 44 + line: 4 + character: 8 + end_position: + bytes: 46 + line: 4 + character: 10 + token_type: + type: Symbol + symbol: ">=" + trailing_trivia: + - start_position: + bytes: 46 + line: 4 + character: 10 + end_position: + bytes: 47 + line: 4 + character: 11 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 47 + line: 4 + character: 11 + end_position: + bytes: 48 + line: 4 + character: 12 + token_type: + type: Number + text: "1" + trailing_trivia: [] + - ~ + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 50 + line: 5 + character: 1 + end_position: + bytes: 54 + line: 5 + character: 5 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 54 + line: 5 + character: 5 + end_position: + bytes: 55 + line: 5 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 61 + line: 5 + character: 12 + end_position: + bytes: 62 + line: 5 + character: 13 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: + - End: + BinaryOperator: + lhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 55 + line: 5 + character: 6 + end_position: + bytes: 56 + line: 5 + character: 7 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 56 + line: 5 + character: 7 + end_position: + bytes: 57 + line: 5 + character: 8 + token_type: + type: Whitespace + characters: " " + binop: + GreaterThanEqual: + leading_trivia: [] + token: + start_position: + bytes: 57 + line: 5 + character: 8 + end_position: + bytes: 59 + line: 5 + character: 10 + token_type: + type: Symbol + symbol: ">=" + trailing_trivia: + - start_position: + bytes: 59 + line: 5 + character: 10 + end_position: + bytes: 60 + line: 5 + character: 11 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 60 + line: 5 + character: 11 + end_position: + bytes: 61 + line: 5 + character: 12 + token_type: + type: Identifier + identifier: y + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/gt-lt/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/gt-lt/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..54e1cf52e4a0ea211f53a3cb0a4db37d9126c8e7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/gt-lt/source.lua @@ -0,0 +1,5 @@ +call(1 < 2) +call(1 <= 2) +call(2 > 1) +call(2 >= 1) +call(x >= y) \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/gt-lt/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/gt-lt/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..df669f6a1b7db2ad905fc915887f339ea4b979b7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/gt-lt/tokens.snap @@ -0,0 +1,501 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/gt-lt + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Number + text: "1" +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "<" +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Number + text: "2" +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 12 + line: 2 + character: 1 + end_position: + bytes: 16 + line: 2 + character: 5 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 16 + line: 2 + character: 5 + end_position: + bytes: 17 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 17 + line: 2 + character: 6 + end_position: + bytes: 18 + line: 2 + character: 7 + token_type: + type: Number + text: "1" +- start_position: + bytes: 18 + line: 2 + character: 7 + end_position: + bytes: 19 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 19 + line: 2 + character: 8 + end_position: + bytes: 21 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: "<=" +- start_position: + bytes: 21 + line: 2 + character: 10 + end_position: + bytes: 22 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 22 + line: 2 + character: 11 + end_position: + bytes: 23 + line: 2 + character: 12 + token_type: + type: Number + text: "2" +- start_position: + bytes: 23 + line: 2 + character: 12 + end_position: + bytes: 24 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 24 + line: 2 + character: 13 + end_position: + bytes: 25 + line: 2 + character: 13 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 25 + line: 3 + character: 1 + end_position: + bytes: 29 + line: 3 + character: 5 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 29 + line: 3 + character: 5 + end_position: + bytes: 30 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 30 + line: 3 + character: 6 + end_position: + bytes: 31 + line: 3 + character: 7 + token_type: + type: Number + text: "2" +- start_position: + bytes: 31 + line: 3 + character: 7 + end_position: + bytes: 32 + line: 3 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 32 + line: 3 + character: 8 + end_position: + bytes: 33 + line: 3 + character: 9 + token_type: + type: Symbol + symbol: ">" +- start_position: + bytes: 33 + line: 3 + character: 9 + end_position: + bytes: 34 + line: 3 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 34 + line: 3 + character: 10 + end_position: + bytes: 35 + line: 3 + character: 11 + token_type: + type: Number + text: "1" +- start_position: + bytes: 35 + line: 3 + character: 11 + end_position: + bytes: 36 + line: 3 + character: 12 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 36 + line: 3 + character: 12 + end_position: + bytes: 37 + line: 3 + character: 12 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 37 + line: 4 + character: 1 + end_position: + bytes: 41 + line: 4 + character: 5 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 41 + line: 4 + character: 5 + end_position: + bytes: 42 + line: 4 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 42 + line: 4 + character: 6 + end_position: + bytes: 43 + line: 4 + character: 7 + token_type: + type: Number + text: "2" +- start_position: + bytes: 43 + line: 4 + character: 7 + end_position: + bytes: 44 + line: 4 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 44 + line: 4 + character: 8 + end_position: + bytes: 46 + line: 4 + character: 10 + token_type: + type: Symbol + symbol: ">=" +- start_position: + bytes: 46 + line: 4 + character: 10 + end_position: + bytes: 47 + line: 4 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 47 + line: 4 + character: 11 + end_position: + bytes: 48 + line: 4 + character: 12 + token_type: + type: Number + text: "1" +- start_position: + bytes: 48 + line: 4 + character: 12 + end_position: + bytes: 49 + line: 4 + character: 13 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 49 + line: 4 + character: 13 + end_position: + bytes: 50 + line: 4 + character: 13 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 50 + line: 5 + character: 1 + end_position: + bytes: 54 + line: 5 + character: 5 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 54 + line: 5 + character: 5 + end_position: + bytes: 55 + line: 5 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 55 + line: 5 + character: 6 + end_position: + bytes: 56 + line: 5 + character: 7 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 56 + line: 5 + character: 7 + end_position: + bytes: 57 + line: 5 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 57 + line: 5 + character: 8 + end_position: + bytes: 59 + line: 5 + character: 10 + token_type: + type: Symbol + symbol: ">=" +- start_position: + bytes: 59 + line: 5 + character: 10 + end_position: + bytes: 60 + line: 5 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 60 + line: 5 + character: 11 + end_position: + bytes: 61 + line: 5 + character: 12 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 61 + line: 5 + character: 12 + end_position: + bytes: 62 + line: 5 + character: 13 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 62 + line: 5 + character: 13 + end_position: + bytes: 62 + line: 5 + character: 13 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/if-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/if-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..1102488e3477cdf9a51327ca6f0c17a54737ad7a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/if-1/ast.snap @@ -0,0 +1,186 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/if-1 +--- +stmts: + - - If: + if_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: if + trailing_trivia: + - start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Whitespace + characters: " " + condition: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 10 + line: 2 + character: 1 + end_position: + bytes: 11 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 11 + line: 2 + character: 2 + end_position: + bytes: 15 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 15 + line: 2 + character: 6 + end_position: + bytes: 16 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 16 + line: 2 + character: 7 + end_position: + bytes: 17 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 17 + line: 2 + character: 8 + end_position: + bytes: 18 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: [] + - ~ + else_if: ~ + else_token: ~ + else: ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 18 + line: 3 + character: 1 + end_position: + bytes: 21 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/if-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/if-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..9211c9664417b8cc4d085b38d9a26e604b335b63 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/if-1/source.lua @@ -0,0 +1,3 @@ +if x then + call() +end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/if-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/if-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..8b7f14767c5ba5847ecade7b4e61412f937deefa --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/if-1/tokens.snap @@ -0,0 +1,149 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/if-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: if +- start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 10 + line: 2 + character: 1 + end_position: + bytes: 11 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 11 + line: 2 + character: 2 + end_position: + bytes: 15 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 15 + line: 2 + character: 6 + end_position: + bytes: 16 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 16 + line: 2 + character: 7 + end_position: + bytes: 17 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 17 + line: 2 + character: 8 + end_position: + bytes: 18 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 18 + line: 3 + character: 1 + end_position: + bytes: 21 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 21 + line: 3 + character: 4 + end_position: + bytes: 21 + line: 3 + character: 4 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/if-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/if-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..c11da4fe5bb80246b69886b45c228bec03411f85 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/if-2/ast.snap @@ -0,0 +1,288 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/if-2 +--- +stmts: + - - If: + if_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: if + trailing_trivia: + - start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Whitespace + characters: " " + condition: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 10 + line: 2 + character: 1 + end_position: + bytes: 11 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 11 + line: 2 + character: 2 + end_position: + bytes: 14 + line: 2 + character: 5 + token_type: + type: Identifier + identifier: foo + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 14 + line: 2 + character: 5 + end_position: + bytes: 15 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 15 + line: 2 + character: 6 + end_position: + bytes: 16 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 16 + line: 2 + character: 7 + end_position: + bytes: 17 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: [] + - ~ + else_if: ~ + else_token: + leading_trivia: [] + token: + start_position: + bytes: 17 + line: 3 + character: 1 + end_position: + bytes: 21 + line: 3 + character: 5 + token_type: + type: Symbol + symbol: else + trailing_trivia: + - start_position: + bytes: 21 + line: 3 + character: 5 + end_position: + bytes: 22 + line: 3 + character: 5 + token_type: + type: Whitespace + characters: "\n" + else: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 22 + line: 4 + character: 1 + end_position: + bytes: 23 + line: 4 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 23 + line: 4 + character: 2 + end_position: + bytes: 26 + line: 4 + character: 5 + token_type: + type: Identifier + identifier: bar + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 26 + line: 4 + character: 5 + end_position: + bytes: 27 + line: 4 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 27 + line: 4 + character: 6 + end_position: + bytes: 28 + line: 4 + character: 7 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 28 + line: 4 + character: 7 + end_position: + bytes: 29 + line: 4 + character: 7 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: [] + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 29 + line: 5 + character: 1 + end_position: + bytes: 32 + line: 5 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/if-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/if-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..faf9ce59d2d86ce8971dd30060b2a2ab27039706 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/if-2/source.lua @@ -0,0 +1,5 @@ +if x then + foo() +else + bar() +end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/if-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/if-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..3824b1b932581dd28886efe70b017494be6514be --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/if-2/tokens.snap @@ -0,0 +1,226 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/if-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: if +- start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 10 + line: 2 + character: 1 + end_position: + bytes: 11 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 11 + line: 2 + character: 2 + end_position: + bytes: 14 + line: 2 + character: 5 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 14 + line: 2 + character: 5 + end_position: + bytes: 15 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 15 + line: 2 + character: 6 + end_position: + bytes: 16 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 16 + line: 2 + character: 7 + end_position: + bytes: 17 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 17 + line: 3 + character: 1 + end_position: + bytes: 21 + line: 3 + character: 5 + token_type: + type: Symbol + symbol: else +- start_position: + bytes: 21 + line: 3 + character: 5 + end_position: + bytes: 22 + line: 3 + character: 5 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 22 + line: 4 + character: 1 + end_position: + bytes: 23 + line: 4 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 23 + line: 4 + character: 2 + end_position: + bytes: 26 + line: 4 + character: 5 + token_type: + type: Identifier + identifier: bar +- start_position: + bytes: 26 + line: 4 + character: 5 + end_position: + bytes: 27 + line: 4 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 27 + line: 4 + character: 6 + end_position: + bytes: 28 + line: 4 + character: 7 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 28 + line: 4 + character: 7 + end_position: + bytes: 29 + line: 4 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 29 + line: 5 + character: 1 + end_position: + bytes: 32 + line: 5 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 32 + line: 5 + character: 4 + end_position: + bytes: 32 + line: 5 + character: 4 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/if-3/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/if-3/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..d439a602c19352968a559ed67222d6aab08a6f53 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/if-3/ast.snap @@ -0,0 +1,344 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/if-3 +--- +stmts: + - - If: + if_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: if + trailing_trivia: + - start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Whitespace + characters: " " + condition: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 10 + line: 2 + character: 1 + end_position: + bytes: 11 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 11 + line: 2 + character: 2 + end_position: + bytes: 14 + line: 2 + character: 5 + token_type: + type: Identifier + identifier: foo + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 14 + line: 2 + character: 5 + end_position: + bytes: 15 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 15 + line: 2 + character: 6 + end_position: + bytes: 16 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 16 + line: 2 + character: 7 + end_position: + bytes: 17 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: [] + - ~ + else_if: + - else_if_token: + leading_trivia: [] + token: + start_position: + bytes: 17 + line: 3 + character: 1 + end_position: + bytes: 23 + line: 3 + character: 7 + token_type: + type: Symbol + symbol: elseif + trailing_trivia: + - start_position: + bytes: 23 + line: 3 + character: 7 + end_position: + bytes: 24 + line: 3 + character: 8 + token_type: + type: Whitespace + characters: " " + condition: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 24 + line: 3 + character: 8 + end_position: + bytes: 25 + line: 3 + character: 9 + token_type: + type: Identifier + identifier: y + trailing_trivia: + - start_position: + bytes: 25 + line: 3 + character: 9 + end_position: + bytes: 26 + line: 3 + character: 10 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 26 + line: 3 + character: 10 + end_position: + bytes: 30 + line: 3 + character: 14 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 30 + line: 3 + character: 14 + end_position: + bytes: 31 + line: 3 + character: 14 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 31 + line: 4 + character: 1 + end_position: + bytes: 32 + line: 4 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 32 + line: 4 + character: 2 + end_position: + bytes: 35 + line: 4 + character: 5 + token_type: + type: Identifier + identifier: bar + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 35 + line: 4 + character: 5 + end_position: + bytes: 36 + line: 4 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 36 + line: 4 + character: 6 + end_position: + bytes: 37 + line: 4 + character: 7 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 37 + line: 4 + character: 7 + end_position: + bytes: 38 + line: 4 + character: 7 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: [] + - ~ + else_token: ~ + else: ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 38 + line: 5 + character: 1 + end_position: + bytes: 41 + line: 5 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/if-3/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/if-3/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..6dd9718d23dcc747242d6f639c1837af75378c20 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/if-3/source.lua @@ -0,0 +1,5 @@ +if x then + foo() +elseif y then + bar() +end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/if-3/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/if-3/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..0e16a5d780a5cc57439661f6e7ebec0e258b3970 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/if-3/tokens.snap @@ -0,0 +1,270 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/if-3 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: if +- start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 10 + line: 2 + character: 1 + end_position: + bytes: 11 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 11 + line: 2 + character: 2 + end_position: + bytes: 14 + line: 2 + character: 5 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 14 + line: 2 + character: 5 + end_position: + bytes: 15 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 15 + line: 2 + character: 6 + end_position: + bytes: 16 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 16 + line: 2 + character: 7 + end_position: + bytes: 17 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 17 + line: 3 + character: 1 + end_position: + bytes: 23 + line: 3 + character: 7 + token_type: + type: Symbol + symbol: elseif +- start_position: + bytes: 23 + line: 3 + character: 7 + end_position: + bytes: 24 + line: 3 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 24 + line: 3 + character: 8 + end_position: + bytes: 25 + line: 3 + character: 9 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 25 + line: 3 + character: 9 + end_position: + bytes: 26 + line: 3 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 26 + line: 3 + character: 10 + end_position: + bytes: 30 + line: 3 + character: 14 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 30 + line: 3 + character: 14 + end_position: + bytes: 31 + line: 3 + character: 14 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 31 + line: 4 + character: 1 + end_position: + bytes: 32 + line: 4 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 32 + line: 4 + character: 2 + end_position: + bytes: 35 + line: 4 + character: 5 + token_type: + type: Identifier + identifier: bar +- start_position: + bytes: 35 + line: 4 + character: 5 + end_position: + bytes: 36 + line: 4 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 36 + line: 4 + character: 6 + end_position: + bytes: 37 + line: 4 + character: 7 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 37 + line: 4 + character: 7 + end_position: + bytes: 38 + line: 4 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 38 + line: 5 + character: 1 + end_position: + bytes: 41 + line: 5 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 41 + line: 5 + character: 4 + end_position: + bytes: 41 + line: 5 + character: 4 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/if-4/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/if-4/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..8af517ba8db83c2c60104ad236c09ac484a705b0 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/if-4/ast.snap @@ -0,0 +1,446 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/if-4 +--- +stmts: + - - If: + if_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: if + trailing_trivia: + - start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Whitespace + characters: " " + condition: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 10 + line: 2 + character: 1 + end_position: + bytes: 11 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 11 + line: 2 + character: 2 + end_position: + bytes: 14 + line: 2 + character: 5 + token_type: + type: Identifier + identifier: foo + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 14 + line: 2 + character: 5 + end_position: + bytes: 15 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 15 + line: 2 + character: 6 + end_position: + bytes: 16 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 16 + line: 2 + character: 7 + end_position: + bytes: 17 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: [] + - ~ + else_if: + - else_if_token: + leading_trivia: [] + token: + start_position: + bytes: 17 + line: 3 + character: 1 + end_position: + bytes: 23 + line: 3 + character: 7 + token_type: + type: Symbol + symbol: elseif + trailing_trivia: + - start_position: + bytes: 23 + line: 3 + character: 7 + end_position: + bytes: 24 + line: 3 + character: 8 + token_type: + type: Whitespace + characters: " " + condition: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 24 + line: 3 + character: 8 + end_position: + bytes: 25 + line: 3 + character: 9 + token_type: + type: Identifier + identifier: y + trailing_trivia: + - start_position: + bytes: 25 + line: 3 + character: 9 + end_position: + bytes: 26 + line: 3 + character: 10 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 26 + line: 3 + character: 10 + end_position: + bytes: 30 + line: 3 + character: 14 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 30 + line: 3 + character: 14 + end_position: + bytes: 31 + line: 3 + character: 14 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 31 + line: 4 + character: 1 + end_position: + bytes: 32 + line: 4 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 32 + line: 4 + character: 2 + end_position: + bytes: 35 + line: 4 + character: 5 + token_type: + type: Identifier + identifier: bar + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 35 + line: 4 + character: 5 + end_position: + bytes: 36 + line: 4 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 36 + line: 4 + character: 6 + end_position: + bytes: 37 + line: 4 + character: 7 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 37 + line: 4 + character: 7 + end_position: + bytes: 38 + line: 4 + character: 7 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: [] + - ~ + else_token: + leading_trivia: [] + token: + start_position: + bytes: 38 + line: 5 + character: 1 + end_position: + bytes: 42 + line: 5 + character: 5 + token_type: + type: Symbol + symbol: else + trailing_trivia: + - start_position: + bytes: 42 + line: 5 + character: 5 + end_position: + bytes: 43 + line: 5 + character: 5 + token_type: + type: Whitespace + characters: "\n" + else: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 43 + line: 6 + character: 1 + end_position: + bytes: 44 + line: 6 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 44 + line: 6 + character: 2 + end_position: + bytes: 47 + line: 6 + character: 5 + token_type: + type: Identifier + identifier: baz + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 47 + line: 6 + character: 5 + end_position: + bytes: 48 + line: 6 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 48 + line: 6 + character: 6 + end_position: + bytes: 49 + line: 6 + character: 7 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 49 + line: 6 + character: 7 + end_position: + bytes: 50 + line: 6 + character: 7 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: [] + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 50 + line: 7 + character: 1 + end_position: + bytes: 53 + line: 7 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/if-4/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/if-4/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..f710ef9a1c0544667a0331f2adc94fcc6a86c539 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/if-4/source.lua @@ -0,0 +1,7 @@ +if x then + foo() +elseif y then + bar() +else + baz() +end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/if-4/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/if-4/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..daa96296acaa16eee118c52372ca538b482be865 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/if-4/tokens.snap @@ -0,0 +1,347 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/if-4 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: if +- start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 10 + line: 2 + character: 1 + end_position: + bytes: 11 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 11 + line: 2 + character: 2 + end_position: + bytes: 14 + line: 2 + character: 5 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 14 + line: 2 + character: 5 + end_position: + bytes: 15 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 15 + line: 2 + character: 6 + end_position: + bytes: 16 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 16 + line: 2 + character: 7 + end_position: + bytes: 17 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 17 + line: 3 + character: 1 + end_position: + bytes: 23 + line: 3 + character: 7 + token_type: + type: Symbol + symbol: elseif +- start_position: + bytes: 23 + line: 3 + character: 7 + end_position: + bytes: 24 + line: 3 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 24 + line: 3 + character: 8 + end_position: + bytes: 25 + line: 3 + character: 9 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 25 + line: 3 + character: 9 + end_position: + bytes: 26 + line: 3 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 26 + line: 3 + character: 10 + end_position: + bytes: 30 + line: 3 + character: 14 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 30 + line: 3 + character: 14 + end_position: + bytes: 31 + line: 3 + character: 14 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 31 + line: 4 + character: 1 + end_position: + bytes: 32 + line: 4 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 32 + line: 4 + character: 2 + end_position: + bytes: 35 + line: 4 + character: 5 + token_type: + type: Identifier + identifier: bar +- start_position: + bytes: 35 + line: 4 + character: 5 + end_position: + bytes: 36 + line: 4 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 36 + line: 4 + character: 6 + end_position: + bytes: 37 + line: 4 + character: 7 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 37 + line: 4 + character: 7 + end_position: + bytes: 38 + line: 4 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 38 + line: 5 + character: 1 + end_position: + bytes: 42 + line: 5 + character: 5 + token_type: + type: Symbol + symbol: else +- start_position: + bytes: 42 + line: 5 + character: 5 + end_position: + bytes: 43 + line: 5 + character: 5 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 43 + line: 6 + character: 1 + end_position: + bytes: 44 + line: 6 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 44 + line: 6 + character: 2 + end_position: + bytes: 47 + line: 6 + character: 5 + token_type: + type: Identifier + identifier: baz +- start_position: + bytes: 47 + line: 6 + character: 5 + end_position: + bytes: 48 + line: 6 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 48 + line: 6 + character: 6 + end_position: + bytes: 49 + line: 6 + character: 7 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 49 + line: 6 + character: 7 + end_position: + bytes: 50 + line: 6 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 50 + line: 7 + character: 1 + end_position: + bytes: 53 + line: 7 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 53 + line: 7 + character: 4 + end_position: + bytes: 53 + line: 7 + character: 4 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/index-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/index-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..80575bcd02dde824d124c356bc8e0cfd6765a4ab --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/index-1/ast.snap @@ -0,0 +1,176 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/index-1 +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Var: + Expression: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Identifier + identifier: a + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Identifier + identifier: b + trailing_trivia: [] + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Identifier + identifier: c + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/index-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/index-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..81c84820ca1cf81fd4f71ac4012b070f0ce945de --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/index-1/source.lua @@ -0,0 +1 @@ +local x = a.b.c \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/index-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/index-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..e077e506ae42f3f236efbe82cb2fafa1fb8a0499 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/index-1/tokens.snap @@ -0,0 +1,138 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/index-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Identifier + identifier: a +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Identifier + identifier: b +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Identifier + identifier: c +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/index-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/index-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..ec946cc34f20ee79ef25ddafdaadec5872070ae5 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/index-2/ast.snap @@ -0,0 +1,196 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/index-2 +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Var: + Expression: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: StringLiteral + literal: a + quote_type: Double + trailing_trivia: [] + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Identifier + identifier: b + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/index-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/index-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..1db46c3ba797399b80b98da9b29b6465a80b9ff4 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/index-2/source.lua @@ -0,0 +1 @@ +local x = call("a").b \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/index-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/index-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..fc7c3722a8db16be5ad12904ff388ab4bb90f461 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/index-2/tokens.snap @@ -0,0 +1,150 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/index-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: StringLiteral + literal: a + quote_type: Double +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Identifier + identifier: b +- start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..8c25f01a6457e25836701738f8756adaed37aea6 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-1/ast.snap @@ -0,0 +1,56 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/local-assignment-1 + +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: [] + equal_token: ~ + expr_list: + pairs: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..da0c326a0e960916b67031a1f397e6f00e685f76 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-1/source.lua @@ -0,0 +1 @@ +local x \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..770c65511db99e60fa407ea2a528527c0faf2e8d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-1/tokens.snap @@ -0,0 +1,50 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/local-assignment-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..fadcf3e2aa4ff1690a92ca0fa901661ae3147d09 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-2/ast.snap @@ -0,0 +1,108 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/local-assignment-2 +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Number + text: "1" + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..aa28c09f74d7dd7b5dd57bb5919c2c335043b776 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-2/source.lua @@ -0,0 +1 @@ +local x = 1 \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..7f0e22c0b0a94e2684f8ab2a86cfba5c2eab2486 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-2/tokens.snap @@ -0,0 +1,94 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/local-assignment-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Number + text: "1" +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-3/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-3/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..9f61423cb44bfede37fe7ce246a30e5da8dc4ce9 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-3/ast.snap @@ -0,0 +1,573 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/local-assignment-3 +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - Punctuated: + - leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: a + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " + - End: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Identifier + identifier: b + trailing_trivia: + - start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - Punctuated: + - Number: + leading_trivia: [] + token: + start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Number + text: "1" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Whitespace + characters: " " + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Number + text: "2" + trailing_trivia: + - start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 18 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 18 + line: 2 + character: 1 + end_position: + bytes: 23 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 23 + line: 2 + character: 6 + end_position: + bytes: 24 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - Punctuated: + - leading_trivia: [] + token: + start_position: + bytes: 24 + line: 2 + character: 7 + end_position: + bytes: 25 + line: 2 + character: 8 + token_type: + type: Identifier + identifier: c + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 25 + line: 2 + character: 8 + end_position: + bytes: 26 + line: 2 + character: 9 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 26 + line: 2 + character: 9 + end_position: + bytes: 27 + line: 2 + character: 10 + token_type: + type: Whitespace + characters: " " + - End: + leading_trivia: [] + token: + start_position: + bytes: 27 + line: 2 + character: 10 + end_position: + bytes: 28 + line: 2 + character: 11 + token_type: + type: Identifier + identifier: d + trailing_trivia: + - start_position: + bytes: 28 + line: 2 + character: 11 + end_position: + bytes: 29 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 29 + line: 2 + character: 12 + end_position: + bytes: 30 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 30 + line: 2 + character: 13 + end_position: + bytes: 31 + line: 2 + character: 14 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - Punctuated: + - Number: + leading_trivia: [] + token: + start_position: + bytes: 31 + line: 2 + character: 14 + end_position: + bytes: 32 + line: 2 + character: 15 + token_type: + type: Number + text: "3" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 32 + line: 2 + character: 15 + end_position: + bytes: 33 + line: 2 + character: 16 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 33 + line: 2 + character: 16 + end_position: + bytes: 34 + line: 2 + character: 17 + token_type: + type: Whitespace + characters: " " + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 34 + line: 2 + character: 17 + end_position: + bytes: 35 + line: 2 + character: 18 + token_type: + type: Number + text: "4" + trailing_trivia: + - start_position: + bytes: 35 + line: 2 + character: 18 + end_position: + bytes: 36 + line: 2 + character: 18 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 36 + line: 3 + character: 1 + end_position: + bytes: 41 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 41 + line: 3 + character: 6 + end_position: + bytes: 42 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - Punctuated: + - leading_trivia: [] + token: + start_position: + bytes: 42 + line: 3 + character: 7 + end_position: + bytes: 43 + line: 3 + character: 8 + token_type: + type: Identifier + identifier: e + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 43 + line: 3 + character: 8 + end_position: + bytes: 44 + line: 3 + character: 9 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 44 + line: 3 + character: 9 + end_position: + bytes: 45 + line: 3 + character: 10 + token_type: + type: Whitespace + characters: " " + - End: + leading_trivia: [] + token: + start_position: + bytes: 45 + line: 3 + character: 10 + end_position: + bytes: 46 + line: 3 + character: 11 + token_type: + type: Identifier + identifier: f + trailing_trivia: + - start_position: + bytes: 46 + line: 3 + character: 11 + end_position: + bytes: 47 + line: 3 + character: 12 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 47 + line: 3 + character: 12 + end_position: + bytes: 48 + line: 3 + character: 13 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 48 + line: 3 + character: 13 + end_position: + bytes: 49 + line: 3 + character: 14 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - Punctuated: + - Number: + leading_trivia: [] + token: + start_position: + bytes: 49 + line: 3 + character: 14 + end_position: + bytes: 50 + line: 3 + character: 15 + token_type: + type: Number + text: "5" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 50 + line: 3 + character: 15 + end_position: + bytes: 51 + line: 3 + character: 16 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 51 + line: 3 + character: 16 + end_position: + bytes: 52 + line: 3 + character: 17 + token_type: + type: Whitespace + characters: " " + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 52 + line: 3 + character: 17 + end_position: + bytes: 53 + line: 3 + character: 18 + token_type: + type: Number + text: "6" + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-3/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-3/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..74c0ed4795ba31bb1294e44130e068acbf68da2a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-3/source.lua @@ -0,0 +1,3 @@ +local a, b = 1, 2 +local c, d = 3, 4 +local e, f = 5, 6 \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-3/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-3/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..1ebb9f19a83211458031ada711587a2c24bff35d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-3/tokens.snap @@ -0,0 +1,468 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/local-assignment-3 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: a +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Identifier + identifier: b +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Number + text: "1" +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Number + text: "2" +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 18 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 18 + line: 2 + character: 1 + end_position: + bytes: 23 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 23 + line: 2 + character: 6 + end_position: + bytes: 24 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 24 + line: 2 + character: 7 + end_position: + bytes: 25 + line: 2 + character: 8 + token_type: + type: Identifier + identifier: c +- start_position: + bytes: 25 + line: 2 + character: 8 + end_position: + bytes: 26 + line: 2 + character: 9 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 26 + line: 2 + character: 9 + end_position: + bytes: 27 + line: 2 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 27 + line: 2 + character: 10 + end_position: + bytes: 28 + line: 2 + character: 11 + token_type: + type: Identifier + identifier: d +- start_position: + bytes: 28 + line: 2 + character: 11 + end_position: + bytes: 29 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 29 + line: 2 + character: 12 + end_position: + bytes: 30 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 30 + line: 2 + character: 13 + end_position: + bytes: 31 + line: 2 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 31 + line: 2 + character: 14 + end_position: + bytes: 32 + line: 2 + character: 15 + token_type: + type: Number + text: "3" +- start_position: + bytes: 32 + line: 2 + character: 15 + end_position: + bytes: 33 + line: 2 + character: 16 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 33 + line: 2 + character: 16 + end_position: + bytes: 34 + line: 2 + character: 17 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 34 + line: 2 + character: 17 + end_position: + bytes: 35 + line: 2 + character: 18 + token_type: + type: Number + text: "4" +- start_position: + bytes: 35 + line: 2 + character: 18 + end_position: + bytes: 36 + line: 2 + character: 18 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 36 + line: 3 + character: 1 + end_position: + bytes: 41 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 41 + line: 3 + character: 6 + end_position: + bytes: 42 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 42 + line: 3 + character: 7 + end_position: + bytes: 43 + line: 3 + character: 8 + token_type: + type: Identifier + identifier: e +- start_position: + bytes: 43 + line: 3 + character: 8 + end_position: + bytes: 44 + line: 3 + character: 9 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 44 + line: 3 + character: 9 + end_position: + bytes: 45 + line: 3 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 45 + line: 3 + character: 10 + end_position: + bytes: 46 + line: 3 + character: 11 + token_type: + type: Identifier + identifier: f +- start_position: + bytes: 46 + line: 3 + character: 11 + end_position: + bytes: 47 + line: 3 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 47 + line: 3 + character: 12 + end_position: + bytes: 48 + line: 3 + character: 13 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 48 + line: 3 + character: 13 + end_position: + bytes: 49 + line: 3 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 49 + line: 3 + character: 14 + end_position: + bytes: 50 + line: 3 + character: 15 + token_type: + type: Number + text: "5" +- start_position: + bytes: 50 + line: 3 + character: 15 + end_position: + bytes: 51 + line: 3 + character: 16 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 51 + line: 3 + character: 16 + end_position: + bytes: 52 + line: 3 + character: 17 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 52 + line: 3 + character: 17 + end_position: + bytes: 53 + line: 3 + character: 18 + token_type: + type: Number + text: "6" +- start_position: + bytes: 53 + line: 3 + character: 18 + end_position: + bytes: 53 + line: 3 + character: 18 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-4/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-4/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..90c44c12c4cecc80164744985bdc808a6f147f6b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-4/ast.snap @@ -0,0 +1,96 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/local-assignment-4 + +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - Punctuated: + - leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " + - End: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Identifier + identifier: y + trailing_trivia: [] + equal_token: ~ + expr_list: + pairs: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-4/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-4/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..43ae25449dce13558c423eae60ce54300c96c47d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-4/source.lua @@ -0,0 +1 @@ +local x, y \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-4/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-4/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..1748c54146afadf7d52fa54feb3732e3a1f0fe44 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-4/tokens.snap @@ -0,0 +1,83 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/local-assignment-4 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-5/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-5/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..0e5be5214a305dd608147e9f3e601f3a1cc9d8ad --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-5/ast.snap @@ -0,0 +1,252 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/local-assignment-5 +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: + - start_position: + bytes: 12 + line: 2 + character: 1 + end_position: + bytes: 29 + line: 2 + character: 18 + token_type: + type: SingleLineComment + comment: " Then a comment" + - start_position: + bytes: 29 + line: 2 + character: 18 + end_position: + bytes: 30 + line: 2 + character: 18 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 30 + line: 3 + character: 1 + end_position: + bytes: 35 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 35 + line: 3 + character: 6 + end_position: + bytes: 36 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 36 + line: 3 + character: 7 + end_position: + bytes: 37 + line: 3 + character: 8 + token_type: + type: Identifier + identifier: y + trailing_trivia: + - start_position: + bytes: 37 + line: 3 + character: 8 + end_position: + bytes: 38 + line: 3 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 38 + line: 3 + character: 9 + end_position: + bytes: 39 + line: 3 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 39 + line: 3 + character: 10 + end_position: + bytes: 40 + line: 3 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 40 + line: 3 + character: 11 + end_position: + bytes: 41 + line: 3 + character: 12 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 41 + line: 3 + character: 12 + end_position: + bytes: 42 + line: 3 + character: 12 + token_type: + type: Whitespace + characters: "\n" + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-5/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-5/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..53d943cc7295f3e11bca6c5ab2875c4b41722b37 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-5/source.lua @@ -0,0 +1,3 @@ +local x = 1 +-- Then a comment +local y = 1 diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-5/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-5/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..c74b7be604e1ba80f449c1024484abff689fe725 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/local-assignment-5/tokens.snap @@ -0,0 +1,215 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/local-assignment-5 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Number + text: "1" +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 12 + line: 2 + character: 1 + end_position: + bytes: 29 + line: 2 + character: 18 + token_type: + type: SingleLineComment + comment: " Then a comment" +- start_position: + bytes: 29 + line: 2 + character: 18 + end_position: + bytes: 30 + line: 2 + character: 18 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 30 + line: 3 + character: 1 + end_position: + bytes: 35 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 35 + line: 3 + character: 6 + end_position: + bytes: 36 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 36 + line: 3 + character: 7 + end_position: + bytes: 37 + line: 3 + character: 8 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 37 + line: 3 + character: 8 + end_position: + bytes: 38 + line: 3 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 38 + line: 3 + character: 9 + end_position: + bytes: 39 + line: 3 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 39 + line: 3 + character: 10 + end_position: + bytes: 40 + line: 3 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 40 + line: 3 + character: 11 + end_position: + bytes: 41 + line: 3 + character: 12 + token_type: + type: Number + text: "1" +- start_position: + bytes: 41 + line: 3 + character: 12 + end_position: + bytes: 42 + line: 3 + character: 12 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 42 + line: 4 + character: 1 + end_position: + bytes: 42 + line: 4 + character: 1 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/local-function-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/local-function-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..04393d9f28cddcf660f9550a04a1d866696b7cf1 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/local-function-1/ast.snap @@ -0,0 +1,241 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/local-function-1 +--- +stmts: + - - LocalFunction: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + function_token: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: function + trailing_trivia: + - start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " + name: + leading_trivia: [] + token: + start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Identifier + identifier: x + trailing_trivia: [] + body: + parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 19 + token_type: + type: Whitespace + characters: "\n" + parameters: + pairs: [] + block: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 19 + line: 2 + character: 1 + end_position: + bytes: 20 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 20 + line: 2 + character: 2 + end_position: + bytes: 24 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 24 + line: 2 + character: 6 + end_position: + bytes: 25 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 26 + line: 2 + character: 8 + end_position: + bytes: 27 + line: 2 + character: 9 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 27 + line: 2 + character: 9 + end_position: + bytes: 28 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 25 + line: 2 + character: 7 + end_position: + bytes: 26 + line: 2 + character: 8 + token_type: + type: Number + text: "1" + trailing_trivia: [] + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 28 + line: 3 + character: 1 + end_position: + bytes: 31 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 31 + line: 3 + character: 4 + end_position: + bytes: 32 + line: 3 + character: 4 + token_type: + type: Whitespace + characters: "\n" + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/local-function-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/local-function-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..fbbbdc20f8fb4481dd90cd69d5ce1928900eff69 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/local-function-1/source.lua @@ -0,0 +1,3 @@ +local function x() + call(1) +end diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/local-function-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/local-function-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..b813f3bd7778109795cabf4e7009a7c95a1cd716 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/local-function-1/tokens.snap @@ -0,0 +1,193 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/local-function-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 19 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 19 + line: 2 + character: 1 + end_position: + bytes: 20 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 20 + line: 2 + character: 2 + end_position: + bytes: 24 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 24 + line: 2 + character: 6 + end_position: + bytes: 25 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 25 + line: 2 + character: 7 + end_position: + bytes: 26 + line: 2 + character: 8 + token_type: + type: Number + text: "1" +- start_position: + bytes: 26 + line: 2 + character: 8 + end_position: + bytes: 27 + line: 2 + character: 9 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 27 + line: 2 + character: 9 + end_position: + bytes: 28 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 28 + line: 3 + character: 1 + end_position: + bytes: 31 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 31 + line: 3 + character: 4 + end_position: + bytes: 32 + line: 3 + character: 4 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 32 + line: 4 + character: 1 + end_position: + bytes: 32 + line: 4 + character: 1 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/local-function-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/local-function-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..b1ab1c0eb020b0defb9bfbcb911aee355081a0c1 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/local-function-2/ast.snap @@ -0,0 +1,590 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() + +--- +stmts: + - - LocalFunction: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + function_token: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: function + trailing_trivia: + - start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " + name: + leading_trivia: [] + token: + start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Identifier + identifier: foo + trailing_trivia: [] + body: + parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 23 + line: 1 + character: 24 + end_position: + bytes: 24 + line: 1 + character: 25 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 24 + line: 1 + character: 25 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Whitespace + characters: " " + parameters: + pairs: + - Punctuated: + - Name: + leading_trivia: [] + token: + start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Identifier + identifier: a + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Whitespace + characters: " " + - End: + Name: + leading_trivia: [] + token: + start_position: + bytes: 22 + line: 1 + character: 23 + end_position: + bytes: 23 + line: 1 + character: 24 + token_type: + type: Identifier + identifier: b + trailing_trivia: [] + block: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 28 + line: 1 + character: 29 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 28 + line: 1 + character: 29 + end_position: + bytes: 29 + line: 1 + character: 29 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalFunction: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 29 + line: 2 + character: 1 + end_position: + bytes: 34 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 34 + line: 2 + character: 6 + end_position: + bytes: 35 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " + function_token: + leading_trivia: [] + token: + start_position: + bytes: 35 + line: 2 + character: 7 + end_position: + bytes: 43 + line: 2 + character: 15 + token_type: + type: Symbol + symbol: function + trailing_trivia: + - start_position: + bytes: 43 + line: 2 + character: 15 + end_position: + bytes: 44 + line: 2 + character: 16 + token_type: + type: Whitespace + characters: " " + name: + leading_trivia: [] + token: + start_position: + bytes: 44 + line: 2 + character: 16 + end_position: + bytes: 47 + line: 2 + character: 19 + token_type: + type: Identifier + identifier: bar + trailing_trivia: [] + body: + parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 47 + line: 2 + character: 19 + end_position: + bytes: 48 + line: 2 + character: 20 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 51 + line: 2 + character: 23 + end_position: + bytes: 52 + line: 2 + character: 24 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 52 + line: 2 + character: 24 + end_position: + bytes: 53 + line: 2 + character: 25 + token_type: + type: Whitespace + characters: " " + parameters: + pairs: + - End: + Ellipse: + leading_trivia: [] + token: + start_position: + bytes: 48 + line: 2 + character: 20 + end_position: + bytes: 51 + line: 2 + character: 23 + token_type: + type: Symbol + symbol: "..." + trailing_trivia: [] + block: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 53 + line: 2 + character: 25 + end_position: + bytes: 56 + line: 2 + character: 28 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 56 + line: 2 + character: 28 + end_position: + bytes: 57 + line: 2 + character: 28 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalFunction: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 57 + line: 3 + character: 1 + end_position: + bytes: 62 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 62 + line: 3 + character: 6 + end_position: + bytes: 63 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " + function_token: + leading_trivia: [] + token: + start_position: + bytes: 63 + line: 3 + character: 7 + end_position: + bytes: 71 + line: 3 + character: 15 + token_type: + type: Symbol + symbol: function + trailing_trivia: + - start_position: + bytes: 71 + line: 3 + character: 15 + end_position: + bytes: 72 + line: 3 + character: 16 + token_type: + type: Whitespace + characters: " " + name: + leading_trivia: [] + token: + start_position: + bytes: 72 + line: 3 + character: 16 + end_position: + bytes: 75 + line: 3 + character: 19 + token_type: + type: Identifier + identifier: baz + trailing_trivia: [] + body: + parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 75 + line: 3 + character: 19 + end_position: + bytes: 76 + line: 3 + character: 20 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 85 + line: 3 + character: 29 + end_position: + bytes: 86 + line: 3 + character: 30 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 86 + line: 3 + character: 30 + end_position: + bytes: 87 + line: 3 + character: 31 + token_type: + type: Whitespace + characters: " " + parameters: + pairs: + - Punctuated: + - Name: + leading_trivia: [] + token: + start_position: + bytes: 76 + line: 3 + character: 20 + end_position: + bytes: 77 + line: 3 + character: 21 + token_type: + type: Identifier + identifier: a + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 77 + line: 3 + character: 21 + end_position: + bytes: 78 + line: 3 + character: 22 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 78 + line: 3 + character: 22 + end_position: + bytes: 79 + line: 3 + character: 23 + token_type: + type: Whitespace + characters: " " + - Punctuated: + - Name: + leading_trivia: [] + token: + start_position: + bytes: 79 + line: 3 + character: 23 + end_position: + bytes: 80 + line: 3 + character: 24 + token_type: + type: Identifier + identifier: b + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 80 + line: 3 + character: 24 + end_position: + bytes: 81 + line: 3 + character: 25 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 81 + line: 3 + character: 25 + end_position: + bytes: 82 + line: 3 + character: 26 + token_type: + type: Whitespace + characters: " " + - End: + Ellipse: + leading_trivia: [] + token: + start_position: + bytes: 82 + line: 3 + character: 26 + end_position: + bytes: 85 + line: 3 + character: 29 + token_type: + type: Symbol + symbol: "..." + trailing_trivia: [] + block: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 87 + line: 3 + character: 31 + end_position: + bytes: 90 + line: 3 + character: 34 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/local-function-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/local-function-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..a17fbee1dfc532c679e6b3336f616685a2441654 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/local-function-2/source.lua @@ -0,0 +1,3 @@ +local function foo(a, b) end +local function bar(...) end +local function baz(a, b, ...) end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/local-function-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/local-function-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..13cbe42855484fcad4d34e8d785f490190359257 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/local-function-2/tokens.snap @@ -0,0 +1,468 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/local-function-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Identifier + identifier: a +- start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 22 + line: 1 + character: 23 + end_position: + bytes: 23 + line: 1 + character: 24 + token_type: + type: Identifier + identifier: b +- start_position: + bytes: 23 + line: 1 + character: 24 + end_position: + bytes: 24 + line: 1 + character: 25 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 24 + line: 1 + character: 25 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 28 + line: 1 + character: 29 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 28 + line: 1 + character: 29 + end_position: + bytes: 29 + line: 1 + character: 29 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 29 + line: 2 + character: 1 + end_position: + bytes: 34 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 34 + line: 2 + character: 6 + end_position: + bytes: 35 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 35 + line: 2 + character: 7 + end_position: + bytes: 43 + line: 2 + character: 15 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 43 + line: 2 + character: 15 + end_position: + bytes: 44 + line: 2 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 44 + line: 2 + character: 16 + end_position: + bytes: 47 + line: 2 + character: 19 + token_type: + type: Identifier + identifier: bar +- start_position: + bytes: 47 + line: 2 + character: 19 + end_position: + bytes: 48 + line: 2 + character: 20 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 48 + line: 2 + character: 20 + end_position: + bytes: 51 + line: 2 + character: 23 + token_type: + type: Symbol + symbol: "..." +- start_position: + bytes: 51 + line: 2 + character: 23 + end_position: + bytes: 52 + line: 2 + character: 24 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 52 + line: 2 + character: 24 + end_position: + bytes: 53 + line: 2 + character: 25 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 53 + line: 2 + character: 25 + end_position: + bytes: 56 + line: 2 + character: 28 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 56 + line: 2 + character: 28 + end_position: + bytes: 57 + line: 2 + character: 28 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 57 + line: 3 + character: 1 + end_position: + bytes: 62 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 62 + line: 3 + character: 6 + end_position: + bytes: 63 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 63 + line: 3 + character: 7 + end_position: + bytes: 71 + line: 3 + character: 15 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 71 + line: 3 + character: 15 + end_position: + bytes: 72 + line: 3 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 72 + line: 3 + character: 16 + end_position: + bytes: 75 + line: 3 + character: 19 + token_type: + type: Identifier + identifier: baz +- start_position: + bytes: 75 + line: 3 + character: 19 + end_position: + bytes: 76 + line: 3 + character: 20 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 76 + line: 3 + character: 20 + end_position: + bytes: 77 + line: 3 + character: 21 + token_type: + type: Identifier + identifier: a +- start_position: + bytes: 77 + line: 3 + character: 21 + end_position: + bytes: 78 + line: 3 + character: 22 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 78 + line: 3 + character: 22 + end_position: + bytes: 79 + line: 3 + character: 23 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 79 + line: 3 + character: 23 + end_position: + bytes: 80 + line: 3 + character: 24 + token_type: + type: Identifier + identifier: b +- start_position: + bytes: 80 + line: 3 + character: 24 + end_position: + bytes: 81 + line: 3 + character: 25 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 81 + line: 3 + character: 25 + end_position: + bytes: 82 + line: 3 + character: 26 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 82 + line: 3 + character: 26 + end_position: + bytes: 85 + line: 3 + character: 29 + token_type: + type: Symbol + symbol: "..." +- start_position: + bytes: 85 + line: 3 + character: 29 + end_position: + bytes: 86 + line: 3 + character: 30 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 86 + line: 3 + character: 30 + end_position: + bytes: 87 + line: 3 + character: 31 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 87 + line: 3 + character: 31 + end_position: + bytes: 90 + line: 3 + character: 34 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 90 + line: 3 + character: 34 + end_position: + bytes: 90 + line: 3 + character: 34 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/mixed-indented-comments/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/mixed-indented-comments/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..7750c7873a074e0ec4c3b00dfed0221938130e3e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/mixed-indented-comments/ast.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/mixed-indented-comments + +--- +stmts: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/mixed-indented-comments/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/mixed-indented-comments/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..23c37db1896b4cf0eab9e7ca54bfb45117ceb9e8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/mixed-indented-comments/source.lua @@ -0,0 +1,4 @@ + -- Indented single line + --[[ + Indented multi line + ]] \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/mixed-indented-comments/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/mixed-indented-comments/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..78d7f720ee6e92b12b53ab81bae86d2e17f62ccb --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/mixed-indented-comments/tokens.snap @@ -0,0 +1,73 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/mixed-indented-comments + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 24 + line: 1 + character: 25 + token_type: + type: SingleLineComment + comment: " Indented single line" +- start_position: + bytes: 24 + line: 1 + character: 25 + end_position: + bytes: 25 + line: 1 + character: 25 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 25 + line: 2 + character: 1 + end_position: + bytes: 26 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 26 + line: 2 + character: 2 + end_position: + bytes: 56 + line: 4 + character: 4 + token_type: + type: MultiLineComment + blocks: 0 + comment: "\n\t\tIndented multi line\n\t" +- start_position: + bytes: 56 + line: 4 + character: 4 + end_position: + bytes: 56 + line: 4 + character: 4 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..31b6ed8eb75b9814cb85c06a4fbf0c209a4eb76c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-1/ast.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/multi-line-comments-1 + +--- +stmts: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..5a8bf75e61862f096ebf24388e3a26b7ddab7bfa --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-1/source.lua @@ -0,0 +1,5 @@ +--[[ + such comments + much lines + wow +]] \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..5920d2c93f97d89b6d30a34c5523260465e9a46a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-1/tokens.snap @@ -0,0 +1,29 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/multi-line-comments-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 39 + line: 5 + character: 3 + token_type: + type: MultiLineComment + blocks: 0 + comment: "\n\tsuch comments\n\tmuch lines\n\twow\n" +- start_position: + bytes: 39 + line: 5 + character: 3 + end_position: + bytes: 39 + line: 5 + character: 3 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..95de1b460c8bf1c5e133fe61595d0e663961d7d0 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-2/ast.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/multi-line-comments-2 + +--- +stmts: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..56291f7fd0c41bfe8017a753d3f2fa23c4841f71 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-2/source.lua @@ -0,0 +1,4 @@ +--[=[ + never have i used these weird equals signs comments + but im sure someone does +]=] \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..9ae8494d583655c25ff51445ce23f1be11dab9cd --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-2/tokens.snap @@ -0,0 +1,29 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/multi-line-comments-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 88 + line: 4 + character: 4 + token_type: + type: MultiLineComment + blocks: 1 + comment: "\n\tnever have i used these weird equals signs comments\n\tbut im sure someone does\n" +- start_position: + bytes: 88 + line: 4 + character: 4 + end_position: + bytes: 88 + line: 4 + character: 4 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-3/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-3/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..3d31018e599136f5bb8dea0054156b499adc2ce1 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-3/ast.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/multi-line-comments-3 + +--- +stmts: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-3/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-3/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..977869da56a74f8519ca7ef99a1e477014d599ae --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-3/source.lua @@ -0,0 +1,3 @@ +--[=[ +--[[ +]=] \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-3/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-3/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..6cb4728f8aca14cd9534b22ea6730de7ad50ed0a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-3/tokens.snap @@ -0,0 +1,29 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/multi-line-comments-3 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 14 + line: 3 + character: 4 + token_type: + type: MultiLineComment + blocks: 1 + comment: "\n--[[\n" +- start_position: + bytes: 14 + line: 3 + character: 4 + end_position: + bytes: 14 + line: 3 + character: 4 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-4/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-4/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..e5cbdd6ee413b455061cbf67b7168d3a27e9558a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-4/ast.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/multi-line-comments-4 + +--- +stmts: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-4/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-4/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..72b48afcd64f56ccc7faeeafb58fa60caed15117 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-4/source.lua @@ -0,0 +1,5 @@ +--[=====[ + lua be like +]====] + still going +]=====] \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-4/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-4/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..cbc8ac6619153db82acc9030538675addbe218c0 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-4/tokens.snap @@ -0,0 +1,29 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/multi-line-comments-4 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 50 + line: 5 + character: 8 + token_type: + type: MultiLineComment + blocks: 5 + comment: "\n\tlua be like\n]====]\n\tstill going\n" +- start_position: + bytes: 50 + line: 5 + character: 8 + end_position: + bytes: 50 + line: 5 + character: 8 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-5/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-5/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..b52c100bb6c1b2c4d499f44d7c0592bd5ee8fdce --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-5/ast.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/multi-line-comments-5 + +--- +stmts: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-5/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-5/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..116f6fb0327dc640384ba9f3e95f6ba1056d4a66 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-5/source.lua @@ -0,0 +1,6 @@ +--[[ +local emotes = { + [":thinking:"] = "http://www.roblox.com/asset/?id=643340245", + [":bug:"] = "http://www.roblox.com/asset/?id=860037275" +} +]] \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-5/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-5/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..cac4f568b5a9ae3f0478e3cf09f31f8d5e091c32 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-5/tokens.snap @@ -0,0 +1,29 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/multi-line-comments-5 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 146 + line: 6 + character: 3 + token_type: + type: MultiLineComment + blocks: 0 + comment: "\nlocal emotes = {\n\t[\":thinking:\"] = \"http://www.roblox.com/asset/?id=643340245\",\n\t[\":bug:\"] = \"http://www.roblox.com/asset/?id=860037275\"\n}\n" +- start_position: + bytes: 146 + line: 6 + character: 3 + end_position: + bytes: 146 + line: 6 + character: 3 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-6/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-6/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..2b3b7063b53c47011406958cbc6d72d098fc4a2a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-6/ast.snap @@ -0,0 +1,165 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() + +--- +stmts: + - - LocalFunction: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + function_token: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: function + trailing_trivia: + - start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " + name: + leading_trivia: [] + token: + start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Identifier + identifier: x + trailing_trivia: [] + body: + parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 38 + line: 1 + character: 39 + end_position: + bytes: 39 + line: 1 + character: 40 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 39 + line: 1 + character: 40 + end_position: + bytes: 40 + line: 1 + character: 40 + token_type: + type: Whitespace + characters: "\n" + parameters: + pairs: + - End: + Ellipse: + leading_trivia: [] + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Symbol + symbol: "..." + trailing_trivia: + - start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 38 + line: 1 + character: 39 + token_type: + type: MultiLineComment + blocks: 0 + comment: comment here + block: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 40 + line: 2 + character: 1 + end_position: + bytes: 43 + line: 2 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-6/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-6/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..e5f7405cf0649caa632cc72b6efbd7786e802a3c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-6/source.lua @@ -0,0 +1,2 @@ +local function x(...--[[comment here]]) +end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-6/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-6/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..36675a2e736dae6bec94c22e8ed12eb10173d5c9 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-6/tokens.snap @@ -0,0 +1,139 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/multi-line-comments-6 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Symbol + symbol: "..." +- start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 38 + line: 1 + character: 39 + token_type: + type: MultiLineComment + blocks: 0 + comment: comment here +- start_position: + bytes: 38 + line: 1 + character: 39 + end_position: + bytes: 39 + line: 1 + character: 40 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 39 + line: 1 + character: 40 + end_position: + bytes: 40 + line: 1 + character: 40 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 40 + line: 2 + character: 1 + end_position: + bytes: 43 + line: 2 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 43 + line: 2 + character: 4 + end_position: + bytes: 43 + line: 2 + character: 4 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-7/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-7/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..d4bf0738b38e777d55493d1c41bc0f68d870b2bb --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-7/ast.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/multi-line-comments-7 + +--- +stmts: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-7/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-7/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..946434aa9f209527031d0c5281d2373de63ab242 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-7/source.lua @@ -0,0 +1,3 @@ +--[=[ μÎλλον ]=] + +-- some text here diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-7/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-7/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..276b2eccce6ba5fc386ef99f9db7632e29d5adb8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-7/tokens.snap @@ -0,0 +1,73 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/multi-line-comments-7 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 22 + line: 1 + character: 17 + token_type: + type: MultiLineComment + blocks: 1 + comment: " μÎλλον " +- start_position: + bytes: 22 + line: 1 + character: 17 + end_position: + bytes: 23 + line: 1 + character: 17 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 23 + line: 2 + character: 1 + end_position: + bytes: 24 + line: 2 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 24 + line: 3 + character: 1 + end_position: + bytes: 41 + line: 3 + character: 18 + token_type: + type: SingleLineComment + comment: " some text here" +- start_position: + bytes: 41 + line: 3 + character: 18 + end_position: + bytes: 42 + line: 3 + character: 18 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 42 + line: 4 + character: 1 + end_position: + bytes: 42 + line: 4 + character: 1 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-8/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-8/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..b3b3fb27254e1e42ca82e64f9b60d04928bf7617 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-8/ast.snap @@ -0,0 +1,143 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/multi-line-comments-8 +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: + - start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 21 + line: 1 + character: 11 + token_type: + type: MultiLineComment + blocks: 0 + comment: 👨ðŸ¾â€ðŸ’» + - start_position: + bytes: 21 + line: 1 + character: 11 + end_position: + bytes: 22 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 22 + line: 2 + character: 1 + end_position: + bytes: 27 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 27 + line: 2 + character: 6 + end_position: + bytes: 28 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 28 + line: 2 + character: 7 + end_position: + bytes: 37 + line: 2 + character: 16 + token_type: + type: Identifier + identifier: more_code + trailing_trivia: + - start_position: + bytes: 37 + line: 2 + character: 16 + end_position: + bytes: 38 + line: 2 + character: 17 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 38 + line: 2 + character: 17 + end_position: + bytes: 39 + line: 2 + character: 18 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 39 + line: 2 + character: 18 + end_position: + bytes: 40 + line: 2 + character: 19 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 40 + line: 2 + character: 19 + end_position: + bytes: 44 + line: 2 + character: 23 + token_type: + type: Identifier + identifier: here + trailing_trivia: + - start_position: + bytes: 44 + line: 2 + character: 23 + end_position: + bytes: 45 + line: 2 + character: 23 + token_type: + type: Whitespace + characters: "\n" + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-8/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-8/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..048d07117a9909cb4991f7720c6cb6a4f3cbb974 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-8/source.lua @@ -0,0 +1,2 @@ +--[[👨ðŸ¾â€ðŸ’»]] +local more_code = here diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-8/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-8/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..3eafa0cc4bc2e6bdbf3c4b29343c86f5fb1c5ee0 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-8/tokens.snap @@ -0,0 +1,128 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/multi-line-comments-8 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 21 + line: 1 + character: 11 + token_type: + type: MultiLineComment + blocks: 0 + comment: 👨ðŸ¾â€ðŸ’» +- start_position: + bytes: 21 + line: 1 + character: 11 + end_position: + bytes: 22 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 22 + line: 2 + character: 1 + end_position: + bytes: 27 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 27 + line: 2 + character: 6 + end_position: + bytes: 28 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 28 + line: 2 + character: 7 + end_position: + bytes: 37 + line: 2 + character: 16 + token_type: + type: Identifier + identifier: more_code +- start_position: + bytes: 37 + line: 2 + character: 16 + end_position: + bytes: 38 + line: 2 + character: 17 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 38 + line: 2 + character: 17 + end_position: + bytes: 39 + line: 2 + character: 18 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 39 + line: 2 + character: 18 + end_position: + bytes: 40 + line: 2 + character: 19 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 40 + line: 2 + character: 19 + end_position: + bytes: 44 + line: 2 + character: 23 + token_type: + type: Identifier + identifier: here +- start_position: + bytes: 44 + line: 2 + character: 23 + end_position: + bytes: 45 + line: 2 + character: 23 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 45 + line: 3 + character: 1 + end_position: + bytes: 45 + line: 3 + character: 1 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-9/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-9/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..6e1d3d1aab858bc8ed7c2942cad4bfd2762342f4 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-9/ast.snap @@ -0,0 +1,6 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +--- +stmts: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-9/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-9/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..5ef37535229369675b8358f7afc2b02c4a03a256 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-9/source.lua @@ -0,0 +1,21 @@ +--[=[ + + This description starts one line down, + + And has a line in the middle, followed by trailing lines. + + ```lua + function test() + print("indentation") + + do + print("more indented") + end + end + ``` + + + @class indentation + + +]=] \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-9/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-9/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..3385af38dec2b9ecf5be252ba0ebef5ff06ad91d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-comments-9/tokens.snap @@ -0,0 +1,27 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 231 + line: 21 + character: 4 + token_type: + type: MultiLineComment + blocks: 1 + comment: "\n\n\tThis description starts one line down,\n\n\tAnd has a line in the middle, followed by trailing lines.\n\n\t```lua\n\tfunction test()\n\t\tprint(\"indentation\")\n\n\t\tdo\n\t\t\tprint(\"more indented\")\n\t\tend\n\tend\n\t```\n\n\n\t@class indentation\n\n\n" +- start_position: + bytes: 231 + line: 21 + character: 4 + end_position: + bytes: 231 + line: 21 + character: 4 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..56c703f600185757aa64679b648f1b140055e637 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-1/ast.snap @@ -0,0 +1,107 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 48 + line: 4 + character: 13 + token_type: + type: StringLiteral + literal: "Full Moon\nis a\nlossless\nLua parser" + quote_type: Brackets + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..1cb9d1965066af3020305aa4c395d5e55fab6b77 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-1/source.lua @@ -0,0 +1,4 @@ +local x = [[Full Moon +is a +lossless +Lua parser]] \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..cdb29fb380bf29b22557d546d4baef5a646c7f7f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-1/tokens.snap @@ -0,0 +1,93 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 48 + line: 4 + character: 13 + token_type: + type: StringLiteral + literal: "Full Moon\nis a\nlossless\nLua parser" + quote_type: Brackets +- start_position: + bytes: 48 + line: 4 + character: 13 + end_position: + bytes: 48 + line: 4 + character: 13 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..e0c6de1e151a88b5c162bb93b26851cbb19a6fea --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-2/ast.snap @@ -0,0 +1,108 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 43 + line: 3 + character: 9 + token_type: + type: StringLiteral + literal: "This is\nseveral equal\nsigns" + multi_line_depth: 1 + quote_type: Brackets + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..8e6c09ebd2b19e51dcc5bd528d63eb23b78ee937 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-2/source.lua @@ -0,0 +1,3 @@ +local x = [=[This is +several equal +signs]=] \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..9254ab6340d62c395da0c2fcef06e131dffab289 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-2/tokens.snap @@ -0,0 +1,94 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 43 + line: 3 + character: 9 + token_type: + type: StringLiteral + literal: "This is\nseveral equal\nsigns" + multi_line_depth: 1 + quote_type: Brackets +- start_position: + bytes: 43 + line: 3 + character: 9 + end_position: + bytes: 43 + line: 3 + character: 9 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-3/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-3/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..c71df3ec8d7f284bd50edbbfd8fa38157d60fe14 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-3/ast.snap @@ -0,0 +1,107 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 154 + line: 6 + character: 3 + token_type: + type: StringLiteral + literal: "\nlocal emotes = {\n\t[\":thinking:\"] = \"http://www.roblox.com/asset/?id=643340245\",\n\t[\":bug:\"] = \"http://www.roblox.com/asset/?id=860037275\"\n}\n" + quote_type: Brackets + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-3/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-3/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..0856c4d25d099a2b1d532dc9ca49db91dd151431 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-3/source.lua @@ -0,0 +1,6 @@ +local x = [[ +local emotes = { + [":thinking:"] = "http://www.roblox.com/asset/?id=643340245", + [":bug:"] = "http://www.roblox.com/asset/?id=860037275" +} +]] \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-3/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-3/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..ec9dc2950c24762bd35462b11fa52e93220cda11 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-3/tokens.snap @@ -0,0 +1,93 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 154 + line: 6 + character: 3 + token_type: + type: StringLiteral + literal: "\nlocal emotes = {\n\t[\":thinking:\"] = \"http://www.roblox.com/asset/?id=643340245\",\n\t[\":bug:\"] = \"http://www.roblox.com/asset/?id=860037275\"\n}\n" + quote_type: Brackets +- start_position: + bytes: 154 + line: 6 + character: 3 + end_position: + bytes: 154 + line: 6 + character: 3 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-4/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-4/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..af33a16f090bb31972b457fe95293d6393e1696d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-4/ast.snap @@ -0,0 +1,77 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +--- +stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: StringLiteral + literal: doge + quote_type: Brackets + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-4/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-4/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..12a0b783029356c6c4b43ba661b5b2542244a920 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-4/source.lua @@ -0,0 +1 @@ +call([[doge]]) \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-4/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-4/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..cf929dfdc5fa734a170676b0411815de190d337e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-4/tokens.snap @@ -0,0 +1,60 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: StringLiteral + literal: doge + quote_type: Brackets +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-5/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-5/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..3f3efe1ec17fbe213c03ae455c903aa59ce5f0ac --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-5/ast.snap @@ -0,0 +1,230 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Identifier + identifier: emoji + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 26 + line: 1 + character: 21 + token_type: + type: StringLiteral + literal: 🧓🽠+ quote_type: Brackets + trailing_trivia: + - start_position: + bytes: 26 + line: 1 + character: 21 + end_position: + bytes: 27 + line: 1 + character: 21 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 27 + line: 2 + character: 1 + end_position: + bytes: 32 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 32 + line: 2 + character: 6 + end_position: + bytes: 33 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 33 + line: 2 + character: 7 + end_position: + bytes: 42 + line: 2 + character: 16 + token_type: + type: Identifier + identifier: more_code + trailing_trivia: + - start_position: + bytes: 42 + line: 2 + character: 16 + end_position: + bytes: 43 + line: 2 + character: 17 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 43 + line: 2 + character: 17 + end_position: + bytes: 44 + line: 2 + character: 18 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 44 + line: 2 + character: 18 + end_position: + bytes: 45 + line: 2 + character: 19 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 45 + line: 2 + character: 19 + end_position: + bytes: 49 + line: 2 + character: 23 + token_type: + type: Identifier + identifier: here + trailing_trivia: + - start_position: + bytes: 49 + line: 2 + character: 23 + end_position: + bytes: 50 + line: 2 + character: 23 + token_type: + type: Whitespace + characters: "\n" + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-5/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-5/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..4780d5f2382549bdb58010c7647b556d80aaee55 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-5/source.lua @@ -0,0 +1,2 @@ +local emoji = [[🧓ðŸ½]] +local more_code = here diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-5/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-5/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..034d5f0c4e1a39b9ca8548e2e49fa1b5c2b5f775 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-5/tokens.snap @@ -0,0 +1,192 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Identifier + identifier: emoji +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 26 + line: 1 + character: 21 + token_type: + type: StringLiteral + literal: 🧓🽠+ quote_type: Brackets +- start_position: + bytes: 26 + line: 1 + character: 21 + end_position: + bytes: 27 + line: 1 + character: 21 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 27 + line: 2 + character: 1 + end_position: + bytes: 32 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 32 + line: 2 + character: 6 + end_position: + bytes: 33 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 33 + line: 2 + character: 7 + end_position: + bytes: 42 + line: 2 + character: 16 + token_type: + type: Identifier + identifier: more_code +- start_position: + bytes: 42 + line: 2 + character: 16 + end_position: + bytes: 43 + line: 2 + character: 17 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 43 + line: 2 + character: 17 + end_position: + bytes: 44 + line: 2 + character: 18 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 44 + line: 2 + character: 18 + end_position: + bytes: 45 + line: 2 + character: 19 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 45 + line: 2 + character: 19 + end_position: + bytes: 49 + line: 2 + character: 23 + token_type: + type: Identifier + identifier: here +- start_position: + bytes: 49 + line: 2 + character: 23 + end_position: + bytes: 50 + line: 2 + character: 23 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 50 + line: 3 + character: 1 + end_position: + bytes: 50 + line: 3 + character: 1 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-6/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-6/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..e389a6fcfe6c003a4e90f0f1aa5426212237bf46 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-6/ast.snap @@ -0,0 +1,120 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/multi-line-string-6 +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Identifier + identifier: foo + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 22 + line: 2 + character: 5 + token_type: + type: StringLiteral + literal: "bar\\\nbaz" + quote_type: Double + trailing_trivia: + - start_position: + bytes: 22 + line: 2 + character: 5 + end_position: + bytes: 23 + line: 2 + character: 5 + token_type: + type: Whitespace + characters: "\n" + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-6/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-6/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..f090ebd0df8ab036ddd4b9e72a250843b170305b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-6/source.lua @@ -0,0 +1,2 @@ +local foo = "bar\ +baz" diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-6/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-6/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..d89312a4c20910f6d75eb00e31cc23778697002b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-6/tokens.snap @@ -0,0 +1,106 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/multi-line-string-6 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 22 + line: 2 + character: 5 + token_type: + type: StringLiteral + literal: "bar\\\nbaz" + quote_type: Double +- start_position: + bytes: 22 + line: 2 + character: 5 + end_position: + bytes: 23 + line: 2 + character: 5 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 23 + line: 3 + character: 1 + end_position: + bytes: 23 + line: 3 + character: 1 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-7/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-7/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..5fd0d30fa08b1e9a89d2fc09fb452993ae0fe29a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-7/ast.snap @@ -0,0 +1,108 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: a + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: StringLiteral + literal: "[%s]" + multi_line_depth: 1 + quote_type: Brackets + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-7/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-7/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..902027fc65b97de765cc6f2d93c26b80efd7ae22 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-7/source.lua @@ -0,0 +1 @@ +local a = [=[[%s]]=] \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-7/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-7/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..3babacfa372ec1629fac5b58b7ed6102be23560e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-7/tokens.snap @@ -0,0 +1,94 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: a +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: StringLiteral + literal: "[%s]" + multi_line_depth: 1 + quote_type: Brackets +- start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-8/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-8/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..a89e03a8509a7a6849e176830027f1740288d1cf --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-8/ast.snap @@ -0,0 +1,108 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 68 + line: 1 + character: 69 + token_type: + type: StringLiteral + literal: "\\v<((do|load)file|require)\\s*\\(?['\"]\\zs[^'\"]+\\ze['\"]" + multi_line_depth: 1 + quote_type: Brackets + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-8/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-8/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..93ec4d942d7da09c17d7ab29046f9e0f075307f4 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-8/source.lua @@ -0,0 +1 @@ +local x = [=[\v<((do|load)file|require)\s*\(?['"]\zs[^'"]+\ze['"]]=] \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-8/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-8/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..eefcaa224c6be0a97296b9cba1fd61e9163c7783 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/multi-line-string-8/tokens.snap @@ -0,0 +1,94 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 68 + line: 1 + character: 69 + token_type: + type: StringLiteral + literal: "\\v<((do|load)file|require)\\s*\\(?['\"]\\zs[^'\"]+\\ze['\"]" + multi_line_depth: 1 + quote_type: Brackets +- start_position: + bytes: 68 + line: 1 + character: 69 + end_position: + bytes: 68 + line: 1 + character: 69 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/negative-numbers/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/negative-numbers/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..4315cf3060e64dbb4cb460fa1db3b82c5a5417b6 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/negative-numbers/ast.snap @@ -0,0 +1,595 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/negative-numbers +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Identifier + identifier: foo + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + BinaryOperator: + lhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Identifier + identifier: x + trailing_trivia: [] + binop: + Minus: + leading_trivia: [] + token: + start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: "-" + trailing_trivia: [] + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 16 + line: 2 + character: 1 + end_position: + bytes: 21 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 21 + line: 2 + character: 6 + end_position: + bytes: 22 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 22 + line: 2 + character: 7 + end_position: + bytes: 25 + line: 2 + character: 10 + token_type: + type: Identifier + identifier: foo + trailing_trivia: + - start_position: + bytes: 25 + line: 2 + character: 10 + end_position: + bytes: 26 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 26 + line: 2 + character: 11 + end_position: + bytes: 27 + line: 2 + character: 12 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 27 + line: 2 + character: 12 + end_position: + bytes: 28 + line: 2 + character: 13 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + BinaryOperator: + lhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 28 + line: 2 + character: 13 + end_position: + bytes: 29 + line: 2 + character: 14 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 29 + line: 2 + character: 14 + end_position: + bytes: 30 + line: 2 + character: 15 + token_type: + type: Whitespace + characters: " " + binop: + Minus: + leading_trivia: [] + token: + start_position: + bytes: 30 + line: 2 + character: 15 + end_position: + bytes: 31 + line: 2 + character: 16 + token_type: + type: Symbol + symbol: "-" + trailing_trivia: [] + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 31 + line: 2 + character: 16 + end_position: + bytes: 32 + line: 2 + character: 17 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 32 + line: 2 + character: 17 + end_position: + bytes: 33 + line: 2 + character: 17 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 33 + line: 3 + character: 1 + end_position: + bytes: 38 + line: 3 + character: 6 + token_type: + type: Identifier + identifier: print + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 38 + line: 3 + character: 6 + end_position: + bytes: 39 + line: 3 + character: 7 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 43 + line: 3 + character: 11 + end_position: + bytes: 44 + line: 3 + character: 12 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 44 + line: 3 + character: 12 + end_position: + bytes: 45 + line: 3 + character: 12 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - End: + BinaryOperator: + lhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 39 + line: 3 + character: 7 + end_position: + bytes: 40 + line: 3 + character: 8 + token_type: + type: Number + text: "1" + trailing_trivia: [] + binop: + Plus: + leading_trivia: [] + token: + start_position: + bytes: 40 + line: 3 + character: 8 + end_position: + bytes: 41 + line: 3 + character: 9 + token_type: + type: Symbol + symbol: + + trailing_trivia: [] + rhs: + UnaryOperator: + unop: + Minus: + leading_trivia: [] + token: + start_position: + bytes: 41 + line: 3 + character: 9 + end_position: + bytes: 42 + line: 3 + character: 10 + token_type: + type: Symbol + symbol: "-" + trailing_trivia: [] + expression: + Number: + leading_trivia: [] + token: + start_position: + bytes: 42 + line: 3 + character: 10 + end_position: + bytes: 43 + line: 3 + character: 11 + token_type: + type: Number + text: "3" + trailing_trivia: [] + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 45 + line: 4 + character: 1 + end_position: + bytes: 50 + line: 4 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 50 + line: 4 + character: 6 + end_position: + bytes: 51 + line: 4 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 51 + line: 4 + character: 7 + end_position: + bytes: 54 + line: 4 + character: 10 + token_type: + type: Identifier + identifier: foo + trailing_trivia: + - start_position: + bytes: 54 + line: 4 + character: 10 + end_position: + bytes: 55 + line: 4 + character: 11 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 55 + line: 4 + character: 11 + end_position: + bytes: 56 + line: 4 + character: 12 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 56 + line: 4 + character: 12 + end_position: + bytes: 57 + line: 4 + character: 13 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + BinaryOperator: + lhs: + UnaryOperator: + unop: + Minus: + leading_trivia: [] + token: + start_position: + bytes: 57 + line: 4 + character: 13 + end_position: + bytes: 58 + line: 4 + character: 14 + token_type: + type: Symbol + symbol: "-" + trailing_trivia: [] + expression: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 58 + line: 4 + character: 14 + end_position: + bytes: 59 + line: 4 + character: 15 + token_type: + type: Identifier + identifier: x + trailing_trivia: [] + binop: + Plus: + leading_trivia: [] + token: + start_position: + bytes: 59 + line: 4 + character: 15 + end_position: + bytes: 60 + line: 4 + character: 16 + token_type: + type: Symbol + symbol: + + trailing_trivia: [] + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 60 + line: 4 + character: 16 + end_position: + bytes: 61 + line: 4 + character: 17 + token_type: + type: Number + text: "1" + trailing_trivia: [] + - ~ diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/negative-numbers/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/negative-numbers/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..3b7ccd7726e36138646ff3efced56944573a57f9 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/negative-numbers/source.lua @@ -0,0 +1,4 @@ +local foo = x-1 +local foo = x -1 +print(1+-3) +local foo = -x+1 \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/negative-numbers/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/negative-numbers/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..ab3ba56a21fccca5059b4b5755dcbbdc551e30ef --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/negative-numbers/tokens.snap @@ -0,0 +1,444 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/negative-numbers +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: "-" +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Number + text: "1" +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 16 + line: 2 + character: 1 + end_position: + bytes: 21 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 21 + line: 2 + character: 6 + end_position: + bytes: 22 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 22 + line: 2 + character: 7 + end_position: + bytes: 25 + line: 2 + character: 10 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 25 + line: 2 + character: 10 + end_position: + bytes: 26 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 26 + line: 2 + character: 11 + end_position: + bytes: 27 + line: 2 + character: 12 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 27 + line: 2 + character: 12 + end_position: + bytes: 28 + line: 2 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 28 + line: 2 + character: 13 + end_position: + bytes: 29 + line: 2 + character: 14 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 29 + line: 2 + character: 14 + end_position: + bytes: 30 + line: 2 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 30 + line: 2 + character: 15 + end_position: + bytes: 31 + line: 2 + character: 16 + token_type: + type: Symbol + symbol: "-" +- start_position: + bytes: 31 + line: 2 + character: 16 + end_position: + bytes: 32 + line: 2 + character: 17 + token_type: + type: Number + text: "1" +- start_position: + bytes: 32 + line: 2 + character: 17 + end_position: + bytes: 33 + line: 2 + character: 17 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 33 + line: 3 + character: 1 + end_position: + bytes: 38 + line: 3 + character: 6 + token_type: + type: Identifier + identifier: print +- start_position: + bytes: 38 + line: 3 + character: 6 + end_position: + bytes: 39 + line: 3 + character: 7 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 39 + line: 3 + character: 7 + end_position: + bytes: 40 + line: 3 + character: 8 + token_type: + type: Number + text: "1" +- start_position: + bytes: 40 + line: 3 + character: 8 + end_position: + bytes: 41 + line: 3 + character: 9 + token_type: + type: Symbol + symbol: + +- start_position: + bytes: 41 + line: 3 + character: 9 + end_position: + bytes: 42 + line: 3 + character: 10 + token_type: + type: Symbol + symbol: "-" +- start_position: + bytes: 42 + line: 3 + character: 10 + end_position: + bytes: 43 + line: 3 + character: 11 + token_type: + type: Number + text: "3" +- start_position: + bytes: 43 + line: 3 + character: 11 + end_position: + bytes: 44 + line: 3 + character: 12 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 44 + line: 3 + character: 12 + end_position: + bytes: 45 + line: 3 + character: 12 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 45 + line: 4 + character: 1 + end_position: + bytes: 50 + line: 4 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 50 + line: 4 + character: 6 + end_position: + bytes: 51 + line: 4 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 51 + line: 4 + character: 7 + end_position: + bytes: 54 + line: 4 + character: 10 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 54 + line: 4 + character: 10 + end_position: + bytes: 55 + line: 4 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 55 + line: 4 + character: 11 + end_position: + bytes: 56 + line: 4 + character: 12 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 56 + line: 4 + character: 12 + end_position: + bytes: 57 + line: 4 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 57 + line: 4 + character: 13 + end_position: + bytes: 58 + line: 4 + character: 14 + token_type: + type: Symbol + symbol: "-" +- start_position: + bytes: 58 + line: 4 + character: 14 + end_position: + bytes: 59 + line: 4 + character: 15 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 59 + line: 4 + character: 15 + end_position: + bytes: 60 + line: 4 + character: 16 + token_type: + type: Symbol + symbol: + +- start_position: + bytes: 60 + line: 4 + character: 16 + end_position: + bytes: 61 + line: 4 + character: 17 + token_type: + type: Number + text: "1" +- start_position: + bytes: 61 + line: 4 + character: 17 + end_position: + bytes: 61 + line: 4 + character: 17 + token_type: + type: Eof diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/numbers-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/numbers-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..af82c9c12545d5af7799d1ce7c306230627cd615 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/numbers-1/ast.snap @@ -0,0 +1,94 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 47 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/numbers-1 +--- +stmts: + - - Assignment: + var_list: + pairs: + - End: + Name: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Identifier + identifier: _ + trailing_trivia: + - start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Number + text: "0x02" + trailing_trivia: + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: "\n" + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/numbers-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/numbers-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..71e00d7f067f71424eb6d3efaf9b0639ac3251a5 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/numbers-1/source.lua @@ -0,0 +1 @@ +_ = 0x02 diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/numbers-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/numbers-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..6abe86fabf4c18e1fe237860bac63b31d83bfbe5 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/numbers-1/tokens.snap @@ -0,0 +1,83 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 40 +expression: tokens +input_file: full-moon/tests/cases/pass/numbers-1 +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Identifier + identifier: _ +- start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Number + text: "0x02" +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 9 + line: 2 + character: 1 + end_position: + bytes: 9 + line: 2 + character: 1 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/numeric-for-loop/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/numeric-for-loop/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..8d1cb626099dc9571c8d6565672299bc167c4cf8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/numeric-for-loop/ast.snap @@ -0,0 +1,736 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/numeric-for-loop +--- +stmts: + - - NumericFor: + for_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: for + trailing_trivia: + - start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " + index_variable: + leading_trivia: [] + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Identifier + identifier: index + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " + start: + Number: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Number + text: "1" + trailing_trivia: [] + start_end_comma: + leading_trivia: [] + token: + start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " + end: + Number: + leading_trivia: [] + token: + start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Number + text: "10" + trailing_trivia: + - start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Whitespace + characters: " " + end_step_comma: ~ + step: ~ + do_token: + leading_trivia: [] + token: + start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Whitespace + characters: " " + block: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 26 + line: 1 + character: 27 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 31 + line: 1 + character: 32 + end_position: + bytes: 32 + line: 1 + character: 33 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 32 + line: 1 + character: 33 + end_position: + bytes: 33 + line: 1 + character: 34 + token_type: + type: Whitespace + characters: " " + arguments: + pairs: + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 26 + line: 1 + character: 27 + end_position: + bytes: 31 + line: 1 + character: 32 + token_type: + type: Identifier + identifier: index + trailing_trivia: [] + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 33 + line: 1 + character: 34 + end_position: + bytes: 36 + line: 1 + character: 37 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 36 + line: 1 + character: 37 + end_position: + bytes: 37 + line: 1 + character: 37 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - NumericFor: + for_token: + leading_trivia: [] + token: + start_position: + bytes: 37 + line: 2 + character: 1 + end_position: + bytes: 40 + line: 2 + character: 4 + token_type: + type: Symbol + symbol: for + trailing_trivia: + - start_position: + bytes: 40 + line: 2 + character: 4 + end_position: + bytes: 41 + line: 2 + character: 5 + token_type: + type: Whitespace + characters: " " + index_variable: + leading_trivia: [] + token: + start_position: + bytes: 41 + line: 2 + character: 5 + end_position: + bytes: 42 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: _ + trailing_trivia: + - start_position: + bytes: 42 + line: 2 + character: 6 + end_position: + bytes: 43 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 43 + line: 2 + character: 7 + end_position: + bytes: 44 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 44 + line: 2 + character: 8 + end_position: + bytes: 45 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " + start: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 45 + line: 2 + character: 9 + end_position: + bytes: 50 + line: 2 + character: 14 + token_type: + type: Identifier + identifier: start + trailing_trivia: [] + start_end_comma: + leading_trivia: [] + token: + start_position: + bytes: 50 + line: 2 + character: 14 + end_position: + bytes: 51 + line: 2 + character: 15 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 51 + line: 2 + character: 15 + end_position: + bytes: 52 + line: 2 + character: 16 + token_type: + type: Whitespace + characters: " " + end: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 52 + line: 2 + character: 16 + end_position: + bytes: 57 + line: 2 + character: 21 + token_type: + type: Identifier + identifier: final + trailing_trivia: + - start_position: + bytes: 57 + line: 2 + character: 21 + end_position: + bytes: 58 + line: 2 + character: 22 + token_type: + type: Whitespace + characters: " " + end_step_comma: ~ + step: ~ + do_token: + leading_trivia: [] + token: + start_position: + bytes: 58 + line: 2 + character: 22 + end_position: + bytes: 60 + line: 2 + character: 24 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 60 + line: 2 + character: 24 + end_position: + bytes: 61 + line: 2 + character: 25 + token_type: + type: Whitespace + characters: " " + block: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 61 + line: 2 + character: 25 + end_position: + bytes: 64 + line: 2 + character: 28 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 64 + line: 2 + character: 28 + end_position: + bytes: 65 + line: 2 + character: 28 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - NumericFor: + for_token: + leading_trivia: [] + token: + start_position: + bytes: 65 + line: 3 + character: 1 + end_position: + bytes: 68 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: for + trailing_trivia: + - start_position: + bytes: 68 + line: 3 + character: 4 + end_position: + bytes: 69 + line: 3 + character: 5 + token_type: + type: Whitespace + characters: " " + index_variable: + leading_trivia: [] + token: + start_position: + bytes: 69 + line: 3 + character: 5 + end_position: + bytes: 70 + line: 3 + character: 6 + token_type: + type: Identifier + identifier: _ + trailing_trivia: + - start_position: + bytes: 70 + line: 3 + character: 6 + end_position: + bytes: 71 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 71 + line: 3 + character: 7 + end_position: + bytes: 72 + line: 3 + character: 8 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 72 + line: 3 + character: 8 + end_position: + bytes: 73 + line: 3 + character: 9 + token_type: + type: Whitespace + characters: " " + start: + Number: + leading_trivia: [] + token: + start_position: + bytes: 73 + line: 3 + character: 9 + end_position: + bytes: 74 + line: 3 + character: 10 + token_type: + type: Number + text: "1" + trailing_trivia: [] + start_end_comma: + leading_trivia: [] + token: + start_position: + bytes: 74 + line: 3 + character: 10 + end_position: + bytes: 75 + line: 3 + character: 11 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 75 + line: 3 + character: 11 + end_position: + bytes: 76 + line: 3 + character: 12 + token_type: + type: Whitespace + characters: " " + end: + Number: + leading_trivia: [] + token: + start_position: + bytes: 76 + line: 3 + character: 12 + end_position: + bytes: 78 + line: 3 + character: 14 + token_type: + type: Number + text: "10" + trailing_trivia: [] + end_step_comma: + leading_trivia: [] + token: + start_position: + bytes: 78 + line: 3 + character: 14 + end_position: + bytes: 79 + line: 3 + character: 15 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 79 + line: 3 + character: 15 + end_position: + bytes: 80 + line: 3 + character: 16 + token_type: + type: Whitespace + characters: " " + step: + Number: + leading_trivia: [] + token: + start_position: + bytes: 80 + line: 3 + character: 16 + end_position: + bytes: 81 + line: 3 + character: 17 + token_type: + type: Number + text: "2" + trailing_trivia: + - start_position: + bytes: 81 + line: 3 + character: 17 + end_position: + bytes: 82 + line: 3 + character: 18 + token_type: + type: Whitespace + characters: " " + do_token: + leading_trivia: [] + token: + start_position: + bytes: 82 + line: 3 + character: 18 + end_position: + bytes: 84 + line: 3 + character: 20 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 84 + line: 3 + character: 20 + end_position: + bytes: 85 + line: 3 + character: 21 + token_type: + type: Whitespace + characters: " " + block: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 85 + line: 3 + character: 21 + end_position: + bytes: 88 + line: 3 + character: 24 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/numeric-for-loop/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/numeric-for-loop/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..7d940114bf1fdb9a5d14aa85472c1787d93ab400 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/numeric-for-loop/source.lua @@ -0,0 +1,3 @@ +for index = 1, 10 do call(index) end +for _ = start, final do end +for _ = 1, 10, 2 do end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/numeric-for-loop/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/numeric-for-loop/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..8abf9e6e295bd5b31231791944df17a3907294a8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/numeric-for-loop/tokens.snap @@ -0,0 +1,589 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/numeric-for-loop + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: for +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Identifier + identifier: index +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Number + text: "1" +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Number + text: "10" +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 26 + line: 1 + character: 27 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 26 + line: 1 + character: 27 + end_position: + bytes: 31 + line: 1 + character: 32 + token_type: + type: Identifier + identifier: index +- start_position: + bytes: 31 + line: 1 + character: 32 + end_position: + bytes: 32 + line: 1 + character: 33 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 32 + line: 1 + character: 33 + end_position: + bytes: 33 + line: 1 + character: 34 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 33 + line: 1 + character: 34 + end_position: + bytes: 36 + line: 1 + character: 37 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 36 + line: 1 + character: 37 + end_position: + bytes: 37 + line: 1 + character: 37 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 37 + line: 2 + character: 1 + end_position: + bytes: 40 + line: 2 + character: 4 + token_type: + type: Symbol + symbol: for +- start_position: + bytes: 40 + line: 2 + character: 4 + end_position: + bytes: 41 + line: 2 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 41 + line: 2 + character: 5 + end_position: + bytes: 42 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: _ +- start_position: + bytes: 42 + line: 2 + character: 6 + end_position: + bytes: 43 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 43 + line: 2 + character: 7 + end_position: + bytes: 44 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 44 + line: 2 + character: 8 + end_position: + bytes: 45 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 45 + line: 2 + character: 9 + end_position: + bytes: 50 + line: 2 + character: 14 + token_type: + type: Identifier + identifier: start +- start_position: + bytes: 50 + line: 2 + character: 14 + end_position: + bytes: 51 + line: 2 + character: 15 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 51 + line: 2 + character: 15 + end_position: + bytes: 52 + line: 2 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 52 + line: 2 + character: 16 + end_position: + bytes: 57 + line: 2 + character: 21 + token_type: + type: Identifier + identifier: final +- start_position: + bytes: 57 + line: 2 + character: 21 + end_position: + bytes: 58 + line: 2 + character: 22 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 58 + line: 2 + character: 22 + end_position: + bytes: 60 + line: 2 + character: 24 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 60 + line: 2 + character: 24 + end_position: + bytes: 61 + line: 2 + character: 25 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 61 + line: 2 + character: 25 + end_position: + bytes: 64 + line: 2 + character: 28 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 64 + line: 2 + character: 28 + end_position: + bytes: 65 + line: 2 + character: 28 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 65 + line: 3 + character: 1 + end_position: + bytes: 68 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: for +- start_position: + bytes: 68 + line: 3 + character: 4 + end_position: + bytes: 69 + line: 3 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 69 + line: 3 + character: 5 + end_position: + bytes: 70 + line: 3 + character: 6 + token_type: + type: Identifier + identifier: _ +- start_position: + bytes: 70 + line: 3 + character: 6 + end_position: + bytes: 71 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 71 + line: 3 + character: 7 + end_position: + bytes: 72 + line: 3 + character: 8 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 72 + line: 3 + character: 8 + end_position: + bytes: 73 + line: 3 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 73 + line: 3 + character: 9 + end_position: + bytes: 74 + line: 3 + character: 10 + token_type: + type: Number + text: "1" +- start_position: + bytes: 74 + line: 3 + character: 10 + end_position: + bytes: 75 + line: 3 + character: 11 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 75 + line: 3 + character: 11 + end_position: + bytes: 76 + line: 3 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 76 + line: 3 + character: 12 + end_position: + bytes: 78 + line: 3 + character: 14 + token_type: + type: Number + text: "10" +- start_position: + bytes: 78 + line: 3 + character: 14 + end_position: + bytes: 79 + line: 3 + character: 15 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 79 + line: 3 + character: 15 + end_position: + bytes: 80 + line: 3 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 80 + line: 3 + character: 16 + end_position: + bytes: 81 + line: 3 + character: 17 + token_type: + type: Number + text: "2" +- start_position: + bytes: 81 + line: 3 + character: 17 + end_position: + bytes: 82 + line: 3 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 82 + line: 3 + character: 18 + end_position: + bytes: 84 + line: 3 + character: 20 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 84 + line: 3 + character: 20 + end_position: + bytes: 85 + line: 3 + character: 21 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 85 + line: 3 + character: 21 + end_position: + bytes: 88 + line: 3 + character: 24 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 88 + line: 3 + character: 24 + end_position: + bytes: 88 + line: 3 + character: 24 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/paren-expressions/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/paren-expressions/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..3da56a49ab45fa2eb4c96dec3013e83cd377c301 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/paren-expressions/ast.snap @@ -0,0 +1,252 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/paren-expressions +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + BinaryOperator: + lhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " + binop: + Plus: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: + + trailing_trivia: + - start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: " " + rhs: + Parentheses: + contained: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + expression: + BinaryOperator: + lhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Number + text: "2" + trailing_trivia: + - start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Whitespace + characters: " " + binop: + Minus: + leading_trivia: [] + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: "-" + trailing_trivia: + - start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Number + text: "3" + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/paren-expressions/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/paren-expressions/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..58013466ec37f5a50f181e33f332c25dd240d764 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/paren-expressions/source.lua @@ -0,0 +1 @@ +local x = 1 + (2 - 3) \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/paren-expressions/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/paren-expressions/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..93d1a56d6ee03dbc7f29e9d5e247e632c012c122 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/paren-expressions/tokens.snap @@ -0,0 +1,204 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/paren-expressions + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Number + text: "1" +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: + +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Number + text: "2" +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: "-" +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Number + text: "3" +- start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/repeat-until/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/repeat-until/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..119545d9581c2184ee4315d3430f400022cc8395 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/repeat-until/ast.snap @@ -0,0 +1,157 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/repeat-until +--- +stmts: + - - Repeat: + repeat_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: repeat + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 7 + line: 2 + character: 1 + end_position: + bytes: 8 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 8 + line: 2 + character: 2 + end_position: + bytes: 12 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 12 + line: 2 + character: 6 + end_position: + bytes: 13 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 13 + line: 2 + character: 7 + end_position: + bytes: 14 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 14 + line: 2 + character: 8 + end_position: + bytes: 15 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: [] + - ~ + until_token: + leading_trivia: [] + token: + start_position: + bytes: 15 + line: 3 + character: 1 + end_position: + bytes: 20 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: until + trailing_trivia: + - start_position: + bytes: 20 + line: 3 + character: 6 + end_position: + bytes: 21 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " + until: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 21 + line: 3 + character: 7 + end_position: + bytes: 30 + line: 3 + character: 16 + token_type: + type: Identifier + identifier: condition + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/repeat-until/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/repeat-until/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..e9b8e59278e2201a515311ae791e0d1119663f01 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/repeat-until/source.lua @@ -0,0 +1,3 @@ +repeat + call() +until condition \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/repeat-until/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/repeat-until/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..6a469aeb1c8537f2fa100f3007822176410fd25f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/repeat-until/tokens.snap @@ -0,0 +1,127 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/repeat-until + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: repeat +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 7 + line: 2 + character: 1 + end_position: + bytes: 8 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 8 + line: 2 + character: 2 + end_position: + bytes: 12 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 12 + line: 2 + character: 6 + end_position: + bytes: 13 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 13 + line: 2 + character: 7 + end_position: + bytes: 14 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 14 + line: 2 + character: 8 + end_position: + bytes: 15 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 15 + line: 3 + character: 1 + end_position: + bytes: 20 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: until +- start_position: + bytes: 20 + line: 3 + character: 6 + end_position: + bytes: 21 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 21 + line: 3 + character: 7 + end_position: + bytes: 30 + line: 3 + character: 16 + token_type: + type: Identifier + identifier: condition +- start_position: + bytes: 30 + line: 3 + character: 16 + end_position: + bytes: 30 + line: 3 + character: 16 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/return-break/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/return-break/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..eddce61d7f190e22e25a123791b2f8a9e30c7e61 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/return-break/ast.snap @@ -0,0 +1,346 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/return-break +--- +stmts: + - - Do: + do_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 3 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: [] + last_stmt: + - Return: + token: + leading_trivia: + - start_position: + bytes: 3 + line: 2 + character: 1 + end_position: + bytes: 4 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 4 + line: 2 + character: 2 + end_position: + bytes: 10 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 10 + line: 2 + character: 8 + end_position: + bytes: 11 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " + returns: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 11 + line: 2 + character: 9 + end_position: + bytes: 12 + line: 2 + character: 10 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 12 + line: 2 + character: 10 + end_position: + bytes: 13 + line: 2 + character: 10 + token_type: + type: Whitespace + characters: "\n" + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 13 + line: 3 + character: 1 + end_position: + bytes: 16 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 16 + line: 3 + character: 4 + end_position: + bytes: 17 + line: 3 + character: 4 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - Do: + do_token: + leading_trivia: + - start_position: + bytes: 17 + line: 4 + character: 1 + end_position: + bytes: 18 + line: 4 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 18 + line: 5 + character: 1 + end_position: + bytes: 20 + line: 5 + character: 3 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 20 + line: 5 + character: 3 + end_position: + bytes: 21 + line: 5 + character: 3 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: [] + last_stmt: + - Break: + leading_trivia: + - start_position: + bytes: 21 + line: 6 + character: 1 + end_position: + bytes: 22 + line: 6 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 22 + line: 6 + character: 2 + end_position: + bytes: 27 + line: 6 + character: 7 + token_type: + type: Symbol + symbol: break + trailing_trivia: + - start_position: + bytes: 27 + line: 6 + character: 7 + end_position: + bytes: 28 + line: 6 + character: 7 + token_type: + type: Whitespace + characters: "\n" + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 28 + line: 7 + character: 1 + end_position: + bytes: 31 + line: 7 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 31 + line: 7 + character: 4 + end_position: + bytes: 32 + line: 7 + character: 4 + token_type: + type: Whitespace + characters: "\n" + - ~ +last_stmt: + - Return: + token: + leading_trivia: + - start_position: + bytes: 32 + line: 8 + character: 1 + end_position: + bytes: 33 + line: 8 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 33 + line: 9 + character: 1 + end_position: + bytes: 39 + line: 9 + character: 7 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 39 + line: 9 + character: 7 + end_position: + bytes: 40 + line: 9 + character: 8 + token_type: + type: Whitespace + characters: " " + returns: + pairs: + - End: + FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 40 + line: 9 + character: 8 + end_position: + bytes: 44 + line: 9 + character: 12 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 44 + line: 9 + character: 12 + end_position: + bytes: 45 + line: 9 + character: 13 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 45 + line: 9 + character: 13 + end_position: + bytes: 46 + line: 9 + character: 14 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 46 + line: 9 + character: 14 + end_position: + bytes: 47 + line: 9 + character: 14 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/return-break/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/return-break/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..e0cf1504e36f78802b65885704de6750925f0cee --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/return-break/source.lua @@ -0,0 +1,9 @@ +do + return 1 +end + +do + break +end + +return call() diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/return-break/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/return-break/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..1038c32af324abd8c84be33f3b9991c153de0b11 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/return-break/tokens.snap @@ -0,0 +1,281 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/return-break + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 3 + line: 1 + character: 3 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 3 + line: 2 + character: 1 + end_position: + bytes: 4 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 4 + line: 2 + character: 2 + end_position: + bytes: 10 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 10 + line: 2 + character: 8 + end_position: + bytes: 11 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 11 + line: 2 + character: 9 + end_position: + bytes: 12 + line: 2 + character: 10 + token_type: + type: Number + text: "1" +- start_position: + bytes: 12 + line: 2 + character: 10 + end_position: + bytes: 13 + line: 2 + character: 10 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 13 + line: 3 + character: 1 + end_position: + bytes: 16 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 16 + line: 3 + character: 4 + end_position: + bytes: 17 + line: 3 + character: 4 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 17 + line: 4 + character: 1 + end_position: + bytes: 18 + line: 4 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 18 + line: 5 + character: 1 + end_position: + bytes: 20 + line: 5 + character: 3 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 20 + line: 5 + character: 3 + end_position: + bytes: 21 + line: 5 + character: 3 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 21 + line: 6 + character: 1 + end_position: + bytes: 22 + line: 6 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 22 + line: 6 + character: 2 + end_position: + bytes: 27 + line: 6 + character: 7 + token_type: + type: Symbol + symbol: break +- start_position: + bytes: 27 + line: 6 + character: 7 + end_position: + bytes: 28 + line: 6 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 28 + line: 7 + character: 1 + end_position: + bytes: 31 + line: 7 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 31 + line: 7 + character: 4 + end_position: + bytes: 32 + line: 7 + character: 4 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 32 + line: 8 + character: 1 + end_position: + bytes: 33 + line: 8 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 33 + line: 9 + character: 1 + end_position: + bytes: 39 + line: 9 + character: 7 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 39 + line: 9 + character: 7 + end_position: + bytes: 40 + line: 9 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 40 + line: 9 + character: 8 + end_position: + bytes: 44 + line: 9 + character: 12 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 44 + line: 9 + character: 12 + end_position: + bytes: 45 + line: 9 + character: 13 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 45 + line: 9 + character: 13 + end_position: + bytes: 46 + line: 9 + character: 14 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 46 + line: 9 + character: 14 + end_position: + bytes: 47 + line: 9 + character: 14 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 47 + line: 10 + character: 1 + end_position: + bytes: 47 + line: 10 + character: 1 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/semicolons-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/semicolons-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..04d72ebf735909fc449d0cfaca5a7409157120db --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/semicolons-1/ast.snap @@ -0,0 +1,264 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/semicolons-1 +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Number + text: "1" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: ; + trailing_trivia: + - start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Whitespace + characters: " " + - - Assignment: + var_list: + pairs: + - End: + Name: + leading_trivia: [] + token: + start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + BinaryOperator: + lhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Whitespace + characters: " " + binop: + Plus: + leading_trivia: [] + token: + start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Symbol + symbol: + + trailing_trivia: + - start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Number + text: "1" + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/semicolons-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/semicolons-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..60b7ec8f135bd3aa3491098a1d464165c82926dd --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/semicolons-1/source.lua @@ -0,0 +1 @@ +local x = 1; x = x + 1 \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/semicolons-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/semicolons-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..36c8231181107567f3338c6971648b78e42df2d9 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/semicolons-1/tokens.snap @@ -0,0 +1,215 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/semicolons-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Number + text: "1" +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: ; +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Symbol + symbol: + +- start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Number + text: "1" +- start_position: + bytes: 22 + line: 1 + character: 23 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/semicolons-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/semicolons-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..8424289c70984e2a9836c70d0361447db0d7ea9c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/semicolons-2/ast.snap @@ -0,0 +1,180 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/semicolons-2 +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: "\n" + - ~ +last_stmt: + - Return: + token: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 2 + character: 1 + end_position: + bytes: 18 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 18 + line: 2 + character: 7 + end_position: + bytes: 19 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: " " + returns: + pairs: + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 19 + line: 2 + character: 8 + end_position: + bytes: 20 + line: 2 + character: 9 + token_type: + type: Identifier + identifier: x + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 20 + line: 2 + character: 9 + end_position: + bytes: 21 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: ; + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/semicolons-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/semicolons-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..ad92d12511cd5d66b4e2914a23561a3be7f13423 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/semicolons-2/source.lua @@ -0,0 +1,2 @@ +local x = 1 +return x; \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/semicolons-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/semicolons-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..ba27d4cb0b7103dc57922d8f1104039cd96872ff --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/semicolons-2/tokens.snap @@ -0,0 +1,149 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/semicolons-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Number + text: "1" +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 12 + line: 2 + character: 1 + end_position: + bytes: 18 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 18 + line: 2 + character: 7 + end_position: + bytes: 19 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 19 + line: 2 + character: 8 + end_position: + bytes: 20 + line: 2 + character: 9 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 20 + line: 2 + character: 9 + end_position: + bytes: 21 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: ; +- start_position: + bytes: 21 + line: 2 + character: 10 + end_position: + bytes: 21 + line: 2 + character: 10 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/shebang/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/shebang/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..6b4590333049feafefbfb897ea61556ced598168 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/shebang/ast.snap @@ -0,0 +1,136 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 47 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/shebang +--- +stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Shebang + line: "#!/usr/bin/env lua" + - start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 19 + token_type: + type: Whitespace + characters: "\n" + - start_position: + bytes: 19 + line: 2 + character: 1 + end_position: + bytes: 20 + line: 2 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 20 + line: 3 + character: 1 + end_position: + bytes: 25 + line: 3 + character: 6 + token_type: + type: Identifier + identifier: print + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 25 + line: 3 + character: 6 + end_position: + bytes: 26 + line: 3 + character: 7 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 39 + line: 3 + character: 20 + end_position: + bytes: 40 + line: 3 + character: 21 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 26 + line: 3 + character: 7 + end_position: + bytes: 39 + line: 3 + character: 20 + token_type: + type: StringLiteral + literal: Hello world + quote_type: Double + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 40 + line: 3 + character: 21 + end_position: + bytes: 41 + line: 3 + character: 22 + token_type: + type: Symbol + symbol: ; + trailing_trivia: + - start_position: + bytes: 41 + line: 3 + character: 22 + end_position: + bytes: 42 + line: 3 + character: 22 + token_type: + type: Whitespace + characters: "\n" + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/shebang/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/shebang/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..202a2c86e15e42f6f9c9e03fed3d29e8d8dae8c8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/shebang/source.lua @@ -0,0 +1,3 @@ +#!/usr/bin/env lua + +print("Hello world"); diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/shebang/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/shebang/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..2cea764348cbc7e655b2504790775de59ffda207 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/shebang/tokens.snap @@ -0,0 +1,117 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 40 +expression: tokens +input_file: full-moon/tests/cases/pass/shebang +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Shebang + line: "#!/usr/bin/env lua" +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 19 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 19 + line: 2 + character: 1 + end_position: + bytes: 20 + line: 2 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 20 + line: 3 + character: 1 + end_position: + bytes: 25 + line: 3 + character: 6 + token_type: + type: Identifier + identifier: print +- start_position: + bytes: 25 + line: 3 + character: 6 + end_position: + bytes: 26 + line: 3 + character: 7 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 26 + line: 3 + character: 7 + end_position: + bytes: 39 + line: 3 + character: 20 + token_type: + type: StringLiteral + literal: Hello world + quote_type: Double +- start_position: + bytes: 39 + line: 3 + character: 20 + end_position: + bytes: 40 + line: 3 + character: 21 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 40 + line: 3 + character: 21 + end_position: + bytes: 41 + line: 3 + character: 22 + token_type: + type: Symbol + symbol: ; +- start_position: + bytes: 41 + line: 3 + character: 22 + end_position: + bytes: 42 + line: 3 + character: 22 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 42 + line: 4 + character: 1 + end_position: + bytes: 42 + line: 4 + character: 1 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..1dda28e0b207b4c17cdb61f34a01e04b54a9a083 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-1/ast.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/single-line-comment-1 + +--- +stmts: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..4a7ee141c49a52b2f2739210707f43a7310355a9 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-1/source.lua @@ -0,0 +1,2 @@ +-- hello world +-- and doge you too \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..92ea695756ef17487b11d691a6a0e93ed1089be9 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-1/tokens.snap @@ -0,0 +1,50 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/single-line-comment-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: SingleLineComment + comment: " hello world" +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 15 + line: 2 + character: 1 + end_position: + bytes: 34 + line: 2 + character: 20 + token_type: + type: SingleLineComment + comment: " and doge you too" +- start_position: + bytes: 34 + line: 2 + character: 20 + end_position: + bytes: 34 + line: 2 + character: 20 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..540e9bccbf9df50b8ad3d093fa04a3a858b74488 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-2/ast.snap @@ -0,0 +1,84 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/single-line-comment-2 + +--- +stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: SingleLineComment + comment: " This calls" + arguments: + pairs: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..2e1eecc9fcb42da193486c34b177f3c29c729135 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-2/source.lua @@ -0,0 +1 @@ +call() -- This calls \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..37c9362a1a0fc37cd4c6a5cffebf7c64b0fe8f3d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-2/tokens.snap @@ -0,0 +1,72 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/single-line-comment-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: SingleLineComment + comment: " This calls" +- start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-3/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-3/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..cb7ae8e84550a536b014fa2ef774a04ef1b61d80 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-3/ast.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/single-line-comment-3 + +--- +stmts: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-3/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-3/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..d83f9542073df80182e05ec677b7601d1b45c815 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-3/source.lua @@ -0,0 +1 @@ +-- tab in comment \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-3/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-3/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..3405d41f1ec1b7bc89caf7a5abcd269e113d3ebb --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-3/tokens.snap @@ -0,0 +1,28 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/single-line-comment-3 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: SingleLineComment + comment: " tab\tin comment" +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-4/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-4/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..1ffe9aa9560f459349f69f5025b53b98a93c0bc5 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-4/ast.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/single-line-comment-4 +--- +stmts: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-4/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-4/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..597200730a199752fcd4801d4922431e190cfe19 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-4/source.lua @@ -0,0 +1,4 @@ +--[comment +--(comment) +--[=comment +-- diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-4/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-4/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..e016797aa3785d1cf1ce9198cad3ae4cc7659db9 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-4/tokens.snap @@ -0,0 +1,105 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 38 +expression: tokens +input_file: full-moon/tests/cases/pass/single-line-comment-4 +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: SingleLineComment + comment: "[comment" +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 11 + line: 2 + character: 1 + end_position: + bytes: 22 + line: 2 + character: 12 + token_type: + type: SingleLineComment + comment: (comment) +- start_position: + bytes: 22 + line: 2 + character: 12 + end_position: + bytes: 23 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 23 + line: 3 + character: 1 + end_position: + bytes: 34 + line: 3 + character: 12 + token_type: + type: SingleLineComment + comment: "[=comment" +- start_position: + bytes: 34 + line: 3 + character: 12 + end_position: + bytes: 35 + line: 3 + character: 12 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 35 + line: 4 + character: 1 + end_position: + bytes: 37 + line: 4 + character: 3 + token_type: + type: SingleLineComment + comment: "" +- start_position: + bytes: 37 + line: 4 + character: 3 + end_position: + bytes: 38 + line: 4 + character: 3 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 38 + line: 5 + character: 1 + end_position: + bytes: 38 + line: 5 + character: 1 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-5/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-5/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..25ffa7323eae88bca773ee1d24c72dc04738b805 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-5/ast.snap @@ -0,0 +1,7 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +--- +stmts: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-5/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-5/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..2e983ada42af991e5711cfdbcd09a480cb2db9b4 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-5/source.lua @@ -0,0 +1,2 @@ +--`signatures` the value defaults to zero or is ignored if `signatures.length +--=== 0`. Whenever possible implementors should make an active decision about \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-5/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-5/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..f17080eb48eb15bbbe589da3861fa2f53b524838 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-5/tokens.snap @@ -0,0 +1,49 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 38 +expression: tokens +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 77 + line: 1 + character: 78 + token_type: + type: SingleLineComment + comment: "`signatures` the value defaults to zero or is ignored if `signatures.length" +- start_position: + bytes: 77 + line: 1 + character: 78 + end_position: + bytes: 78 + line: 1 + character: 78 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 78 + line: 2 + character: 1 + end_position: + bytes: 155 + line: 2 + character: 78 + token_type: + type: SingleLineComment + comment: "=== 0`. Whenever possible implementors should make an active decision about" +- start_position: + bytes: 155 + line: 2 + character: 78 + end_position: + bytes: 155 + line: 2 + character: 78 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-6/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-6/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..25ffa7323eae88bca773ee1d24c72dc04738b805 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-6/ast.snap @@ -0,0 +1,7 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +--- +stmts: [] + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-6/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-6/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..f822b93c6e2a069efe9627a794f7a850d30e0506 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-6/source.lua @@ -0,0 +1 @@ +--éšä¾¿å†™ç‚¹ä¸æ–‡ diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-6/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-6/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..223fb990f5cfa9bd319638ce8c5a4f32b2d52998 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-6/tokens.snap @@ -0,0 +1,39 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 40 +expression: tokens +input_file: full-moon/tests/cases/pass/single-line-comment-6 +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 20 + line: 1 + character: 9 + token_type: + type: SingleLineComment + comment: éšä¾¿å†™ç‚¹ä¸æ–‡ +- start_position: + bytes: 20 + line: 1 + character: 9 + end_position: + bytes: 21 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 21 + line: 2 + character: 1 + end_position: + bytes: 21 + line: 2 + character: 1 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-7/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-7/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..640d51b6f2e7b0491604561806e6fd4746b29d28 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-7/ast.snap @@ -0,0 +1,119 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/single-line-comment-7 +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: a + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: "\n" + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-7/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-7/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..2f5cb16638a4ecb10caf6ed3a52ca82e0f02773a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-7/source.lua @@ -0,0 +1,3 @@ +local a = 1 + +--}}å°è£…方便访问的接å£========================================== \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-7/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-7/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..87f28442323e4895dc087881fbdd3b07b21b71ff --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/single-line-comment-7/tokens.snap @@ -0,0 +1,127 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 40 +expression: tokens +input_file: full-moon/tests/cases/pass/single-line-comment-7 +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: a +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Number + text: "1" +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 12 + line: 2 + character: 1 + end_position: + bytes: 13 + line: 2 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 13 + line: 3 + character: 1 + end_position: + bytes: 86 + line: 3 + character: 56 + token_type: + type: SingleLineComment + comment: "}}å°è£…方便访问的接å£==========================================" +- start_position: + bytes: 86 + line: 3 + character: 56 + end_position: + bytes: 86 + line: 3 + character: 56 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/strings-escape-newline/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/strings-escape-newline/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..d36adc4ba7f808ec1ce7a2d54f564eb9fa58f2bf --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/strings-escape-newline/ast.snap @@ -0,0 +1,90 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/strings-escape-newline +--- +stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Identifier + identifier: print + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 17 + line: 2 + character: 6 + end_position: + bytes: 18 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 18 + line: 2 + character: 7 + end_position: + bytes: 19 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 17 + line: 2 + character: 6 + token_type: + type: StringLiteral + literal: "foo\\\n\tbar" + quote_type: Double + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/strings-escape-newline/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/strings-escape-newline/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..4ed7bf4c4a398d78e427190db476beae86c4e083 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/strings-escape-newline/source.lua @@ -0,0 +1,2 @@ +print("foo\ + bar") diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/strings-escape-newline/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/strings-escape-newline/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..173ab55cdc8312d902e796f6daa0000241d241fa --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/strings-escape-newline/tokens.snap @@ -0,0 +1,73 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/strings-escape-newline + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Identifier + identifier: print +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 17 + line: 2 + character: 6 + token_type: + type: StringLiteral + literal: "foo\\\n\tbar" + quote_type: Double +- start_position: + bytes: 17 + line: 2 + character: 6 + end_position: + bytes: 18 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 18 + line: 2 + character: 7 + end_position: + bytes: 19 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 19 + line: 3 + character: 1 + end_position: + bytes: 19 + line: 3 + character: 1 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/strings-escape/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/strings-escape/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..f1cdb6c7e25c7897f3493cd38cdf37066b02b0c3 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/strings-escape/ast.snap @@ -0,0 +1,385 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/strings-escape +--- +stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: StringLiteral + literal: "\\\\" + quote_type: Single + trailing_trivia: [] + - ~ + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 11 + line: 2 + character: 1 + end_position: + bytes: 15 + line: 2 + character: 5 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 15 + line: 2 + character: 5 + end_position: + bytes: 16 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 20 + line: 2 + character: 10 + end_position: + bytes: 21 + line: 2 + character: 11 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 21 + line: 2 + character: 11 + end_position: + bytes: 22 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 16 + line: 2 + character: 6 + end_position: + bytes: 20 + line: 2 + character: 10 + token_type: + type: StringLiteral + literal: "\\\\" + quote_type: Double + trailing_trivia: [] + - ~ + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 22 + line: 3 + character: 1 + end_position: + bytes: 26 + line: 3 + character: 5 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 26 + line: 3 + character: 5 + end_position: + bytes: 27 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 42 + line: 3 + character: 21 + end_position: + bytes: 43 + line: 3 + character: 22 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: + - End: + TableConstructor: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 27 + line: 3 + character: 6 + end_position: + bytes: 28 + line: 3 + character: 7 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 28 + line: 3 + character: 7 + end_position: + bytes: 29 + line: 3 + character: 8 + token_type: + type: Whitespace + characters: " " + - leading_trivia: [] + token: + start_position: + bytes: 41 + line: 3 + character: 20 + end_position: + bytes: 42 + line: 3 + character: 21 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: [] + fields: + pairs: + - End: + ExpressionKey: + brackets: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 29 + line: 3 + character: 8 + end_position: + bytes: 30 + line: 3 + character: 9 + token_type: + type: Symbol + symbol: "[" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 34 + line: 3 + character: 13 + end_position: + bytes: 35 + line: 3 + character: 14 + token_type: + type: Symbol + symbol: "]" + trailing_trivia: + - start_position: + bytes: 35 + line: 3 + character: 14 + end_position: + bytes: 36 + line: 3 + character: 15 + token_type: + type: Whitespace + characters: " " + key: + String: + leading_trivia: [] + token: + start_position: + bytes: 30 + line: 3 + character: 9 + end_position: + bytes: 34 + line: 3 + character: 13 + token_type: + type: StringLiteral + literal: "\\\\" + quote_type: Double + trailing_trivia: [] + equal: + leading_trivia: [] + token: + start_position: + bytes: 36 + line: 3 + character: 15 + end_position: + bytes: 37 + line: 3 + character: 16 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 37 + line: 3 + character: 16 + end_position: + bytes: 38 + line: 3 + character: 17 + token_type: + type: Whitespace + characters: " " + value: + String: + leading_trivia: [] + token: + start_position: + bytes: 38 + line: 3 + character: 17 + end_position: + bytes: 40 + line: 3 + character: 19 + token_type: + type: StringLiteral + literal: "" + quote_type: Double + trailing_trivia: + - start_position: + bytes: 40 + line: 3 + character: 19 + end_position: + bytes: 41 + line: 3 + character: 20 + token_type: + type: Whitespace + characters: " " + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/strings-escape/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/strings-escape/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..5c2e4f13d231361933cbae8755a71218b113c259 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/strings-escape/source.lua @@ -0,0 +1,3 @@ +call('\\') +call("\\") +call({ ["\\"] = "" }) \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/strings-escape/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/strings-escape/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..b5501309d80ac54e702558312504a3d54f33ba5f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/strings-escape/tokens.snap @@ -0,0 +1,284 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 38 +expression: tokens +input_file: full-moon/tests/cases/pass/strings-escape +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: StringLiteral + literal: "\\\\" + quote_type: Single +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 11 + line: 2 + character: 1 + end_position: + bytes: 15 + line: 2 + character: 5 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 15 + line: 2 + character: 5 + end_position: + bytes: 16 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 16 + line: 2 + character: 6 + end_position: + bytes: 20 + line: 2 + character: 10 + token_type: + type: StringLiteral + literal: "\\\\" + quote_type: Double +- start_position: + bytes: 20 + line: 2 + character: 10 + end_position: + bytes: 21 + line: 2 + character: 11 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 21 + line: 2 + character: 11 + end_position: + bytes: 22 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 22 + line: 3 + character: 1 + end_position: + bytes: 26 + line: 3 + character: 5 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 26 + line: 3 + character: 5 + end_position: + bytes: 27 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 27 + line: 3 + character: 6 + end_position: + bytes: 28 + line: 3 + character: 7 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 28 + line: 3 + character: 7 + end_position: + bytes: 29 + line: 3 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 29 + line: 3 + character: 8 + end_position: + bytes: 30 + line: 3 + character: 9 + token_type: + type: Symbol + symbol: "[" +- start_position: + bytes: 30 + line: 3 + character: 9 + end_position: + bytes: 34 + line: 3 + character: 13 + token_type: + type: StringLiteral + literal: "\\\\" + quote_type: Double +- start_position: + bytes: 34 + line: 3 + character: 13 + end_position: + bytes: 35 + line: 3 + character: 14 + token_type: + type: Symbol + symbol: "]" +- start_position: + bytes: 35 + line: 3 + character: 14 + end_position: + bytes: 36 + line: 3 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 36 + line: 3 + character: 15 + end_position: + bytes: 37 + line: 3 + character: 16 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 37 + line: 3 + character: 16 + end_position: + bytes: 38 + line: 3 + character: 17 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 38 + line: 3 + character: 17 + end_position: + bytes: 40 + line: 3 + character: 19 + token_type: + type: StringLiteral + literal: "" + quote_type: Double +- start_position: + bytes: 40 + line: 3 + character: 19 + end_position: + bytes: 41 + line: 3 + character: 20 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 41 + line: 3 + character: 20 + end_position: + bytes: 42 + line: 3 + character: 21 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 42 + line: 3 + character: 21 + end_position: + bytes: 43 + line: 3 + character: 22 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 43 + line: 3 + character: 22 + end_position: + bytes: 43 + line: 3 + character: 22 + token_type: + type: Eof diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/strings/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/strings/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..4a9bf05e5a8754368737630fb89cf4f04172ba43 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/strings/ast.snap @@ -0,0 +1,325 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/strings +--- +stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: StringLiteral + literal: double + quote_type: Double + trailing_trivia: [] + - ~ + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 15 + line: 2 + character: 1 + end_position: + bytes: 19 + line: 2 + character: 5 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 19 + line: 2 + character: 5 + end_position: + bytes: 20 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 28 + line: 2 + character: 14 + end_position: + bytes: 29 + line: 2 + character: 15 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 29 + line: 2 + character: 15 + end_position: + bytes: 30 + line: 2 + character: 15 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 20 + line: 2 + character: 6 + end_position: + bytes: 28 + line: 2 + character: 14 + token_type: + type: StringLiteral + literal: single + quote_type: Single + trailing_trivia: [] + - ~ + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 30 + line: 3 + character: 1 + end_position: + bytes: 34 + line: 3 + character: 5 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 34 + line: 3 + character: 5 + end_position: + bytes: 35 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 45 + line: 3 + character: 16 + end_position: + bytes: 46 + line: 3 + character: 17 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 46 + line: 3 + character: 17 + end_position: + bytes: 47 + line: 3 + character: 17 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 35 + line: 3 + character: 6 + end_position: + bytes: 45 + line: 3 + character: 16 + token_type: + type: StringLiteral + literal: "foo\\nbar" + quote_type: Double + trailing_trivia: [] + - ~ + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 47 + line: 4 + character: 1 + end_position: + bytes: 51 + line: 4 + character: 5 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 51 + line: 4 + character: 5 + end_position: + bytes: 52 + line: 4 + character: 6 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 54 + line: 4 + character: 8 + end_position: + bytes: 55 + line: 4 + character: 9 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 52 + line: 4 + character: 6 + end_position: + bytes: 54 + line: 4 + character: 8 + token_type: + type: StringLiteral + literal: "" + quote_type: Double + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/strings/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/strings/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..9f41684004d9b9140f464e02ce594e1799b0944d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/strings/source.lua @@ -0,0 +1,4 @@ +call("double") +call('single') +call("foo\nbar") +call("") \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/strings/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/strings/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..a8ec42c7d790b56cc0987a609484e68f259e6253 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/strings/tokens.snap @@ -0,0 +1,230 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/strings + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: StringLiteral + literal: double + quote_type: Double +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 15 + line: 2 + character: 1 + end_position: + bytes: 19 + line: 2 + character: 5 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 19 + line: 2 + character: 5 + end_position: + bytes: 20 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 20 + line: 2 + character: 6 + end_position: + bytes: 28 + line: 2 + character: 14 + token_type: + type: StringLiteral + literal: single + quote_type: Single +- start_position: + bytes: 28 + line: 2 + character: 14 + end_position: + bytes: 29 + line: 2 + character: 15 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 29 + line: 2 + character: 15 + end_position: + bytes: 30 + line: 2 + character: 15 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 30 + line: 3 + character: 1 + end_position: + bytes: 34 + line: 3 + character: 5 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 34 + line: 3 + character: 5 + end_position: + bytes: 35 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 35 + line: 3 + character: 6 + end_position: + bytes: 45 + line: 3 + character: 16 + token_type: + type: StringLiteral + literal: "foo\\nbar" + quote_type: Double +- start_position: + bytes: 45 + line: 3 + character: 16 + end_position: + bytes: 46 + line: 3 + character: 17 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 46 + line: 3 + character: 17 + end_position: + bytes: 47 + line: 3 + character: 17 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 47 + line: 4 + character: 1 + end_position: + bytes: 51 + line: 4 + character: 5 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 51 + line: 4 + character: 5 + end_position: + bytes: 52 + line: 4 + character: 6 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 52 + line: 4 + character: 6 + end_position: + bytes: 54 + line: 4 + character: 8 + token_type: + type: StringLiteral + literal: "" + quote_type: Double +- start_position: + bytes: 54 + line: 4 + character: 8 + end_position: + bytes: 55 + line: 4 + character: 9 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 55 + line: 4 + character: 9 + end_position: + bytes: 55 + line: 4 + character: 9 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-1/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..9c19b7a601b6872a5a9d6169f9c10f1b342b4463 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-1/ast.snap @@ -0,0 +1,137 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/table-constructor-1 +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + TableConstructor: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: "\n" + - leading_trivia: [] + token: + start_position: + bytes: 12 + line: 2 + character: 1 + end_position: + bytes: 13 + line: 2 + character: 2 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: [] + fields: + pairs: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-1/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..0e6aaa89b07dffc68f90d9027e66d1d44fb32e4c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-1/source.lua @@ -0,0 +1,2 @@ +local x = { +} \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-1/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..5e2fdf499cd592531c0cf426043245421cf447de --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-1/tokens.snap @@ -0,0 +1,116 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/table-constructor-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 12 + line: 2 + character: 1 + end_position: + bytes: 13 + line: 2 + character: 2 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 13 + line: 2 + character: 2 + end_position: + bytes: 13 + line: 2 + character: 2 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-2/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..6c551af251f099d52aec59481bab54ee9ad501ee --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-2/ast.snap @@ -0,0 +1,227 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/table-constructor-2 +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + TableConstructor: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: [] + fields: + pairs: + - Punctuated: + - NoKey: + Number: + leading_trivia: [] + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Number + text: "1" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: " " + - Punctuated: + - NoKey: + Number: + leading_trivia: [] + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Number + text: "2" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Whitespace + characters: " " + - End: + NoKey: + Number: + leading_trivia: [] + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Number + text: "3" + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-2/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..7192737b68b1fff85b23782eb0c07e5c88f21287 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-2/source.lua @@ -0,0 +1 @@ +local x = {1, 2, 3} \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-2/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..7a2f30eb7c55f27cfce2a2b77dc0789c614764e6 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-2/tokens.snap @@ -0,0 +1,182 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/table-constructor-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Number + text: "1" +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Number + text: "2" +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Number + text: "3" +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-3/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-3/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..d8685812fac81f3df22f02cc8bcaf517d17f338c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-3/ast.snap @@ -0,0 +1,910 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/table-constructor-3 +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + TableConstructor: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: "\n" + - leading_trivia: [] + token: + start_position: + bytes: 35 + line: 5 + character: 1 + end_position: + bytes: 36 + line: 5 + character: 2 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: + - start_position: + bytes: 36 + line: 5 + character: 2 + end_position: + bytes: 37 + line: 5 + character: 2 + token_type: + type: Whitespace + characters: "\n" + fields: + pairs: + - Punctuated: + - NameKey: + key: + leading_trivia: + - start_position: + bytes: 12 + line: 2 + character: 1 + end_position: + bytes: 13 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 13 + line: 2 + character: 2 + end_position: + bytes: 14 + line: 2 + character: 3 + token_type: + type: Identifier + identifier: a + trailing_trivia: + - start_position: + bytes: 14 + line: 2 + character: 3 + end_position: + bytes: 15 + line: 2 + character: 4 + token_type: + type: Whitespace + characters: " " + equal: + leading_trivia: [] + token: + start_position: + bytes: 15 + line: 2 + character: 4 + end_position: + bytes: 16 + line: 2 + character: 5 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 16 + line: 2 + character: 5 + end_position: + bytes: 17 + line: 2 + character: 6 + token_type: + type: Whitespace + characters: " " + value: + Number: + leading_trivia: [] + token: + start_position: + bytes: 17 + line: 2 + character: 6 + end_position: + bytes: 18 + line: 2 + character: 7 + token_type: + type: Number + text: "1" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 18 + line: 2 + character: 7 + end_position: + bytes: 19 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 19 + line: 2 + character: 8 + end_position: + bytes: 20 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: "\n" + - Punctuated: + - NameKey: + key: + leading_trivia: + - start_position: + bytes: 20 + line: 3 + character: 1 + end_position: + bytes: 21 + line: 3 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 21 + line: 3 + character: 2 + end_position: + bytes: 22 + line: 3 + character: 3 + token_type: + type: Identifier + identifier: b + trailing_trivia: + - start_position: + bytes: 22 + line: 3 + character: 3 + end_position: + bytes: 23 + line: 3 + character: 4 + token_type: + type: Whitespace + characters: " " + equal: + leading_trivia: [] + token: + start_position: + bytes: 23 + line: 3 + character: 4 + end_position: + bytes: 24 + line: 3 + character: 5 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 24 + line: 3 + character: 5 + end_position: + bytes: 25 + line: 3 + character: 6 + token_type: + type: Whitespace + characters: " " + value: + Number: + leading_trivia: [] + token: + start_position: + bytes: 25 + line: 3 + character: 6 + end_position: + bytes: 26 + line: 3 + character: 7 + token_type: + type: Number + text: "2" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 26 + line: 3 + character: 7 + end_position: + bytes: 27 + line: 3 + character: 8 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 27 + line: 3 + character: 8 + end_position: + bytes: 28 + line: 3 + character: 8 + token_type: + type: Whitespace + characters: "\n" + - End: + NameKey: + key: + leading_trivia: + - start_position: + bytes: 28 + line: 4 + character: 1 + end_position: + bytes: 29 + line: 4 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 29 + line: 4 + character: 2 + end_position: + bytes: 30 + line: 4 + character: 3 + token_type: + type: Identifier + identifier: c + trailing_trivia: + - start_position: + bytes: 30 + line: 4 + character: 3 + end_position: + bytes: 31 + line: 4 + character: 4 + token_type: + type: Whitespace + characters: " " + equal: + leading_trivia: [] + token: + start_position: + bytes: 31 + line: 4 + character: 4 + end_position: + bytes: 32 + line: 4 + character: 5 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 32 + line: 4 + character: 5 + end_position: + bytes: 33 + line: 4 + character: 6 + token_type: + type: Whitespace + characters: " " + value: + Number: + leading_trivia: [] + token: + start_position: + bytes: 33 + line: 4 + character: 6 + end_position: + bytes: 34 + line: 4 + character: 7 + token_type: + type: Number + text: "3" + trailing_trivia: + - start_position: + bytes: 34 + line: 4 + character: 7 + end_position: + bytes: 35 + line: 4 + character: 7 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: + - start_position: + bytes: 37 + line: 6 + character: 1 + end_position: + bytes: 38 + line: 6 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 38 + line: 7 + character: 1 + end_position: + bytes: 43 + line: 7 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 43 + line: 7 + character: 6 + end_position: + bytes: 44 + line: 7 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 44 + line: 7 + character: 7 + end_position: + bytes: 45 + line: 7 + character: 8 + token_type: + type: Identifier + identifier: y + trailing_trivia: + - start_position: + bytes: 45 + line: 7 + character: 8 + end_position: + bytes: 46 + line: 7 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 46 + line: 7 + character: 9 + end_position: + bytes: 47 + line: 7 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 47 + line: 7 + character: 10 + end_position: + bytes: 48 + line: 7 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + TableConstructor: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 48 + line: 7 + character: 11 + end_position: + bytes: 49 + line: 7 + character: 12 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 49 + line: 7 + character: 12 + end_position: + bytes: 50 + line: 7 + character: 12 + token_type: + type: Whitespace + characters: "\n" + - leading_trivia: [] + token: + start_position: + bytes: 74 + line: 11 + character: 1 + end_position: + bytes: 75 + line: 11 + character: 2 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: [] + fields: + pairs: + - Punctuated: + - NameKey: + key: + leading_trivia: + - start_position: + bytes: 50 + line: 8 + character: 1 + end_position: + bytes: 51 + line: 8 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 51 + line: 8 + character: 2 + end_position: + bytes: 52 + line: 8 + character: 3 + token_type: + type: Identifier + identifier: a + trailing_trivia: + - start_position: + bytes: 52 + line: 8 + character: 3 + end_position: + bytes: 53 + line: 8 + character: 4 + token_type: + type: Whitespace + characters: " " + equal: + leading_trivia: [] + token: + start_position: + bytes: 53 + line: 8 + character: 4 + end_position: + bytes: 54 + line: 8 + character: 5 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 54 + line: 8 + character: 5 + end_position: + bytes: 55 + line: 8 + character: 6 + token_type: + type: Whitespace + characters: " " + value: + Number: + leading_trivia: [] + token: + start_position: + bytes: 55 + line: 8 + character: 6 + end_position: + bytes: 56 + line: 8 + character: 7 + token_type: + type: Number + text: "1" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 56 + line: 8 + character: 7 + end_position: + bytes: 57 + line: 8 + character: 8 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 57 + line: 8 + character: 8 + end_position: + bytes: 58 + line: 8 + character: 8 + token_type: + type: Whitespace + characters: "\n" + - Punctuated: + - NameKey: + key: + leading_trivia: + - start_position: + bytes: 58 + line: 9 + character: 1 + end_position: + bytes: 59 + line: 9 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 59 + line: 9 + character: 2 + end_position: + bytes: 60 + line: 9 + character: 3 + token_type: + type: Identifier + identifier: b + trailing_trivia: + - start_position: + bytes: 60 + line: 9 + character: 3 + end_position: + bytes: 61 + line: 9 + character: 4 + token_type: + type: Whitespace + characters: " " + equal: + leading_trivia: [] + token: + start_position: + bytes: 61 + line: 9 + character: 4 + end_position: + bytes: 62 + line: 9 + character: 5 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 62 + line: 9 + character: 5 + end_position: + bytes: 63 + line: 9 + character: 6 + token_type: + type: Whitespace + characters: " " + value: + Number: + leading_trivia: [] + token: + start_position: + bytes: 63 + line: 9 + character: 6 + end_position: + bytes: 64 + line: 9 + character: 7 + token_type: + type: Number + text: "2" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 64 + line: 9 + character: 7 + end_position: + bytes: 65 + line: 9 + character: 8 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 65 + line: 9 + character: 8 + end_position: + bytes: 66 + line: 9 + character: 8 + token_type: + type: Whitespace + characters: "\n" + - Punctuated: + - NameKey: + key: + leading_trivia: + - start_position: + bytes: 66 + line: 10 + character: 1 + end_position: + bytes: 67 + line: 10 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 67 + line: 10 + character: 2 + end_position: + bytes: 68 + line: 10 + character: 3 + token_type: + type: Identifier + identifier: c + trailing_trivia: + - start_position: + bytes: 68 + line: 10 + character: 3 + end_position: + bytes: 69 + line: 10 + character: 4 + token_type: + type: Whitespace + characters: " " + equal: + leading_trivia: [] + token: + start_position: + bytes: 69 + line: 10 + character: 4 + end_position: + bytes: 70 + line: 10 + character: 5 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 70 + line: 10 + character: 5 + end_position: + bytes: 71 + line: 10 + character: 6 + token_type: + type: Whitespace + characters: " " + value: + Number: + leading_trivia: [] + token: + start_position: + bytes: 71 + line: 10 + character: 6 + end_position: + bytes: 72 + line: 10 + character: 7 + token_type: + type: Number + text: "3" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 72 + line: 10 + character: 7 + end_position: + bytes: 73 + line: 10 + character: 8 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 73 + line: 10 + character: 8 + end_position: + bytes: 74 + line: 10 + character: 8 + token_type: + type: Whitespace + characters: "\n" + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-3/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-3/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..17788fde433a50da8218a7d3714e5109ce93eaaa --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-3/source.lua @@ -0,0 +1,11 @@ +local x = { + a = 1, + b = 2, + c = 3 +} + +local y = { + a = 1, + b = 2, + c = 3, +} \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-3/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-3/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..761cd2d22a57646d11125c459b8db9be57a052b9 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-3/tokens.snap @@ -0,0 +1,754 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/table-constructor-3 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 12 + line: 2 + character: 1 + end_position: + bytes: 13 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 13 + line: 2 + character: 2 + end_position: + bytes: 14 + line: 2 + character: 3 + token_type: + type: Identifier + identifier: a +- start_position: + bytes: 14 + line: 2 + character: 3 + end_position: + bytes: 15 + line: 2 + character: 4 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 15 + line: 2 + character: 4 + end_position: + bytes: 16 + line: 2 + character: 5 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 16 + line: 2 + character: 5 + end_position: + bytes: 17 + line: 2 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 17 + line: 2 + character: 6 + end_position: + bytes: 18 + line: 2 + character: 7 + token_type: + type: Number + text: "1" +- start_position: + bytes: 18 + line: 2 + character: 7 + end_position: + bytes: 19 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 19 + line: 2 + character: 8 + end_position: + bytes: 20 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 20 + line: 3 + character: 1 + end_position: + bytes: 21 + line: 3 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 21 + line: 3 + character: 2 + end_position: + bytes: 22 + line: 3 + character: 3 + token_type: + type: Identifier + identifier: b +- start_position: + bytes: 22 + line: 3 + character: 3 + end_position: + bytes: 23 + line: 3 + character: 4 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 23 + line: 3 + character: 4 + end_position: + bytes: 24 + line: 3 + character: 5 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 24 + line: 3 + character: 5 + end_position: + bytes: 25 + line: 3 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 25 + line: 3 + character: 6 + end_position: + bytes: 26 + line: 3 + character: 7 + token_type: + type: Number + text: "2" +- start_position: + bytes: 26 + line: 3 + character: 7 + end_position: + bytes: 27 + line: 3 + character: 8 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 27 + line: 3 + character: 8 + end_position: + bytes: 28 + line: 3 + character: 8 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 28 + line: 4 + character: 1 + end_position: + bytes: 29 + line: 4 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 29 + line: 4 + character: 2 + end_position: + bytes: 30 + line: 4 + character: 3 + token_type: + type: Identifier + identifier: c +- start_position: + bytes: 30 + line: 4 + character: 3 + end_position: + bytes: 31 + line: 4 + character: 4 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 31 + line: 4 + character: 4 + end_position: + bytes: 32 + line: 4 + character: 5 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 32 + line: 4 + character: 5 + end_position: + bytes: 33 + line: 4 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 33 + line: 4 + character: 6 + end_position: + bytes: 34 + line: 4 + character: 7 + token_type: + type: Number + text: "3" +- start_position: + bytes: 34 + line: 4 + character: 7 + end_position: + bytes: 35 + line: 4 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 35 + line: 5 + character: 1 + end_position: + bytes: 36 + line: 5 + character: 2 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 36 + line: 5 + character: 2 + end_position: + bytes: 37 + line: 5 + character: 2 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 37 + line: 6 + character: 1 + end_position: + bytes: 38 + line: 6 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 38 + line: 7 + character: 1 + end_position: + bytes: 43 + line: 7 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 43 + line: 7 + character: 6 + end_position: + bytes: 44 + line: 7 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 44 + line: 7 + character: 7 + end_position: + bytes: 45 + line: 7 + character: 8 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 45 + line: 7 + character: 8 + end_position: + bytes: 46 + line: 7 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 46 + line: 7 + character: 9 + end_position: + bytes: 47 + line: 7 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 47 + line: 7 + character: 10 + end_position: + bytes: 48 + line: 7 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 48 + line: 7 + character: 11 + end_position: + bytes: 49 + line: 7 + character: 12 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 49 + line: 7 + character: 12 + end_position: + bytes: 50 + line: 7 + character: 12 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 50 + line: 8 + character: 1 + end_position: + bytes: 51 + line: 8 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 51 + line: 8 + character: 2 + end_position: + bytes: 52 + line: 8 + character: 3 + token_type: + type: Identifier + identifier: a +- start_position: + bytes: 52 + line: 8 + character: 3 + end_position: + bytes: 53 + line: 8 + character: 4 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 53 + line: 8 + character: 4 + end_position: + bytes: 54 + line: 8 + character: 5 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 54 + line: 8 + character: 5 + end_position: + bytes: 55 + line: 8 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 55 + line: 8 + character: 6 + end_position: + bytes: 56 + line: 8 + character: 7 + token_type: + type: Number + text: "1" +- start_position: + bytes: 56 + line: 8 + character: 7 + end_position: + bytes: 57 + line: 8 + character: 8 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 57 + line: 8 + character: 8 + end_position: + bytes: 58 + line: 8 + character: 8 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 58 + line: 9 + character: 1 + end_position: + bytes: 59 + line: 9 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 59 + line: 9 + character: 2 + end_position: + bytes: 60 + line: 9 + character: 3 + token_type: + type: Identifier + identifier: b +- start_position: + bytes: 60 + line: 9 + character: 3 + end_position: + bytes: 61 + line: 9 + character: 4 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 61 + line: 9 + character: 4 + end_position: + bytes: 62 + line: 9 + character: 5 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 62 + line: 9 + character: 5 + end_position: + bytes: 63 + line: 9 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 63 + line: 9 + character: 6 + end_position: + bytes: 64 + line: 9 + character: 7 + token_type: + type: Number + text: "2" +- start_position: + bytes: 64 + line: 9 + character: 7 + end_position: + bytes: 65 + line: 9 + character: 8 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 65 + line: 9 + character: 8 + end_position: + bytes: 66 + line: 9 + character: 8 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 66 + line: 10 + character: 1 + end_position: + bytes: 67 + line: 10 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 67 + line: 10 + character: 2 + end_position: + bytes: 68 + line: 10 + character: 3 + token_type: + type: Identifier + identifier: c +- start_position: + bytes: 68 + line: 10 + character: 3 + end_position: + bytes: 69 + line: 10 + character: 4 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 69 + line: 10 + character: 4 + end_position: + bytes: 70 + line: 10 + character: 5 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 70 + line: 10 + character: 5 + end_position: + bytes: 71 + line: 10 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 71 + line: 10 + character: 6 + end_position: + bytes: 72 + line: 10 + character: 7 + token_type: + type: Number + text: "3" +- start_position: + bytes: 72 + line: 10 + character: 7 + end_position: + bytes: 73 + line: 10 + character: 8 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 73 + line: 10 + character: 8 + end_position: + bytes: 74 + line: 10 + character: 8 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 74 + line: 11 + character: 1 + end_position: + bytes: 75 + line: 11 + character: 2 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 75 + line: 11 + character: 2 + end_position: + bytes: 75 + line: 11 + character: 2 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-4/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-4/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..2a0f13bf60d006d359678e369ec1293bed464fa6 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-4/ast.snap @@ -0,0 +1,312 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/table-constructor-4 +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + TableConstructor: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: "\n" + - leading_trivia: [] + token: + start_position: + bytes: 27 + line: 3 + character: 1 + end_position: + bytes: 28 + line: 3 + character: 2 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: [] + fields: + pairs: + - Punctuated: + - ExpressionKey: + brackets: + tokens: + - leading_trivia: + - start_position: + bytes: 12 + line: 2 + character: 1 + end_position: + bytes: 13 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 13 + line: 2 + character: 2 + end_position: + bytes: 14 + line: 2 + character: 3 + token_type: + type: Symbol + symbol: "[" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 20 + line: 2 + character: 9 + end_position: + bytes: 21 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: "]" + trailing_trivia: + - start_position: + bytes: 21 + line: 2 + character: 10 + end_position: + bytes: 22 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: " " + key: + FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 14 + line: 2 + character: 3 + end_position: + bytes: 18 + line: 2 + character: 7 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 18 + line: 2 + character: 7 + end_position: + bytes: 19 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 19 + line: 2 + character: 8 + end_position: + bytes: 20 + line: 2 + character: 9 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: [] + equal: + leading_trivia: [] + token: + start_position: + bytes: 22 + line: 2 + character: 11 + end_position: + bytes: 23 + line: 2 + character: 12 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 23 + line: 2 + character: 12 + end_position: + bytes: 24 + line: 2 + character: 13 + token_type: + type: Whitespace + characters: " " + value: + Number: + leading_trivia: [] + token: + start_position: + bytes: 24 + line: 2 + character: 13 + end_position: + bytes: 25 + line: 2 + character: 14 + token_type: + type: Number + text: "1" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 25 + line: 2 + character: 14 + end_position: + bytes: 26 + line: 2 + character: 15 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 26 + line: 2 + character: 15 + end_position: + bytes: 27 + line: 2 + character: 15 + token_type: + type: Whitespace + characters: "\n" + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-4/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-4/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..5870b430addf13cce10eb2fe2e1d9b55d771ff02 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-4/source.lua @@ -0,0 +1,3 @@ +local x = { + [call()] = 1, +} \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-4/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-4/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..4e46a8ac4270b8cefbef53eee5dc61360246d326 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-4/tokens.snap @@ -0,0 +1,248 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/table-constructor-4 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 12 + line: 2 + character: 1 + end_position: + bytes: 13 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 13 + line: 2 + character: 2 + end_position: + bytes: 14 + line: 2 + character: 3 + token_type: + type: Symbol + symbol: "[" +- start_position: + bytes: 14 + line: 2 + character: 3 + end_position: + bytes: 18 + line: 2 + character: 7 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 18 + line: 2 + character: 7 + end_position: + bytes: 19 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 19 + line: 2 + character: 8 + end_position: + bytes: 20 + line: 2 + character: 9 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 20 + line: 2 + character: 9 + end_position: + bytes: 21 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: "]" +- start_position: + bytes: 21 + line: 2 + character: 10 + end_position: + bytes: 22 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 22 + line: 2 + character: 11 + end_position: + bytes: 23 + line: 2 + character: 12 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 23 + line: 2 + character: 12 + end_position: + bytes: 24 + line: 2 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 24 + line: 2 + character: 13 + end_position: + bytes: 25 + line: 2 + character: 14 + token_type: + type: Number + text: "1" +- start_position: + bytes: 25 + line: 2 + character: 14 + end_position: + bytes: 26 + line: 2 + character: 15 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 26 + line: 2 + character: 15 + end_position: + bytes: 27 + line: 2 + character: 15 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 27 + line: 3 + character: 1 + end_position: + bytes: 28 + line: 3 + character: 2 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 28 + line: 3 + character: 2 + end_position: + bytes: 28 + line: 3 + character: 2 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-5/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-5/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..7f0856dfebaf5c2782e2f8be222a75071705e2ac --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-5/ast.snap @@ -0,0 +1,365 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/table-constructor-5 +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + TableConstructor: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: "\n" + - leading_trivia: [] + token: + start_position: + bytes: 31 + line: 4 + character: 1 + end_position: + bytes: 32 + line: 4 + character: 2 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: [] + fields: + pairs: + - Punctuated: + - ExpressionKey: + brackets: + tokens: + - leading_trivia: + - start_position: + bytes: 12 + line: 2 + character: 1 + end_position: + bytes: 13 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 13 + line: 2 + character: 2 + end_position: + bytes: 14 + line: 2 + character: 3 + token_type: + type: Symbol + symbol: "[" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 20 + line: 2 + character: 9 + end_position: + bytes: 21 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: "]" + trailing_trivia: + - start_position: + bytes: 21 + line: 2 + character: 10 + end_position: + bytes: 22 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: " " + key: + FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 14 + line: 2 + character: 3 + end_position: + bytes: 18 + line: 2 + character: 7 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 18 + line: 2 + character: 7 + end_position: + bytes: 19 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 19 + line: 2 + character: 8 + end_position: + bytes: 20 + line: 2 + character: 9 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: [] + equal: + leading_trivia: [] + token: + start_position: + bytes: 22 + line: 2 + character: 11 + end_position: + bytes: 23 + line: 2 + character: 12 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 23 + line: 2 + character: 12 + end_position: + bytes: 24 + line: 2 + character: 13 + token_type: + type: Whitespace + characters: " " + value: + Number: + leading_trivia: [] + token: + start_position: + bytes: 24 + line: 2 + character: 13 + end_position: + bytes: 25 + line: 2 + character: 14 + token_type: + type: Number + text: "1" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 25 + line: 2 + character: 14 + end_position: + bytes: 26 + line: 2 + character: 15 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 26 + line: 2 + character: 15 + end_position: + bytes: 27 + line: 2 + character: 15 + token_type: + type: Whitespace + characters: "\n" + - Punctuated: + - NoKey: + Number: + leading_trivia: + - start_position: + bytes: 27 + line: 3 + character: 1 + end_position: + bytes: 28 + line: 3 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 28 + line: 3 + character: 2 + end_position: + bytes: 29 + line: 3 + character: 3 + token_type: + type: Number + text: "2" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 29 + line: 3 + character: 3 + end_position: + bytes: 30 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 30 + line: 3 + character: 4 + end_position: + bytes: 31 + line: 3 + character: 4 + token_type: + type: Whitespace + characters: "\n" + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-5/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-5/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..afeca1f3193ea8ea9de2b0c2cc1f5305b377ec6d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-5/source.lua @@ -0,0 +1,4 @@ +local x = { + [call()] = 1, + 2, +} \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-5/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-5/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..9afbf2ab61614418a5ba6a3ef77c5e9fded223f5 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-5/tokens.snap @@ -0,0 +1,292 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/table-constructor-5 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 12 + line: 2 + character: 1 + end_position: + bytes: 13 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 13 + line: 2 + character: 2 + end_position: + bytes: 14 + line: 2 + character: 3 + token_type: + type: Symbol + symbol: "[" +- start_position: + bytes: 14 + line: 2 + character: 3 + end_position: + bytes: 18 + line: 2 + character: 7 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 18 + line: 2 + character: 7 + end_position: + bytes: 19 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 19 + line: 2 + character: 8 + end_position: + bytes: 20 + line: 2 + character: 9 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 20 + line: 2 + character: 9 + end_position: + bytes: 21 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: "]" +- start_position: + bytes: 21 + line: 2 + character: 10 + end_position: + bytes: 22 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 22 + line: 2 + character: 11 + end_position: + bytes: 23 + line: 2 + character: 12 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 23 + line: 2 + character: 12 + end_position: + bytes: 24 + line: 2 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 24 + line: 2 + character: 13 + end_position: + bytes: 25 + line: 2 + character: 14 + token_type: + type: Number + text: "1" +- start_position: + bytes: 25 + line: 2 + character: 14 + end_position: + bytes: 26 + line: 2 + character: 15 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 26 + line: 2 + character: 15 + end_position: + bytes: 27 + line: 2 + character: 15 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 27 + line: 3 + character: 1 + end_position: + bytes: 28 + line: 3 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 28 + line: 3 + character: 2 + end_position: + bytes: 29 + line: 3 + character: 3 + token_type: + type: Number + text: "2" +- start_position: + bytes: 29 + line: 3 + character: 3 + end_position: + bytes: 30 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 30 + line: 3 + character: 4 + end_position: + bytes: 31 + line: 3 + character: 4 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 31 + line: 4 + character: 1 + end_position: + bytes: 32 + line: 4 + character: 2 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 32 + line: 4 + character: 2 + end_position: + bytes: 32 + line: 4 + character: 2 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-6/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-6/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..886715070621d4e0b3906eebe40e86312b5bccb1 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-6/ast.snap @@ -0,0 +1,166 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/table-constructor-6 +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Identifier + identifier: foo + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + TableConstructor: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: " " + - leading_trivia: [] + token: + start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: [] + fields: + pairs: + - End: + NoKey: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Identifier + identifier: bar + trailing_trivia: + - start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Whitespace + characters: " " + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-6/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-6/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..c5bde7d58f1679761c28e454f7fdf6cfa6fdd060 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-6/source.lua @@ -0,0 +1 @@ +local foo = { bar } \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-6/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-6/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..e3466688ef71c1d51e53b686863457ea1fed0990 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructor-6/tokens.snap @@ -0,0 +1,138 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/table-constructor-6 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Identifier + identifier: bar +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/table-constructors-7/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructors-7/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..37b8b5085e7c42452f1befba56aca5ebb20f74d5 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructors-7/ast.snap @@ -0,0 +1,551 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/table-constructors-7 +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Identifier + identifier: blacklist + trailing_trivia: + - start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + TableConstructor: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 20 + token_type: + type: Whitespace + characters: "\n" + - leading_trivia: [] + token: + start_position: + bytes: 215 + line: 5 + character: 1 + end_position: + bytes: 216 + line: 5 + character: 2 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: [] + fields: + pairs: + - Punctuated: + - ExpressionKey: + brackets: + tokens: + - leading_trivia: + - start_position: + bytes: 20 + line: 2 + character: 1 + end_position: + bytes: 21 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 21 + line: 2 + character: 2 + end_position: + bytes: 22 + line: 2 + character: 3 + token_type: + type: Symbol + symbol: "[" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 55 + line: 2 + character: 36 + end_position: + bytes: 56 + line: 2 + character: 37 + token_type: + type: Symbol + symbol: "]" + trailing_trivia: + - start_position: + bytes: 56 + line: 2 + character: 37 + end_position: + bytes: 57 + line: 2 + character: 38 + token_type: + type: Whitespace + characters: " " + key: + String: + leading_trivia: [] + token: + start_position: + bytes: 22 + line: 2 + character: 3 + end_position: + bytes: 55 + line: 2 + character: 36 + token_type: + type: StringLiteral + literal: Audio file failed to load (18). + quote_type: Double + trailing_trivia: [] + equal: + leading_trivia: [] + token: + start_position: + bytes: 57 + line: 2 + character: 38 + end_position: + bytes: 58 + line: 2 + character: 39 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 58 + line: 2 + character: 39 + end_position: + bytes: 59 + line: 2 + character: 40 + token_type: + type: Whitespace + characters: " " + value: + Symbol: + leading_trivia: [] + token: + start_position: + bytes: 59 + line: 2 + character: 40 + end_position: + bytes: 63 + line: 2 + character: 44 + token_type: + type: Symbol + symbol: "true" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 63 + line: 2 + character: 44 + end_position: + bytes: 64 + line: 2 + character: 45 + token_type: + type: Symbol + symbol: ; + trailing_trivia: + - start_position: + bytes: 64 + line: 2 + character: 45 + end_position: + bytes: 65 + line: 2 + character: 45 + token_type: + type: Whitespace + characters: "\n" + - Punctuated: + - ExpressionKey: + brackets: + tokens: + - leading_trivia: + - start_position: + bytes: 65 + line: 3 + character: 1 + end_position: + bytes: 66 + line: 3 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 66 + line: 3 + character: 2 + end_position: + bytes: 67 + line: 3 + character: 3 + token_type: + type: Symbol + symbol: "[" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 131 + line: 3 + character: 67 + end_position: + bytes: 132 + line: 3 + character: 68 + token_type: + type: Symbol + symbol: "]" + trailing_trivia: + - start_position: + bytes: 132 + line: 3 + character: 68 + end_position: + bytes: 133 + line: 3 + character: 69 + token_type: + type: Whitespace + characters: " " + key: + String: + leading_trivia: [] + token: + start_position: + bytes: 67 + line: 3 + character: 3 + end_position: + bytes: 131 + line: 3 + character: 67 + token_type: + type: StringLiteral + literal: HTTP 0 (HTTP 429 (HTTP/1.1 429 ProvisionedThroughputExceeded)) + quote_type: Double + trailing_trivia: [] + equal: + leading_trivia: [] + token: + start_position: + bytes: 133 + line: 3 + character: 69 + end_position: + bytes: 134 + line: 3 + character: 70 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 134 + line: 3 + character: 70 + end_position: + bytes: 135 + line: 3 + character: 71 + token_type: + type: Whitespace + characters: " " + value: + Symbol: + leading_trivia: [] + token: + start_position: + bytes: 135 + line: 3 + character: 71 + end_position: + bytes: 139 + line: 3 + character: 75 + token_type: + type: Symbol + symbol: "true" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 139 + line: 3 + character: 75 + end_position: + bytes: 140 + line: 3 + character: 76 + token_type: + type: Symbol + symbol: ; + trailing_trivia: + - start_position: + bytes: 140 + line: 3 + character: 76 + end_position: + bytes: 141 + line: 3 + character: 76 + token_type: + type: Whitespace + characters: "\n" + - Punctuated: + - ExpressionKey: + brackets: + tokens: + - leading_trivia: + - start_position: + bytes: 141 + line: 4 + character: 1 + end_position: + bytes: 142 + line: 4 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 142 + line: 4 + character: 2 + end_position: + bytes: 143 + line: 4 + character: 3 + token_type: + type: Symbol + symbol: "[" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 205 + line: 4 + character: 65 + end_position: + bytes: 206 + line: 4 + character: 66 + token_type: + type: Symbol + symbol: "]" + trailing_trivia: + - start_position: + bytes: 206 + line: 4 + character: 66 + end_position: + bytes: 207 + line: 4 + character: 67 + token_type: + type: Whitespace + characters: " " + key: + String: + leading_trivia: [] + token: + start_position: + bytes: 143 + line: 4 + character: 3 + end_position: + bytes: 205 + line: 4 + character: 65 + token_type: + type: StringLiteral + literal: LoadCharacter can only be called when Player is in the world + quote_type: Double + trailing_trivia: [] + equal: + leading_trivia: [] + token: + start_position: + bytes: 207 + line: 4 + character: 67 + end_position: + bytes: 208 + line: 4 + character: 68 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 208 + line: 4 + character: 68 + end_position: + bytes: 209 + line: 4 + character: 69 + token_type: + type: Whitespace + characters: " " + value: + Symbol: + leading_trivia: [] + token: + start_position: + bytes: 209 + line: 4 + character: 69 + end_position: + bytes: 213 + line: 4 + character: 73 + token_type: + type: Symbol + symbol: "true" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 213 + line: 4 + character: 73 + end_position: + bytes: 214 + line: 4 + character: 74 + token_type: + type: Symbol + symbol: ; + trailing_trivia: + - start_position: + bytes: 214 + line: 4 + character: 74 + end_position: + bytes: 215 + line: 4 + character: 74 + token_type: + type: Whitespace + characters: "\n" + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/table-constructors-7/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructors-7/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..5688c7fcc49b1834a94f17de9391c2a3e6085823 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructors-7/source.lua @@ -0,0 +1,5 @@ +local blacklist = { + ["Audio file failed to load (18)."] = true; + ["HTTP 0 (HTTP 429 (HTTP/1.1 429 ProvisionedThroughputExceeded))"] = true; + ["LoadCharacter can only be called when Player is in the world"] = true; +} \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/table-constructors-7/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructors-7/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..fb2a7b02baf12a4d557652af1ca1e443770f86c5 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructors-7/tokens.snap @@ -0,0 +1,449 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/table-constructors-7 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Identifier + identifier: blacklist +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 20 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 20 + line: 2 + character: 1 + end_position: + bytes: 21 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 21 + line: 2 + character: 2 + end_position: + bytes: 22 + line: 2 + character: 3 + token_type: + type: Symbol + symbol: "[" +- start_position: + bytes: 22 + line: 2 + character: 3 + end_position: + bytes: 55 + line: 2 + character: 36 + token_type: + type: StringLiteral + literal: Audio file failed to load (18). + quote_type: Double +- start_position: + bytes: 55 + line: 2 + character: 36 + end_position: + bytes: 56 + line: 2 + character: 37 + token_type: + type: Symbol + symbol: "]" +- start_position: + bytes: 56 + line: 2 + character: 37 + end_position: + bytes: 57 + line: 2 + character: 38 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 57 + line: 2 + character: 38 + end_position: + bytes: 58 + line: 2 + character: 39 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 58 + line: 2 + character: 39 + end_position: + bytes: 59 + line: 2 + character: 40 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 59 + line: 2 + character: 40 + end_position: + bytes: 63 + line: 2 + character: 44 + token_type: + type: Symbol + symbol: "true" +- start_position: + bytes: 63 + line: 2 + character: 44 + end_position: + bytes: 64 + line: 2 + character: 45 + token_type: + type: Symbol + symbol: ; +- start_position: + bytes: 64 + line: 2 + character: 45 + end_position: + bytes: 65 + line: 2 + character: 45 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 65 + line: 3 + character: 1 + end_position: + bytes: 66 + line: 3 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 66 + line: 3 + character: 2 + end_position: + bytes: 67 + line: 3 + character: 3 + token_type: + type: Symbol + symbol: "[" +- start_position: + bytes: 67 + line: 3 + character: 3 + end_position: + bytes: 131 + line: 3 + character: 67 + token_type: + type: StringLiteral + literal: HTTP 0 (HTTP 429 (HTTP/1.1 429 ProvisionedThroughputExceeded)) + quote_type: Double +- start_position: + bytes: 131 + line: 3 + character: 67 + end_position: + bytes: 132 + line: 3 + character: 68 + token_type: + type: Symbol + symbol: "]" +- start_position: + bytes: 132 + line: 3 + character: 68 + end_position: + bytes: 133 + line: 3 + character: 69 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 133 + line: 3 + character: 69 + end_position: + bytes: 134 + line: 3 + character: 70 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 134 + line: 3 + character: 70 + end_position: + bytes: 135 + line: 3 + character: 71 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 135 + line: 3 + character: 71 + end_position: + bytes: 139 + line: 3 + character: 75 + token_type: + type: Symbol + symbol: "true" +- start_position: + bytes: 139 + line: 3 + character: 75 + end_position: + bytes: 140 + line: 3 + character: 76 + token_type: + type: Symbol + symbol: ; +- start_position: + bytes: 140 + line: 3 + character: 76 + end_position: + bytes: 141 + line: 3 + character: 76 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 141 + line: 4 + character: 1 + end_position: + bytes: 142 + line: 4 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 142 + line: 4 + character: 2 + end_position: + bytes: 143 + line: 4 + character: 3 + token_type: + type: Symbol + symbol: "[" +- start_position: + bytes: 143 + line: 4 + character: 3 + end_position: + bytes: 205 + line: 4 + character: 65 + token_type: + type: StringLiteral + literal: LoadCharacter can only be called when Player is in the world + quote_type: Double +- start_position: + bytes: 205 + line: 4 + character: 65 + end_position: + bytes: 206 + line: 4 + character: 66 + token_type: + type: Symbol + symbol: "]" +- start_position: + bytes: 206 + line: 4 + character: 66 + end_position: + bytes: 207 + line: 4 + character: 67 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 207 + line: 4 + character: 67 + end_position: + bytes: 208 + line: 4 + character: 68 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 208 + line: 4 + character: 68 + end_position: + bytes: 209 + line: 4 + character: 69 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 209 + line: 4 + character: 69 + end_position: + bytes: 213 + line: 4 + character: 73 + token_type: + type: Symbol + symbol: "true" +- start_position: + bytes: 213 + line: 4 + character: 73 + end_position: + bytes: 214 + line: 4 + character: 74 + token_type: + type: Symbol + symbol: ; +- start_position: + bytes: 214 + line: 4 + character: 74 + end_position: + bytes: 215 + line: 4 + character: 74 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 215 + line: 5 + character: 1 + end_position: + bytes: 216 + line: 5 + character: 2 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 216 + line: 5 + character: 2 + end_position: + bytes: 216 + line: 5 + character: 2 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/table-constructors-8/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructors-8/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..3cdcdf5ca90685f4ddf5cb2b271b9200b0bc7bca --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructors-8/ast.snap @@ -0,0 +1,373 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/table-constructors-8 +--- +stmts: [] +last_stmt: + - Return: + token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + returns: + pairs: + - End: + TableConstructor: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: "\n" + - leading_trivia: [] + token: + start_position: + bytes: 129 + line: 4 + character: 1 + end_position: + bytes: 130 + line: 4 + character: 2 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: + - start_position: + bytes: 130 + line: 4 + character: 2 + end_position: + bytes: 131 + line: 4 + character: 2 + token_type: + type: Whitespace + characters: "\n" + fields: + pairs: + - Punctuated: + - ExpressionKey: + brackets: + tokens: + - leading_trivia: + - start_position: + bytes: 9 + line: 2 + character: 1 + end_position: + bytes: 10 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 10 + line: 2 + character: 2 + end_position: + bytes: 11 + line: 2 + character: 3 + token_type: + type: Symbol + symbol: "[" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 36 + line: 2 + character: 28 + end_position: + bytes: 37 + line: 2 + character: 29 + token_type: + type: Symbol + symbol: "]" + trailing_trivia: + - start_position: + bytes: 37 + line: 2 + character: 29 + end_position: + bytes: 38 + line: 2 + character: 30 + token_type: + type: Whitespace + characters: " " + key: + String: + leading_trivia: [] + token: + start_position: + bytes: 11 + line: 2 + character: 3 + end_position: + bytes: 36 + line: 2 + character: 28 + token_type: + type: StringLiteral + literal: "Noob Attack: Periastron" + quote_type: Double + trailing_trivia: [] + equal: + leading_trivia: [] + token: + start_position: + bytes: 38 + line: 2 + character: 30 + end_position: + bytes: 39 + line: 2 + character: 31 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 39 + line: 2 + character: 31 + end_position: + bytes: 40 + line: 2 + character: 32 + token_type: + type: Whitespace + characters: " " + value: + String: + leading_trivia: [] + token: + start_position: + bytes: 40 + line: 2 + character: 32 + end_position: + bytes: 66 + line: 2 + character: 58 + token_type: + type: StringLiteral + literal: Noob Attack - Periastron + quote_type: Double + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 66 + line: 2 + character: 58 + end_position: + bytes: 67 + line: 2 + character: 59 + token_type: + type: Symbol + symbol: ; + trailing_trivia: + - start_position: + bytes: 67 + line: 2 + character: 59 + end_position: + bytes: 68 + line: 2 + character: 59 + token_type: + type: Whitespace + characters: "\n" + - Punctuated: + - ExpressionKey: + brackets: + tokens: + - leading_trivia: + - start_position: + bytes: 68 + line: 3 + character: 1 + end_position: + bytes: 69 + line: 3 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 69 + line: 3 + character: 2 + end_position: + bytes: 70 + line: 3 + character: 3 + token_type: + type: Symbol + symbol: "[" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 97 + line: 3 + character: 28 + end_position: + bytes: 98 + line: 3 + character: 29 + token_type: + type: Symbol + symbol: "]" + trailing_trivia: + - start_position: + bytes: 98 + line: 3 + character: 29 + end_position: + bytes: 99 + line: 3 + character: 30 + token_type: + type: Whitespace + characters: " " + key: + String: + leading_trivia: [] + token: + start_position: + bytes: 70 + line: 3 + character: 3 + end_position: + bytes: 97 + line: 3 + character: 28 + token_type: + type: StringLiteral + literal: Noob Attack꞉ Periastron + quote_type: Double + trailing_trivia: [] + equal: + leading_trivia: [] + token: + start_position: + bytes: 99 + line: 3 + character: 30 + end_position: + bytes: 100 + line: 3 + character: 31 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 100 + line: 3 + character: 31 + end_position: + bytes: 101 + line: 3 + character: 32 + token_type: + type: Whitespace + characters: " " + value: + String: + leading_trivia: [] + token: + start_position: + bytes: 101 + line: 3 + character: 32 + end_position: + bytes: 127 + line: 3 + character: 58 + token_type: + type: StringLiteral + literal: Noob Attack - Periastron + quote_type: Double + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 127 + line: 3 + character: 58 + end_position: + bytes: 128 + line: 3 + character: 59 + token_type: + type: Symbol + symbol: ; + trailing_trivia: + - start_position: + bytes: 128 + line: 3 + character: 59 + end_position: + bytes: 129 + line: 3 + character: 59 + token_type: + type: Whitespace + characters: "\n" + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/table-constructors-8/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructors-8/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..ed28eaa45238ffa7912a24d7391e5a6170b83a27 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructors-8/source.lua @@ -0,0 +1,4 @@ +return { + ["Noob Attack: Periastron"] = "Noob Attack - Periastron"; + ["Noob Attack꞉ Periastron"] = "Noob Attack - Periastron"; +} diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/table-constructors-8/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructors-8/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..d6eda3400bd38928373f235e82b3cf751bf567e7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/table-constructors-8/tokens.snap @@ -0,0 +1,307 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/table-constructors-8 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 9 + line: 2 + character: 1 + end_position: + bytes: 10 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 10 + line: 2 + character: 2 + end_position: + bytes: 11 + line: 2 + character: 3 + token_type: + type: Symbol + symbol: "[" +- start_position: + bytes: 11 + line: 2 + character: 3 + end_position: + bytes: 36 + line: 2 + character: 28 + token_type: + type: StringLiteral + literal: "Noob Attack: Periastron" + quote_type: Double +- start_position: + bytes: 36 + line: 2 + character: 28 + end_position: + bytes: 37 + line: 2 + character: 29 + token_type: + type: Symbol + symbol: "]" +- start_position: + bytes: 37 + line: 2 + character: 29 + end_position: + bytes: 38 + line: 2 + character: 30 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 38 + line: 2 + character: 30 + end_position: + bytes: 39 + line: 2 + character: 31 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 39 + line: 2 + character: 31 + end_position: + bytes: 40 + line: 2 + character: 32 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 40 + line: 2 + character: 32 + end_position: + bytes: 66 + line: 2 + character: 58 + token_type: + type: StringLiteral + literal: Noob Attack - Periastron + quote_type: Double +- start_position: + bytes: 66 + line: 2 + character: 58 + end_position: + bytes: 67 + line: 2 + character: 59 + token_type: + type: Symbol + symbol: ; +- start_position: + bytes: 67 + line: 2 + character: 59 + end_position: + bytes: 68 + line: 2 + character: 59 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 68 + line: 3 + character: 1 + end_position: + bytes: 69 + line: 3 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 69 + line: 3 + character: 2 + end_position: + bytes: 70 + line: 3 + character: 3 + token_type: + type: Symbol + symbol: "[" +- start_position: + bytes: 70 + line: 3 + character: 3 + end_position: + bytes: 97 + line: 3 + character: 28 + token_type: + type: StringLiteral + literal: Noob Attack꞉ Periastron + quote_type: Double +- start_position: + bytes: 97 + line: 3 + character: 28 + end_position: + bytes: 98 + line: 3 + character: 29 + token_type: + type: Symbol + symbol: "]" +- start_position: + bytes: 98 + line: 3 + character: 29 + end_position: + bytes: 99 + line: 3 + character: 30 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 99 + line: 3 + character: 30 + end_position: + bytes: 100 + line: 3 + character: 31 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 100 + line: 3 + character: 31 + end_position: + bytes: 101 + line: 3 + character: 32 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 101 + line: 3 + character: 32 + end_position: + bytes: 127 + line: 3 + character: 58 + token_type: + type: StringLiteral + literal: Noob Attack - Periastron + quote_type: Double +- start_position: + bytes: 127 + line: 3 + character: 58 + end_position: + bytes: 128 + line: 3 + character: 59 + token_type: + type: Symbol + symbol: ; +- start_position: + bytes: 128 + line: 3 + character: 59 + end_position: + bytes: 129 + line: 3 + character: 59 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 129 + line: 4 + character: 1 + end_position: + bytes: 130 + line: 4 + character: 2 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 130 + line: 4 + character: 2 + end_position: + bytes: 131 + line: 4 + character: 2 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 131 + line: 5 + character: 1 + end_position: + bytes: 131 + line: 5 + character: 1 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/trivia-parsing/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/trivia-parsing/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..7164014c8468bde2f130a2e4edd1deb0805164c4 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/trivia-parsing/ast.snap @@ -0,0 +1,734 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/trivia-parsing +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Identifier + identifier: foo + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Identifier + identifier: bar + trailing_trivia: + - start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Whitespace + characters: " " + - start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 35 + line: 1 + character: 36 + token_type: + type: SingleLineComment + comment: " trailing comment" + - start_position: + bytes: 35 + line: 1 + character: 36 + end_position: + bytes: 36 + line: 1 + character: 36 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: + - start_position: + bytes: 36 + line: 2 + character: 1 + end_position: + bytes: 37 + line: 2 + character: 1 + token_type: + type: Whitespace + characters: "\n" + - start_position: + bytes: 37 + line: 3 + character: 1 + end_position: + bytes: 55 + line: 3 + character: 19 + token_type: + type: SingleLineComment + comment: " leading comment" + - start_position: + bytes: 55 + line: 3 + character: 19 + end_position: + bytes: 56 + line: 3 + character: 19 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 56 + line: 4 + character: 1 + end_position: + bytes: 61 + line: 4 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 61 + line: 4 + character: 6 + end_position: + bytes: 62 + line: 4 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 62 + line: 4 + character: 7 + end_position: + bytes: 65 + line: 4 + character: 10 + token_type: + type: Identifier + identifier: bar + trailing_trivia: + - start_position: + bytes: 65 + line: 4 + character: 10 + end_position: + bytes: 66 + line: 4 + character: 11 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 66 + line: 4 + character: 11 + end_position: + bytes: 67 + line: 4 + character: 12 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 67 + line: 4 + character: 12 + end_position: + bytes: 68 + line: 4 + character: 13 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 68 + line: 4 + character: 13 + end_position: + bytes: 71 + line: 4 + character: 16 + token_type: + type: Identifier + identifier: baz + trailing_trivia: + - start_position: + bytes: 71 + line: 4 + character: 16 + end_position: + bytes: 72 + line: 4 + character: 16 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 72 + line: 5 + character: 1 + end_position: + bytes: 77 + line: 5 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 77 + line: 5 + character: 6 + end_position: + bytes: 78 + line: 5 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 78 + line: 5 + character: 7 + end_position: + bytes: 81 + line: 5 + character: 10 + token_type: + type: Identifier + identifier: baz + trailing_trivia: + - start_position: + bytes: 81 + line: 5 + character: 10 + end_position: + bytes: 82 + line: 5 + character: 11 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 82 + line: 5 + character: 11 + end_position: + bytes: 83 + line: 5 + character: 12 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 83 + line: 5 + character: 12 + end_position: + bytes: 84 + line: 5 + character: 13 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 84 + line: 5 + character: 13 + end_position: + bytes: 87 + line: 5 + character: 16 + token_type: + type: Identifier + identifier: foo + trailing_trivia: + - start_position: + bytes: 87 + line: 5 + character: 16 + end_position: + bytes: 88 + line: 5 + character: 16 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - Do: + do_token: + leading_trivia: + - start_position: + bytes: 88 + line: 6 + character: 1 + end_position: + bytes: 89 + line: 6 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 89 + line: 7 + character: 1 + end_position: + bytes: 91 + line: 7 + character: 3 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 91 + line: 7 + character: 3 + end_position: + bytes: 92 + line: 7 + character: 3 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - LocalAssignment: + local_token: + leading_trivia: + - start_position: + bytes: 92 + line: 8 + character: 1 + end_position: + bytes: 93 + line: 8 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 93 + line: 8 + character: 2 + end_position: + bytes: 98 + line: 8 + character: 7 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 98 + line: 8 + character: 7 + end_position: + bytes: 99 + line: 8 + character: 8 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 99 + line: 8 + character: 8 + end_position: + bytes: 102 + line: 8 + character: 11 + token_type: + type: Identifier + identifier: foo + trailing_trivia: + - start_position: + bytes: 102 + line: 8 + character: 11 + end_position: + bytes: 103 + line: 8 + character: 12 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 103 + line: 8 + character: 12 + end_position: + bytes: 104 + line: 8 + character: 13 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 104 + line: 8 + character: 13 + end_position: + bytes: 105 + line: 8 + character: 14 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 105 + line: 8 + character: 14 + end_position: + bytes: 108 + line: 8 + character: 17 + token_type: + type: Identifier + identifier: bar + trailing_trivia: + - start_position: + bytes: 108 + line: 8 + character: 17 + end_position: + bytes: 109 + line: 8 + character: 17 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: + - start_position: + bytes: 109 + line: 9 + character: 1 + end_position: + bytes: 110 + line: 9 + character: 2 + token_type: + type: Whitespace + characters: "\t" + - start_position: + bytes: 110 + line: 9 + character: 2 + end_position: + bytes: 120 + line: 9 + character: 12 + token_type: + type: SingleLineComment + comment: " comment" + - start_position: + bytes: 120 + line: 9 + character: 12 + end_position: + bytes: 121 + line: 9 + character: 12 + token_type: + type: Whitespace + characters: "\n" + - start_position: + bytes: 121 + line: 10 + character: 1 + end_position: + bytes: 122 + line: 10 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 122 + line: 10 + character: 2 + end_position: + bytes: 127 + line: 10 + character: 7 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 127 + line: 10 + character: 7 + end_position: + bytes: 128 + line: 10 + character: 8 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 128 + line: 10 + character: 8 + end_position: + bytes: 131 + line: 10 + character: 11 + token_type: + type: Identifier + identifier: bar + trailing_trivia: + - start_position: + bytes: 131 + line: 10 + character: 11 + end_position: + bytes: 132 + line: 10 + character: 12 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 132 + line: 10 + character: 12 + end_position: + bytes: 133 + line: 10 + character: 13 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 133 + line: 10 + character: 13 + end_position: + bytes: 134 + line: 10 + character: 14 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 134 + line: 10 + character: 14 + end_position: + bytes: 137 + line: 10 + character: 17 + token_type: + type: Identifier + identifier: baz + trailing_trivia: + - start_position: + bytes: 137 + line: 10 + character: 17 + end_position: + bytes: 138 + line: 10 + character: 17 + token_type: + type: Whitespace + characters: "\n" + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 138 + line: 11 + character: 1 + end_position: + bytes: 141 + line: 11 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/trivia-parsing/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/trivia-parsing/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..702108ccbe2e016760b8c8277480a0f5d59ae754 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/trivia-parsing/source.lua @@ -0,0 +1,11 @@ +local foo = bar -- trailing comment + +-- leading comment +local bar = baz +local baz = foo + +do + local foo = bar + -- comment + local bar = baz +end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/trivia-parsing/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/trivia-parsing/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..9d60f0338aa9a361a0181397f104cdcb2050779a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/trivia-parsing/tokens.snap @@ -0,0 +1,611 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/trivia-parsing + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Identifier + identifier: bar +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 35 + line: 1 + character: 36 + token_type: + type: SingleLineComment + comment: " trailing comment" +- start_position: + bytes: 35 + line: 1 + character: 36 + end_position: + bytes: 36 + line: 1 + character: 36 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 36 + line: 2 + character: 1 + end_position: + bytes: 37 + line: 2 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 37 + line: 3 + character: 1 + end_position: + bytes: 55 + line: 3 + character: 19 + token_type: + type: SingleLineComment + comment: " leading comment" +- start_position: + bytes: 55 + line: 3 + character: 19 + end_position: + bytes: 56 + line: 3 + character: 19 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 56 + line: 4 + character: 1 + end_position: + bytes: 61 + line: 4 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 61 + line: 4 + character: 6 + end_position: + bytes: 62 + line: 4 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 62 + line: 4 + character: 7 + end_position: + bytes: 65 + line: 4 + character: 10 + token_type: + type: Identifier + identifier: bar +- start_position: + bytes: 65 + line: 4 + character: 10 + end_position: + bytes: 66 + line: 4 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 66 + line: 4 + character: 11 + end_position: + bytes: 67 + line: 4 + character: 12 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 67 + line: 4 + character: 12 + end_position: + bytes: 68 + line: 4 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 68 + line: 4 + character: 13 + end_position: + bytes: 71 + line: 4 + character: 16 + token_type: + type: Identifier + identifier: baz +- start_position: + bytes: 71 + line: 4 + character: 16 + end_position: + bytes: 72 + line: 4 + character: 16 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 72 + line: 5 + character: 1 + end_position: + bytes: 77 + line: 5 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 77 + line: 5 + character: 6 + end_position: + bytes: 78 + line: 5 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 78 + line: 5 + character: 7 + end_position: + bytes: 81 + line: 5 + character: 10 + token_type: + type: Identifier + identifier: baz +- start_position: + bytes: 81 + line: 5 + character: 10 + end_position: + bytes: 82 + line: 5 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 82 + line: 5 + character: 11 + end_position: + bytes: 83 + line: 5 + character: 12 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 83 + line: 5 + character: 12 + end_position: + bytes: 84 + line: 5 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 84 + line: 5 + character: 13 + end_position: + bytes: 87 + line: 5 + character: 16 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 87 + line: 5 + character: 16 + end_position: + bytes: 88 + line: 5 + character: 16 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 88 + line: 6 + character: 1 + end_position: + bytes: 89 + line: 6 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 89 + line: 7 + character: 1 + end_position: + bytes: 91 + line: 7 + character: 3 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 91 + line: 7 + character: 3 + end_position: + bytes: 92 + line: 7 + character: 3 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 92 + line: 8 + character: 1 + end_position: + bytes: 93 + line: 8 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 93 + line: 8 + character: 2 + end_position: + bytes: 98 + line: 8 + character: 7 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 98 + line: 8 + character: 7 + end_position: + bytes: 99 + line: 8 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 99 + line: 8 + character: 8 + end_position: + bytes: 102 + line: 8 + character: 11 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 102 + line: 8 + character: 11 + end_position: + bytes: 103 + line: 8 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 103 + line: 8 + character: 12 + end_position: + bytes: 104 + line: 8 + character: 13 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 104 + line: 8 + character: 13 + end_position: + bytes: 105 + line: 8 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 105 + line: 8 + character: 14 + end_position: + bytes: 108 + line: 8 + character: 17 + token_type: + type: Identifier + identifier: bar +- start_position: + bytes: 108 + line: 8 + character: 17 + end_position: + bytes: 109 + line: 8 + character: 17 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 109 + line: 9 + character: 1 + end_position: + bytes: 110 + line: 9 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 110 + line: 9 + character: 2 + end_position: + bytes: 120 + line: 9 + character: 12 + token_type: + type: SingleLineComment + comment: " comment" +- start_position: + bytes: 120 + line: 9 + character: 12 + end_position: + bytes: 121 + line: 9 + character: 12 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 121 + line: 10 + character: 1 + end_position: + bytes: 122 + line: 10 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 122 + line: 10 + character: 2 + end_position: + bytes: 127 + line: 10 + character: 7 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 127 + line: 10 + character: 7 + end_position: + bytes: 128 + line: 10 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 128 + line: 10 + character: 8 + end_position: + bytes: 131 + line: 10 + character: 11 + token_type: + type: Identifier + identifier: bar +- start_position: + bytes: 131 + line: 10 + character: 11 + end_position: + bytes: 132 + line: 10 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 132 + line: 10 + character: 12 + end_position: + bytes: 133 + line: 10 + character: 13 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 133 + line: 10 + character: 13 + end_position: + bytes: 134 + line: 10 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 134 + line: 10 + character: 14 + end_position: + bytes: 137 + line: 10 + character: 17 + token_type: + type: Identifier + identifier: baz +- start_position: + bytes: 137 + line: 10 + character: 17 + end_position: + bytes: 138 + line: 10 + character: 17 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 138 + line: 11 + character: 1 + end_position: + bytes: 141 + line: 11 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 141 + line: 11 + character: 4 + end_position: + bytes: 141 + line: 11 + character: 4 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/unops/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/unops/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..da0e77602e4f5484039fb96ee97de19f6e1826f7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/unops/ast.snap @@ -0,0 +1,667 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/unops +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Identifier + identifier: negativeLiteral + trailing_trivia: + - start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 22 + line: 1 + character: 23 + end_position: + bytes: 23 + line: 1 + character: 24 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 23 + line: 1 + character: 24 + end_position: + bytes: 24 + line: 1 + character: 25 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + UnaryOperator: + unop: + Minus: + leading_trivia: [] + token: + start_position: + bytes: 24 + line: 1 + character: 25 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Symbol + symbol: "-" + trailing_trivia: [] + expression: + Number: + leading_trivia: [] + token: + start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 26 + line: 1 + character: 27 + token_type: + type: Number + text: "3" + trailing_trivia: + - start_position: + bytes: 26 + line: 1 + character: 27 + end_position: + bytes: 27 + line: 1 + character: 27 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 27 + line: 2 + character: 1 + end_position: + bytes: 32 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 32 + line: 2 + character: 6 + end_position: + bytes: 33 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 33 + line: 2 + character: 7 + end_position: + bytes: 49 + line: 2 + character: 23 + token_type: + type: Identifier + identifier: negativeVariable + trailing_trivia: + - start_position: + bytes: 49 + line: 2 + character: 23 + end_position: + bytes: 50 + line: 2 + character: 24 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 50 + line: 2 + character: 24 + end_position: + bytes: 51 + line: 2 + character: 25 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 51 + line: 2 + character: 25 + end_position: + bytes: 52 + line: 2 + character: 26 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + UnaryOperator: + unop: + Minus: + leading_trivia: [] + token: + start_position: + bytes: 52 + line: 2 + character: 26 + end_position: + bytes: 53 + line: 2 + character: 27 + token_type: + type: Symbol + symbol: "-" + trailing_trivia: [] + expression: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 53 + line: 2 + character: 27 + end_position: + bytes: 54 + line: 2 + character: 28 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 54 + line: 2 + character: 28 + end_position: + bytes: 55 + line: 2 + character: 28 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 55 + line: 3 + character: 1 + end_position: + bytes: 60 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 60 + line: 3 + character: 6 + end_position: + bytes: 61 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 61 + line: 3 + character: 7 + end_position: + bytes: 71 + line: 3 + character: 17 + token_type: + type: Identifier + identifier: notLiteral + trailing_trivia: + - start_position: + bytes: 71 + line: 3 + character: 17 + end_position: + bytes: 72 + line: 3 + character: 18 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 72 + line: 3 + character: 18 + end_position: + bytes: 73 + line: 3 + character: 19 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 73 + line: 3 + character: 19 + end_position: + bytes: 74 + line: 3 + character: 20 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + UnaryOperator: + unop: + Not: + leading_trivia: [] + token: + start_position: + bytes: 74 + line: 3 + character: 20 + end_position: + bytes: 77 + line: 3 + character: 23 + token_type: + type: Symbol + symbol: not + trailing_trivia: + - start_position: + bytes: 77 + line: 3 + character: 23 + end_position: + bytes: 78 + line: 3 + character: 24 + token_type: + type: Whitespace + characters: " " + expression: + Symbol: + leading_trivia: [] + token: + start_position: + bytes: 78 + line: 3 + character: 24 + end_position: + bytes: 82 + line: 3 + character: 28 + token_type: + type: Symbol + symbol: "true" + trailing_trivia: + - start_position: + bytes: 82 + line: 3 + character: 28 + end_position: + bytes: 83 + line: 3 + character: 28 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 83 + line: 4 + character: 1 + end_position: + bytes: 88 + line: 4 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 88 + line: 4 + character: 6 + end_position: + bytes: 89 + line: 4 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 89 + line: 4 + character: 7 + end_position: + bytes: 100 + line: 4 + character: 18 + token_type: + type: Identifier + identifier: notVariable + trailing_trivia: + - start_position: + bytes: 100 + line: 4 + character: 18 + end_position: + bytes: 101 + line: 4 + character: 19 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 101 + line: 4 + character: 19 + end_position: + bytes: 102 + line: 4 + character: 20 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 102 + line: 4 + character: 20 + end_position: + bytes: 103 + line: 4 + character: 21 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + UnaryOperator: + unop: + Not: + leading_trivia: [] + token: + start_position: + bytes: 103 + line: 4 + character: 21 + end_position: + bytes: 106 + line: 4 + character: 24 + token_type: + type: Symbol + symbol: not + trailing_trivia: + - start_position: + bytes: 106 + line: 4 + character: 24 + end_position: + bytes: 107 + line: 4 + character: 25 + token_type: + type: Whitespace + characters: " " + expression: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 107 + line: 4 + character: 25 + end_position: + bytes: 108 + line: 4 + character: 26 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 108 + line: 4 + character: 26 + end_position: + bytes: 109 + line: 4 + character: 26 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 109 + line: 5 + character: 1 + end_position: + bytes: 114 + line: 5 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 114 + line: 5 + character: 6 + end_position: + bytes: 115 + line: 5 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 115 + line: 5 + character: 7 + end_position: + bytes: 121 + line: 5 + character: 13 + token_type: + type: Identifier + identifier: length + trailing_trivia: + - start_position: + bytes: 121 + line: 5 + character: 13 + end_position: + bytes: 122 + line: 5 + character: 14 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 122 + line: 5 + character: 14 + end_position: + bytes: 123 + line: 5 + character: 15 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 123 + line: 5 + character: 15 + end_position: + bytes: 124 + line: 5 + character: 16 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + UnaryOperator: + unop: + Hash: + leading_trivia: [] + token: + start_position: + bytes: 124 + line: 5 + character: 16 + end_position: + bytes: 125 + line: 5 + character: 17 + token_type: + type: Symbol + symbol: "#" + trailing_trivia: [] + expression: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 125 + line: 5 + character: 17 + end_position: + bytes: 126 + line: 5 + character: 18 + token_type: + type: Identifier + identifier: x + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/unops/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/unops/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..47d8330ddf02bc7ff3464f6d33275e735a35015d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/unops/source.lua @@ -0,0 +1,5 @@ +local negativeLiteral = -3 +local negativeVariable = -x +local notLiteral = not true +local notVariable = not x +local length = #x \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/unops/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/unops/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..5101a9d9832bf224b6e1577241e7d17235f997e0 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/unops/tokens.snap @@ -0,0 +1,523 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/unops + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Identifier + identifier: negativeLiteral +- start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 22 + line: 1 + character: 23 + end_position: + bytes: 23 + line: 1 + character: 24 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 23 + line: 1 + character: 24 + end_position: + bytes: 24 + line: 1 + character: 25 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 24 + line: 1 + character: 25 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Symbol + symbol: "-" +- start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 26 + line: 1 + character: 27 + token_type: + type: Number + text: "3" +- start_position: + bytes: 26 + line: 1 + character: 27 + end_position: + bytes: 27 + line: 1 + character: 27 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 27 + line: 2 + character: 1 + end_position: + bytes: 32 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 32 + line: 2 + character: 6 + end_position: + bytes: 33 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 33 + line: 2 + character: 7 + end_position: + bytes: 49 + line: 2 + character: 23 + token_type: + type: Identifier + identifier: negativeVariable +- start_position: + bytes: 49 + line: 2 + character: 23 + end_position: + bytes: 50 + line: 2 + character: 24 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 50 + line: 2 + character: 24 + end_position: + bytes: 51 + line: 2 + character: 25 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 51 + line: 2 + character: 25 + end_position: + bytes: 52 + line: 2 + character: 26 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 52 + line: 2 + character: 26 + end_position: + bytes: 53 + line: 2 + character: 27 + token_type: + type: Symbol + symbol: "-" +- start_position: + bytes: 53 + line: 2 + character: 27 + end_position: + bytes: 54 + line: 2 + character: 28 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 54 + line: 2 + character: 28 + end_position: + bytes: 55 + line: 2 + character: 28 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 55 + line: 3 + character: 1 + end_position: + bytes: 60 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 60 + line: 3 + character: 6 + end_position: + bytes: 61 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 61 + line: 3 + character: 7 + end_position: + bytes: 71 + line: 3 + character: 17 + token_type: + type: Identifier + identifier: notLiteral +- start_position: + bytes: 71 + line: 3 + character: 17 + end_position: + bytes: 72 + line: 3 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 72 + line: 3 + character: 18 + end_position: + bytes: 73 + line: 3 + character: 19 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 73 + line: 3 + character: 19 + end_position: + bytes: 74 + line: 3 + character: 20 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 74 + line: 3 + character: 20 + end_position: + bytes: 77 + line: 3 + character: 23 + token_type: + type: Symbol + symbol: not +- start_position: + bytes: 77 + line: 3 + character: 23 + end_position: + bytes: 78 + line: 3 + character: 24 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 78 + line: 3 + character: 24 + end_position: + bytes: 82 + line: 3 + character: 28 + token_type: + type: Symbol + symbol: "true" +- start_position: + bytes: 82 + line: 3 + character: 28 + end_position: + bytes: 83 + line: 3 + character: 28 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 83 + line: 4 + character: 1 + end_position: + bytes: 88 + line: 4 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 88 + line: 4 + character: 6 + end_position: + bytes: 89 + line: 4 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 89 + line: 4 + character: 7 + end_position: + bytes: 100 + line: 4 + character: 18 + token_type: + type: Identifier + identifier: notVariable +- start_position: + bytes: 100 + line: 4 + character: 18 + end_position: + bytes: 101 + line: 4 + character: 19 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 101 + line: 4 + character: 19 + end_position: + bytes: 102 + line: 4 + character: 20 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 102 + line: 4 + character: 20 + end_position: + bytes: 103 + line: 4 + character: 21 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 103 + line: 4 + character: 21 + end_position: + bytes: 106 + line: 4 + character: 24 + token_type: + type: Symbol + symbol: not +- start_position: + bytes: 106 + line: 4 + character: 24 + end_position: + bytes: 107 + line: 4 + character: 25 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 107 + line: 4 + character: 25 + end_position: + bytes: 108 + line: 4 + character: 26 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 108 + line: 4 + character: 26 + end_position: + bytes: 109 + line: 4 + character: 26 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 109 + line: 5 + character: 1 + end_position: + bytes: 114 + line: 5 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 114 + line: 5 + character: 6 + end_position: + bytes: 115 + line: 5 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 115 + line: 5 + character: 7 + end_position: + bytes: 121 + line: 5 + character: 13 + token_type: + type: Identifier + identifier: length +- start_position: + bytes: 121 + line: 5 + character: 13 + end_position: + bytes: 122 + line: 5 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 122 + line: 5 + character: 14 + end_position: + bytes: 123 + line: 5 + character: 15 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 123 + line: 5 + character: 15 + end_position: + bytes: 124 + line: 5 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 124 + line: 5 + character: 16 + end_position: + bytes: 125 + line: 5 + character: 17 + token_type: + type: Symbol + symbol: "#" +- start_position: + bytes: 125 + line: 5 + character: 17 + end_position: + bytes: 126 + line: 5 + character: 18 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 126 + line: 5 + character: 18 + end_position: + bytes: 126 + line: 5 + character: 18 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/utf-8/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/utf-8/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..cc9212d6db8ff5871e55488e97b82cf1d165e428 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/utf-8/ast.snap @@ -0,0 +1,136 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/utf-8 +--- +stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Identifier + identifier: print + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 24 + line: 1 + character: 22 + end_position: + bytes: 25 + line: 1 + character: 23 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: + - End: + BinaryOperator: + lhs: + String: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 13 + line: 1 + character: 11 + token_type: + type: StringLiteral + literal: "👚 " + quote_type: Double + trailing_trivia: + - start_position: + bytes: 13 + line: 1 + character: 11 + end_position: + bytes: 14 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " + binop: + TwoDots: + leading_trivia: [] + token: + start_position: + bytes: 14 + line: 1 + character: 12 + end_position: + bytes: 16 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: ".." + trailing_trivia: + - start_position: + bytes: 16 + line: 1 + character: 14 + end_position: + bytes: 17 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 17 + line: 1 + character: 15 + end_position: + bytes: 24 + line: 1 + character: 22 + token_type: + type: Identifier + identifier: message + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/utf-8/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/utf-8/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..2f69a435e2c49caeff7418f261d185b5adde63fd --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/utf-8/source.lua @@ -0,0 +1 @@ +print("👚 " .. message) \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/utf-8/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/utf-8/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..9f6d50f11f009a353270107eda145aef19af055c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/utf-8/tokens.snap @@ -0,0 +1,106 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/utf-8 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Identifier + identifier: print +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 13 + line: 1 + character: 11 + token_type: + type: StringLiteral + literal: "👚 " + quote_type: Double +- start_position: + bytes: 13 + line: 1 + character: 11 + end_position: + bytes: 14 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 14 + line: 1 + character: 12 + end_position: + bytes: 16 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: ".." +- start_position: + bytes: 16 + line: 1 + character: 14 + end_position: + bytes: 17 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 17 + line: 1 + character: 15 + end_position: + bytes: 24 + line: 1 + character: 22 + token_type: + type: Identifier + identifier: message +- start_position: + bytes: 24 + line: 1 + character: 22 + end_position: + bytes: 25 + line: 1 + character: 23 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 25 + line: 1 + character: 23 + end_position: + bytes: 25 + line: 1 + character: 23 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/while/ast.snap b/src/Rust/vvs_parser/src/tests/cases/pass/while/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..081c5300112b29f5e32742796884d05502add1f7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/while/ast.snap @@ -0,0 +1,222 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/cases/pass/while +--- +stmts: + - - While: + while_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: while + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + condition: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Identifier + identifier: condition + trailing_trivia: + - start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Whitespace + characters: " " + do_token: + leading_trivia: [] + token: + start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 19 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 19 + line: 2 + character: 1 + end_position: + bytes: 20 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 20 + line: 2 + character: 2 + end_position: + bytes: 24 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 24 + line: 2 + character: 6 + end_position: + bytes: 25 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 25 + line: 2 + character: 7 + end_position: + bytes: 26 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 26 + line: 2 + character: 8 + end_position: + bytes: 27 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: [] + - ~ + last_stmt: + - Break: + leading_trivia: + - start_position: + bytes: 27 + line: 3 + character: 1 + end_position: + bytes: 28 + line: 3 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 28 + line: 3 + character: 2 + end_position: + bytes: 33 + line: 3 + character: 7 + token_type: + type: Symbol + symbol: break + trailing_trivia: + - start_position: + bytes: 33 + line: 3 + character: 7 + end_position: + bytes: 34 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: "\n" + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 34 + line: 4 + character: 1 + end_position: + bytes: 37 + line: 4 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/while/source.lua b/src/Rust/vvs_parser/src/tests/cases/pass/while/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..0fe6ecf3e9cc473d70d29f8709c2efe297f5726b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/while/source.lua @@ -0,0 +1,4 @@ +while condition do + call() + break +end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/cases/pass/while/tokens.snap b/src/Rust/vvs_parser/src/tests/cases/pass/while/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..7d618d483aa98523b326ca8131b6626829b41579 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/cases/pass/while/tokens.snap @@ -0,0 +1,182 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/cases/pass/while + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: while +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Identifier + identifier: condition +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 19 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 19 + line: 2 + character: 1 + end_position: + bytes: 20 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 20 + line: 2 + character: 2 + end_position: + bytes: 24 + line: 2 + character: 6 + token_type: + type: Identifier + identifier: call +- start_position: + bytes: 24 + line: 2 + character: 6 + end_position: + bytes: 25 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 25 + line: 2 + character: 7 + end_position: + bytes: 26 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 26 + line: 2 + character: 8 + end_position: + bytes: 27 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 27 + line: 3 + character: 1 + end_position: + bytes: 28 + line: 3 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 28 + line: 3 + character: 2 + end_position: + bytes: 33 + line: 3 + character: 7 + token_type: + type: Symbol + symbol: break +- start_position: + bytes: 33 + line: 3 + character: 7 + end_position: + bytes: 34 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 34 + line: 4 + character: 1 + end_position: + bytes: 37 + line: 4 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 37 + line: 4 + character: 4 + end_position: + bytes: 37 + line: 4 + character: 4 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/comments_around_functions.rs b/src/Rust/vvs_parser/src/tests/comments_around_functions.rs new file mode 100644 index 0000000000000000000000000000000000000000..dfa197804fd6295216ab214e92503afc9aad7d20 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/comments_around_functions.rs @@ -0,0 +1,52 @@ +// This is code from a real life usage of full-moon + +use crate::{ast::*, node::Node, tokenizer::TokenKind, visitors::Visitor}; + +const CODE: &str = r#" + +local Module = {} +Module.__index = Module + +--[[ + Creates a new instance of Module. + + ```lua + Module.new() + ``` + + @static + @param name string - This is the name for this Module. + @returns Module - Returns the new Module! +]] +function Module.new(name) + +end + +"#; + +struct MemberVisitor { + comments: Vec<String>, +} + +impl Visitor for MemberVisitor { + fn visit_function_declaration(&mut self, function: &FunctionDeclaration) { + let (tokens, _) = function.surrounding_trivia(); + let mut tokens = tokens; + tokens.retain(|t| t.token_kind() == TokenKind::MultiLineComment); + self.comments + .extend(tokens.into_iter().map(|t| t.to_string()).collect::<Vec<String>>()) + } +} + +fn generate() -> Result<(), Vec<crate::Error>> { + let ast = crate::prelude::parser::parse_lua_tree(CODE)?; + let mut visitor = MemberVisitor { comments: Vec::new() }; + visitor.visit_ast(&ast); + println!("{:?}", visitor.comments); + Ok(()) +} + +#[test] +fn test() { + generate().expect("Oh"); +} diff --git a/src/Rust/vvs_parser/src/tests/common.rs b/src/Rust/vvs_parser/src/tests/common.rs new file mode 100644 index 0000000000000000000000000000000000000000..c484fa2f5fdb56d1637d4d45d64ad4b24f404cb6 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/common.rs @@ -0,0 +1,19 @@ +use std::fs; +use std::path::Path; + +fn with_insta_settings(path: &Path, f: impl FnOnce()) { + let mut settings = insta::Settings::clone_current(); + settings.set_prepend_module_to_snapshot(false); + settings.set_snapshot_path(path); + settings.set_input_file(path); + settings.bind(f) +} + +pub fn run_test_folder<P: AsRef<Path>>(folder: P, test_fn: impl Fn(&Path)) { + for entry in fs::read_dir(folder).expect("couldn't read directory") { + let entry = entry.unwrap(); + let path = entry.path().canonicalize().unwrap(); + dbg!(entry.path().to_string_lossy()); + with_insta_settings(&path, || test_fn(&path)) + } +} diff --git a/src/Rust/vvs_parser/src/tests/derive_node.rs b/src/Rust/vvs_parser/src/tests/derive_node.rs new file mode 100644 index 0000000000000000000000000000000000000000..ef4e837fb461acd6360163c933806381c6c469f0 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/derive_node.rs @@ -0,0 +1,32 @@ +use crate::{ast, node::Node, prelude::parser::parse_lua_tree as parse, visitors::Visitor}; + +const MIN_MAX_CODE: &str = "local x = { 1, 2, 3 }"; + +#[test] +fn test_position_min_max() { + struct TestVisitor(bool); + + impl Visitor for TestVisitor { + fn visit_table_constructor(&mut self, constructor: &ast::TableConstructor) { + self.0 = true; + assert_eq!( + MIN_MAX_CODE + .as_bytes() + .get(constructor.start_position().unwrap().bytes()), + Some(&b'{') + ); + assert_eq!( + MIN_MAX_CODE + .as_bytes() + .get(constructor.end_position().unwrap().bytes() - 1), + Some(&b'}') + ); + } + } + + let ast = parse(MIN_MAX_CODE).unwrap(); + + let mut visitor = TestVisitor(false); + visitor.visit_ast(&ast); + assert!(visitor.0, "TableConstructor was never found"); +} diff --git a/src/Rust/vvs_parser/src/tests/fail_cases.rs b/src/Rust/vvs_parser/src/tests/fail_cases.rs new file mode 100644 index 0000000000000000000000000000000000000000..a8461cd7736f16e525b3bb19876967dc5faddf62 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/fail_cases.rs @@ -0,0 +1,94 @@ +use crate::{ast::AstResult, tests::common::run_test_folder, tokenizer}; +use codespan_reporting::{ + diagnostic::{Diagnostic, Label}, + files::SimpleFiles, +}; +use insta::{assert_snapshot, assert_yaml_snapshot}; +use std::fs; + +fn process_codespan_display(source_name: &str, source: &str, errors: &[crate::Error]) { + let mut files = SimpleFiles::new(); + let file_id = files.add(source_name, source); + let config = codespan_reporting::term::Config::default(); + let mut output = termcolor::NoColor::new(Vec::new()); + + for error in errors { + let range = error.range(); + let diagnostic = Diagnostic::error() + .with_message(error.error_message()) + .with_code(match error { + crate::Error::AstError(_) => "ast", + crate::Error::TokenizerError(_) => "tokenizer", + }) + .with_labels(vec![Label::primary(file_id, (range.0.bytes())..(range.1.bytes()))]); + codespan_reporting::term::emit(&mut output, &config, &files, &diagnostic).unwrap(); + } + + assert_snapshot!("error_display", String::from_utf8(output.into_inner()).unwrap()); +} + +fn run_parser_fail_cases(folder: &str) { + run_test_folder(folder, |path| { + let source = fs::read_to_string(path.join("source.lua")).expect("couldn't read source.lua"); + let tokens = tokenizer::Lexer::new(&source).collect().unwrap(); + assert_yaml_snapshot!("tokens", tokens); + + let result = AstResult::parse_fallible(&source); + + if result.errors().is_empty() { + panic!("fail case passed for {path:?}"); + } + + assert_yaml_snapshot!("errors", result.errors()); + assert_yaml_snapshot!("ast", result.ast()); + + process_codespan_display("source.lua", &source, result.errors()); + + let ast = result.into_ast().update_positions(); + assert_yaml_snapshot!("ast_to_string", format!("{ast}")); + }); +} + +#[test] +fn test_roblox_parser_fail_cases() { + run_parser_fail_cases("./src/tests/roblox_cases/fail/parser"); +} + +#[test] +fn test_lua52_parser_fail_cases() { + run_parser_fail_cases("./src/tests/lua52_cases/fail/parser"); +} + +#[test] +fn test_lua53_parser_fail_cases() { + run_parser_fail_cases("./src/tests/lua53_cases/fail/parser"); +} + +#[test] +fn test_lua54_parser_fail_cases() { + run_parser_fail_cases("./src/tests/lua54_cases/fail/parser"); +} + +#[test] +fn test_vivy_parser_fail_cases() { + run_parser_fail_cases("./src/tests/vivy_cases/fail/parser"); +} + +#[test] +fn test_option_parser_fail_cases() { + run_test_folder("./src/tests/option_cases/fail/parser", |path| { + let source = fs::read_to_string(path.join("source.ini")).expect("couldn't read source.ini"); + let tokens = tokenizer::Lexer::new(&source).collect().unwrap(); + assert_yaml_snapshot!("tokens", tokens); + + let result = crate::ast::OptionTableResult::parse_fallible(&source); + if result.errors().is_empty() { + panic!("fail case passed for {path:?}"); + } + + assert_yaml_snapshot!("errors", result.errors()); + assert_yaml_snapshot!("option_table", result.option_table()); + + process_codespan_display("source.ini", &source, result.errors()); + }); +} diff --git a/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/goto-1/ast.snap b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/goto-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..b43eda27a59dc1ef94fbcc0d907bb05879296e48 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/goto-1/ast.snap @@ -0,0 +1,23 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 23 +expression: result.ast +input_file: full-moon/tests/lua52_cases/fail/parser/goto-1 +--- +nodes: + stmts: [] +eof: + leading_trivia: [] + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/goto-1/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/goto-1/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..3ae24382142dd91330df32526e46642a358dddcc --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/goto-1/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 28 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/lua52_cases/fail/parser/goto-1 +--- +"" + diff --git a/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/goto-1/error_display.snap b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/goto-1/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..59b9a7010d9970da57a525da3366e8f678eeb151 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/goto-1/error_display.snap @@ -0,0 +1,11 @@ +--- +source: vvs_parser/tests/fail_cases.rs +assertion_line: 53 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: vvs_parser/tests/lua52_cases/fail/parser/goto-1 +--- +error[ast]: unexpected expression when looking for a statement + ┌─ source.lua:1:5 + │ +1 │ goto + │ ^ diff --git a/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/goto-1/errors.snap b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/goto-1/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..892b3f6c83c0e12ae7beee9260cba56ccbe54528 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/goto-1/errors.snap @@ -0,0 +1,19 @@ +--- +source: vvs_parser/tests/fail_cases.rs +assertion_line: 22 +expression: result.errors() +input_file: vvs_parser/tests/lua52_cases/fail/parser/goto-1 +--- +- AstError: + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Eof + additional: unexpected expression when looking for a statement diff --git a/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/goto-1/source.lua b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/goto-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..cce75b692468bd159c75a41b4876187b99a956e7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/goto-1/source.lua @@ -0,0 +1 @@ +goto \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/goto-1/tokens.snap b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/goto-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..7ae0d19319ef95651af93e4925a32011afcf7364 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/goto-1/tokens.snap @@ -0,0 +1,27 @@ +--- +source: vvs_parser/tests/fail_cases.rs +assertion_line: 60 +expression: tokens +input_file: vvs_parser/tests/lua52_cases/fail/parser/goto-1 +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: goto +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Eof diff --git a/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-1/ast.snap b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..ddf9510e690768d8843f0484a5c3c9ba8e92a811 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-1/ast.snap @@ -0,0 +1,22 @@ +--- +source: vvs_parser/tests/fail_cases.rs +assertion_line: 23 +expression: result.ast() +input_file: vvs_parser/tests/lua52_cases/fail/parser/label-1 +--- +nodes: + stmts: [] +eof: + leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Eof + trailing_trivia: [] diff --git a/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-1/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-1/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..b3b47b03e9ada211ebb14940a6de6b9620e860cc --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-1/ast_to_string.snap @@ -0,0 +1,7 @@ +--- +source: vvs_parser/tests/fail_cases.rs +assertion_line: 28 +expression: "vvs_parser::print(&ast)" +input_file: vvs_parser/tests/lua52_cases/fail/parser/label-1 +--- +"" diff --git a/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-1/error_display.snap b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-1/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..d102ab01c8adb995490c0761a8e7a4e0c1c98f08 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-1/error_display.snap @@ -0,0 +1,17 @@ +--- +source: vvs_parser/tests/fail_cases.rs +assertion_line: 53 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: vvs_parser/tests/lua52_cases/fail/parser/label-1 +--- +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:1 + │ +1 │ ::label + │ ^^ + +error[ast]: unexpected expression when looking for a statement + ┌─ source.lua:1:8 + │ +1 │ ::label + │ ^ diff --git a/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-1/errors.snap b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-1/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..105e410b1588d0ec0700771ca4b0103bbf810077 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-1/errors.snap @@ -0,0 +1,33 @@ +--- +source: vvs_parser/tests/fail_cases.rs +assertion_line: 22 +expression: result.errors() +input_file: vvs_parser/tests/lua52_cases/fail/parser/label-1 +--- +- AstError: + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: "::" + additional: "unexpected token, this needs to be a statement" +- AstError: + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Eof + additional: unexpected expression when looking for a statement diff --git a/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-1/source.lua b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..4ef49c49f456acc613ac8f7c8cc34aba1ae436df --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-1/source.lua @@ -0,0 +1 @@ +::label \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-1/tokens.snap b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..897e38791c519490c708c4c0992e197ee4a0a02e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-1/tokens.snap @@ -0,0 +1,39 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/lua52_cases/fail/parser/label-1 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 2 + line: 1 + character: 3 + token_type: + type: Symbol + symbol: "::" +- start_position: + bytes: 2 + line: 1 + character: 3 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: label +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-2/ast.snap b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..978cd6d9a5a2b6e4e4c2d93fde8fe553a6f696ce --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-2/ast.snap @@ -0,0 +1,23 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 23 +expression: result.ast +input_file: full-moon/tests/lua52_cases/fail/parser/label-2 +--- +nodes: + stmts: [] +eof: + leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-2/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-2/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..ff6f72223eb08c47e627964e36fe7572e5508cc0 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-2/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 28 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/lua52_cases/fail/parser/label-2 +--- +"" + diff --git a/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-2/error_display.snap b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-2/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..c93bc34ffcc3e65386a9e8cd72dd9271df4f58c3 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-2/error_display.snap @@ -0,0 +1,17 @@ +--- +source: vvs_parser/tests/fail_cases.rs +assertion_line: 53 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: vvs_parser/tests/lua52_cases/fail/parser/label-2 +--- +error[ast]: unexpected expression when looking for a statement + ┌─ source.lua:1:6 + │ +1 │ label:: + │ ^^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:6 + │ +1 │ label:: + │ ^^ diff --git a/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-2/errors.snap b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-2/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..14bd5089782f1455f3a5d0520e33503488825043 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-2/errors.snap @@ -0,0 +1,34 @@ +--- +source: vvs_parser/tests/fail_cases.rs +assertion_line: 22 +expression: result.errors() +input_file: vvs_parser/tests/lua52_cases/fail/parser/label-2 +--- +- AstError: + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Symbol + symbol: "::" + additional: unexpected expression when looking for a statement +- AstError: + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Symbol + symbol: "::" + additional: "unexpected token, this needs to be a statement" diff --git a/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-2/source.lua b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..6a8a2de76629ac8dfcfe02c248742fae405c019f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-2/source.lua @@ -0,0 +1 @@ +label:: \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-2/tokens.snap b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..6a18496e22277edd7e5f8d83a3d67299457c8b37 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua52_cases/fail/parser/label-2/tokens.snap @@ -0,0 +1,39 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +input_file: full-moon/tests/lua52_cases/fail/parser/label-2 + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Identifier + identifier: label +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Symbol + symbol: "::" +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/lua52_cases/pass/not-z-escape-string/ast.snap b/src/Rust/vvs_parser/src/tests/lua52_cases/pass/not-z-escape-string/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..f087bb32dd3d8cb2c2e62432c097d23a39350594 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua52_cases/pass/not-z-escape-string/ast.snap @@ -0,0 +1,79 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/lua52_cases/pass/not-z-escape-string +--- +stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Identifier + identifier: print + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 28 + line: 2 + character: 12 + end_position: + bytes: 29 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 28 + line: 2 + character: 12 + token_type: + type: StringLiteral + literal: "testing \\\n\t twelve" + quote_type: Double + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/lua52_cases/pass/not-z-escape-string/source.lua b/src/Rust/vvs_parser/src/tests/lua52_cases/pass/not-z-escape-string/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..05b5128a640c1e659d836665fd3650ecad49d77d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua52_cases/pass/not-z-escape-string/source.lua @@ -0,0 +1,2 @@ +print("testing \ + twelve") \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/lua52_cases/pass/not-z-escape-string/tokens.snap b/src/Rust/vvs_parser/src/tests/lua52_cases/pass/not-z-escape-string/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..b07bc0577121e8f50ef1bb459e17bcd5fe7cb32c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua52_cases/pass/not-z-escape-string/tokens.snap @@ -0,0 +1,60 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Identifier + identifier: print +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 28 + line: 2 + character: 12 + token_type: + type: StringLiteral + literal: "testing \\\n\t twelve" + quote_type: Double +- start_position: + bytes: 28 + line: 2 + character: 12 + end_position: + bytes: 29 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 29 + line: 2 + character: 13 + end_position: + bytes: 29 + line: 2 + character: 13 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/lua52_cases/pass/numbers/ast.snap b/src/Rust/vvs_parser/src/tests/lua52_cases/pass/numbers/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..59fb072d176f2df0b9ce433cdf59be81704a3a63 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua52_cases/pass/numbers/ast.snap @@ -0,0 +1,429 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 47 +expression: ast.nodes() +input_file: full-moon/tests/lua52_cases/pass/numbers +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: + - start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: SingleLineComment + comment: " fractional hexadecimal" + - start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 26 + line: 1 + character: 26 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 26 + line: 2 + character: 1 + end_position: + bytes: 31 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 31 + line: 2 + character: 6 + end_position: + bytes: 32 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 32 + line: 2 + character: 7 + end_position: + bytes: 33 + line: 2 + character: 8 + token_type: + type: Identifier + identifier: a + trailing_trivia: + - start_position: + bytes: 33 + line: 2 + character: 8 + end_position: + bytes: 34 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 34 + line: 2 + character: 9 + end_position: + bytes: 35 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 35 + line: 2 + character: 10 + end_position: + bytes: 36 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 36 + line: 2 + character: 11 + end_position: + bytes: 42 + line: 2 + character: 17 + token_type: + type: Number + text: "0x0.1E" + trailing_trivia: + - start_position: + bytes: 42 + line: 2 + character: 17 + end_position: + bytes: 43 + line: 2 + character: 17 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: + - start_position: + bytes: 43 + line: 3 + character: 1 + end_position: + bytes: 44 + line: 3 + character: 1 + token_type: + type: Whitespace + characters: "\n" + - start_position: + bytes: 44 + line: 4 + character: 1 + end_position: + bytes: 77 + line: 4 + character: 34 + token_type: + type: SingleLineComment + comment: " binary exponent in hexadecimal" + - start_position: + bytes: 77 + line: 4 + character: 34 + end_position: + bytes: 78 + line: 4 + character: 34 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 78 + line: 5 + character: 1 + end_position: + bytes: 83 + line: 5 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 83 + line: 5 + character: 6 + end_position: + bytes: 84 + line: 5 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 84 + line: 5 + character: 7 + end_position: + bytes: 85 + line: 5 + character: 8 + token_type: + type: Identifier + identifier: b + trailing_trivia: + - start_position: + bytes: 85 + line: 5 + character: 8 + end_position: + bytes: 86 + line: 5 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 86 + line: 5 + character: 9 + end_position: + bytes: 87 + line: 5 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 87 + line: 5 + character: 10 + end_position: + bytes: 88 + line: 5 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 88 + line: 5 + character: 11 + end_position: + bytes: 96 + line: 5 + character: 19 + token_type: + type: Number + text: "0xA23p-4" + trailing_trivia: + - start_position: + bytes: 96 + line: 5 + character: 19 + end_position: + bytes: 97 + line: 5 + character: 19 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: + - start_position: + bytes: 97 + line: 6 + character: 1 + end_position: + bytes: 98 + line: 6 + character: 1 + token_type: + type: Whitespace + characters: "\n" + - start_position: + bytes: 98 + line: 7 + character: 1 + end_position: + bytes: 118 + line: 7 + character: 21 + token_type: + type: SingleLineComment + comment: " a mixture of both" + - start_position: + bytes: 118 + line: 7 + character: 21 + end_position: + bytes: 119 + line: 7 + character: 21 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 119 + line: 8 + character: 1 + end_position: + bytes: 124 + line: 8 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 124 + line: 8 + character: 6 + end_position: + bytes: 125 + line: 8 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 125 + line: 8 + character: 7 + end_position: + bytes: 126 + line: 8 + character: 8 + token_type: + type: Identifier + identifier: c + trailing_trivia: + - start_position: + bytes: 126 + line: 8 + character: 8 + end_position: + bytes: 127 + line: 8 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 127 + line: 8 + character: 9 + end_position: + bytes: 128 + line: 8 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 128 + line: 8 + character: 10 + end_position: + bytes: 129 + line: 8 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 129 + line: 8 + character: 11 + end_position: + bytes: 149 + line: 8 + character: 31 + token_type: + type: Number + text: 0X1.921FB54442D18P+1 + trailing_trivia: + - start_position: + bytes: 149 + line: 8 + character: 31 + end_position: + bytes: 150 + line: 8 + character: 31 + token_type: + type: Whitespace + characters: "\n" + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/lua52_cases/pass/numbers/source.lua b/src/Rust/vvs_parser/src/tests/lua52_cases/pass/numbers/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..ef1430c41bf96d0a016ef493e696d82750a3f313 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua52_cases/pass/numbers/source.lua @@ -0,0 +1,15 @@ +-- fractional hexadecimal +local a = 0x0.1E + +-- binary exponent in hexadecimal +local b = 0xA23p-4 + +-- a mixture of both +local c = 0X1.921FB54442D18P+1 + +-- LuaJIT numbers (ULL/LL ending for both decimal and hexidecimal, or imaginary) +-- This is in Lua 5.2 tests for simplicity +-- rewrite todo: add this back, but in a separate luajit pass folder +-- local d = 42LL +-- local e = 0x2aLL +-- local f = 12.5i diff --git a/src/Rust/vvs_parser/src/tests/lua52_cases/pass/numbers/tokens.snap b/src/Rust/vvs_parser/src/tests/lua52_cases/pass/numbers/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..f8b26543403cf4fb8b72128a0fe71bc9289b655f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua52_cases/pass/numbers/tokens.snap @@ -0,0 +1,512 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 40 +expression: tokens +input_file: full-moon/tests/lua52_cases/pass/numbers +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: SingleLineComment + comment: " fractional hexadecimal" +- start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 26 + line: 1 + character: 26 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 26 + line: 2 + character: 1 + end_position: + bytes: 31 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 31 + line: 2 + character: 6 + end_position: + bytes: 32 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 32 + line: 2 + character: 7 + end_position: + bytes: 33 + line: 2 + character: 8 + token_type: + type: Identifier + identifier: a +- start_position: + bytes: 33 + line: 2 + character: 8 + end_position: + bytes: 34 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 34 + line: 2 + character: 9 + end_position: + bytes: 35 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 35 + line: 2 + character: 10 + end_position: + bytes: 36 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 36 + line: 2 + character: 11 + end_position: + bytes: 42 + line: 2 + character: 17 + token_type: + type: Number + text: "0x0.1E" +- start_position: + bytes: 42 + line: 2 + character: 17 + end_position: + bytes: 43 + line: 2 + character: 17 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 43 + line: 3 + character: 1 + end_position: + bytes: 44 + line: 3 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 44 + line: 4 + character: 1 + end_position: + bytes: 77 + line: 4 + character: 34 + token_type: + type: SingleLineComment + comment: " binary exponent in hexadecimal" +- start_position: + bytes: 77 + line: 4 + character: 34 + end_position: + bytes: 78 + line: 4 + character: 34 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 78 + line: 5 + character: 1 + end_position: + bytes: 83 + line: 5 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 83 + line: 5 + character: 6 + end_position: + bytes: 84 + line: 5 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 84 + line: 5 + character: 7 + end_position: + bytes: 85 + line: 5 + character: 8 + token_type: + type: Identifier + identifier: b +- start_position: + bytes: 85 + line: 5 + character: 8 + end_position: + bytes: 86 + line: 5 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 86 + line: 5 + character: 9 + end_position: + bytes: 87 + line: 5 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 87 + line: 5 + character: 10 + end_position: + bytes: 88 + line: 5 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 88 + line: 5 + character: 11 + end_position: + bytes: 96 + line: 5 + character: 19 + token_type: + type: Number + text: "0xA23p-4" +- start_position: + bytes: 96 + line: 5 + character: 19 + end_position: + bytes: 97 + line: 5 + character: 19 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 97 + line: 6 + character: 1 + end_position: + bytes: 98 + line: 6 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 98 + line: 7 + character: 1 + end_position: + bytes: 118 + line: 7 + character: 21 + token_type: + type: SingleLineComment + comment: " a mixture of both" +- start_position: + bytes: 118 + line: 7 + character: 21 + end_position: + bytes: 119 + line: 7 + character: 21 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 119 + line: 8 + character: 1 + end_position: + bytes: 124 + line: 8 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 124 + line: 8 + character: 6 + end_position: + bytes: 125 + line: 8 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 125 + line: 8 + character: 7 + end_position: + bytes: 126 + line: 8 + character: 8 + token_type: + type: Identifier + identifier: c +- start_position: + bytes: 126 + line: 8 + character: 8 + end_position: + bytes: 127 + line: 8 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 127 + line: 8 + character: 9 + end_position: + bytes: 128 + line: 8 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 128 + line: 8 + character: 10 + end_position: + bytes: 129 + line: 8 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 129 + line: 8 + character: 11 + end_position: + bytes: 149 + line: 8 + character: 31 + token_type: + type: Number + text: 0X1.921FB54442D18P+1 +- start_position: + bytes: 149 + line: 8 + character: 31 + end_position: + bytes: 150 + line: 8 + character: 31 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 150 + line: 9 + character: 1 + end_position: + bytes: 151 + line: 9 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 151 + line: 10 + character: 1 + end_position: + bytes: 231 + line: 10 + character: 81 + token_type: + type: SingleLineComment + comment: " LuaJIT numbers (ULL/LL ending for both decimal and hexidecimal, or imaginary)" +- start_position: + bytes: 231 + line: 10 + character: 81 + end_position: + bytes: 232 + line: 10 + character: 81 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 232 + line: 11 + character: 1 + end_position: + bytes: 274 + line: 11 + character: 43 + token_type: + type: SingleLineComment + comment: " This is in Lua 5.2 tests for simplicity" +- start_position: + bytes: 274 + line: 11 + character: 43 + end_position: + bytes: 275 + line: 11 + character: 43 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 275 + line: 12 + character: 1 + end_position: + bytes: 343 + line: 12 + character: 69 + token_type: + type: SingleLineComment + comment: " rewrite todo: add this back, but in a separate luajit pass folder" +- start_position: + bytes: 343 + line: 12 + character: 69 + end_position: + bytes: 344 + line: 12 + character: 69 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 344 + line: 13 + character: 1 + end_position: + bytes: 361 + line: 13 + character: 18 + token_type: + type: SingleLineComment + comment: " local d = 42LL" +- start_position: + bytes: 361 + line: 13 + character: 18 + end_position: + bytes: 362 + line: 13 + character: 18 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 362 + line: 14 + character: 1 + end_position: + bytes: 381 + line: 14 + character: 20 + token_type: + type: SingleLineComment + comment: " local e = 0x2aLL" +- start_position: + bytes: 381 + line: 14 + character: 20 + end_position: + bytes: 382 + line: 14 + character: 20 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 382 + line: 15 + character: 1 + end_position: + bytes: 400 + line: 15 + character: 19 + token_type: + type: SingleLineComment + comment: " local f = 12.5i" +- start_position: + bytes: 400 + line: 15 + character: 19 + end_position: + bytes: 401 + line: 15 + character: 19 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 401 + line: 16 + character: 1 + end_position: + bytes: 401 + line: 16 + character: 1 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/lua52_cases/pass/z-escape-string/ast.snap b/src/Rust/vvs_parser/src/tests/lua52_cases/pass/z-escape-string/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..8a1171775c79e3c76ec9cdab22811c89b3c28912 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua52_cases/pass/z-escape-string/ast.snap @@ -0,0 +1,79 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/lua52_cases/pass/z-escape-string +--- +stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Identifier + identifier: print + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 29 + line: 2 + character: 12 + end_position: + bytes: 30 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 29 + line: 2 + character: 12 + token_type: + type: StringLiteral + literal: "testing \\z\n\t twelve" + quote_type: Double + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/lua52_cases/pass/z-escape-string/source.lua b/src/Rust/vvs_parser/src/tests/lua52_cases/pass/z-escape-string/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..230a2b44a21ab07ea30b88b2f4ddeb9daedb8b3b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua52_cases/pass/z-escape-string/source.lua @@ -0,0 +1,2 @@ +print("testing \z + twelve") \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/lua52_cases/pass/z-escape-string/tokens.snap b/src/Rust/vvs_parser/src/tests/lua52_cases/pass/z-escape-string/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..3193aac1745e30a672b9ac81e2972afa80295f0a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua52_cases/pass/z-escape-string/tokens.snap @@ -0,0 +1,60 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Identifier + identifier: print +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 29 + line: 2 + character: 12 + token_type: + type: StringLiteral + literal: "testing \\z\n\t twelve" + quote_type: Double +- start_position: + bytes: 29 + line: 2 + character: 12 + end_position: + bytes: 30 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 30 + line: 2 + character: 13 + end_position: + bytes: 30 + line: 2 + character: 13 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/lua53_cases/fail/parser/double-greater-than-binop/ast.snap b/src/Rust/vvs_parser/src/tests/lua53_cases/fail/parser/double-greater-than-binop/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..c7c48185224c551088f98a1bca61215732c09722 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua53_cases/fail/parser/double-greater-than-binop/ast.snap @@ -0,0 +1,156 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 23 +expression: result.ast +input_file: full-moon/tests/lua53_cases/fail/parser/double-greater-than-binop +--- +nodes: + stmts: + - - LocalAssignment: + local_token: + leading_trivia: + - start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 64 + line: 1 + character: 65 + token_type: + type: SingleLineComment + comment: " We shouldn't parse this as >> since it has a space in between" + - start_position: + bytes: 64 + line: 1 + character: 65 + end_position: + bytes: 65 + line: 1 + character: 65 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 65 + line: 2 + character: 1 + end_position: + bytes: 70 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 70 + line: 2 + character: 6 + end_position: + bytes: 71 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 71 + line: 2 + character: 7 + end_position: + bytes: 72 + line: 2 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 72 + line: 2 + character: 8 + end_position: + bytes: 73 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 73 + line: 2 + character: 9 + end_position: + bytes: 74 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 74 + line: 2 + character: 10 + end_position: + bytes: 75 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 75 + line: 2 + character: 11 + end_position: + bytes: 76 + line: 2 + character: 12 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 76 + line: 2 + character: 12 + end_position: + bytes: 77 + line: 2 + character: 13 + token_type: + type: Whitespace + characters: " " + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 82 + line: 2 + character: 18 + end_position: + bytes: 82 + line: 2 + character: 18 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/lua53_cases/fail/parser/double-greater-than-binop/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/lua53_cases/fail/parser/double-greater-than-binop/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..4d317ff119446177608c9f436daee516d2fdfed8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua53_cases/fail/parser/double-greater-than-binop/ast_to_string.snap @@ -0,0 +1,8 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 28 +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/lua53_cases/fail/parser/double-greater-than-binop +--- +"-- We shouldn't parse this as >> since it has a space in between\nlocal x = 1 " + diff --git a/src/Rust/vvs_parser/src/tests/lua53_cases/fail/parser/double-greater-than-binop/error.snap b/src/Rust/vvs_parser/src/tests/lua53_cases/fail/parser/double-greater-than-binop/error.snap new file mode 100644 index 0000000000000000000000000000000000000000..6a22b3726ec171ce80657f79fd84976549027906 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua53_cases/fail/parser/double-greater-than-binop/error.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: error +--- +UnexpectedToken: + token: + start_position: + bytes: 75 + line: 2 + character: 11 + end_position: + bytes: 76 + line: 2 + character: 12 + token_type: + type: Number + text: "1" + additional: expected expression + diff --git a/src/Rust/vvs_parser/src/tests/lua53_cases/fail/parser/double-greater-than-binop/error_display.snap b/src/Rust/vvs_parser/src/tests/lua53_cases/fail/parser/double-greater-than-binop/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..afad87187c2dbfd14b1b839cefcc17ed9f3e3b86 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua53_cases/fail/parser/double-greater-than-binop/error_display.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 56 +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/lua53_cases/fail/parser/double-greater-than-binop +--- +error[ast]: expected expression after binary operator + ┌─ source.lua:2:13 + │ +2 │ local x = 1 > > 2 + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:2:15 + │ +2 │ local x = 1 > > 2 + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/lua53_cases/fail/parser/double-greater-than-binop/errors.snap b/src/Rust/vvs_parser/src/tests/lua53_cases/fail/parser/double-greater-than-binop/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..dc4ec410730816d145e0f3d21613ff9ee55208bf --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua53_cases/fail/parser/double-greater-than-binop/errors.snap @@ -0,0 +1,34 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/lua53_cases/fail/parser/double-greater-than-binop +--- +- AstError: + token: + start_position: + bytes: 77 + line: 2 + character: 13 + end_position: + bytes: 78 + line: 2 + character: 14 + token_type: + type: Symbol + symbol: ">" + additional: expected expression after binary operator +- AstError: + token: + start_position: + bytes: 79 + line: 2 + character: 15 + end_position: + bytes: 80 + line: 2 + character: 16 + token_type: + type: Symbol + symbol: ">" + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/lua53_cases/fail/parser/double-greater-than-binop/source.lua b/src/Rust/vvs_parser/src/tests/lua53_cases/fail/parser/double-greater-than-binop/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..350ffca6ed51ecb7924501a857873150749e5b5c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua53_cases/fail/parser/double-greater-than-binop/source.lua @@ -0,0 +1,2 @@ +-- We shouldn't parse this as >> since it has a space in between +local x = 1 > > 2 \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/lua53_cases/fail/parser/double-greater-than-binop/tokens.snap b/src/Rust/vvs_parser/src/tests/lua53_cases/fail/parser/double-greater-than-binop/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..81737b53ac0163576b45acbf6a60769f362b65fd --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua53_cases/fail/parser/double-greater-than-binop/tokens.snap @@ -0,0 +1,180 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 64 + line: 1 + character: 65 + token_type: + type: SingleLineComment + comment: " We shouldn't parse this as >> since it has a space in between" +- start_position: + bytes: 64 + line: 1 + character: 65 + end_position: + bytes: 65 + line: 1 + character: 65 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 65 + line: 2 + character: 1 + end_position: + bytes: 70 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 70 + line: 2 + character: 6 + end_position: + bytes: 71 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 71 + line: 2 + character: 7 + end_position: + bytes: 72 + line: 2 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 72 + line: 2 + character: 8 + end_position: + bytes: 73 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 73 + line: 2 + character: 9 + end_position: + bytes: 74 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 74 + line: 2 + character: 10 + end_position: + bytes: 75 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 75 + line: 2 + character: 11 + end_position: + bytes: 76 + line: 2 + character: 12 + token_type: + type: Number + text: "1" +- start_position: + bytes: 76 + line: 2 + character: 12 + end_position: + bytes: 77 + line: 2 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 77 + line: 2 + character: 13 + end_position: + bytes: 78 + line: 2 + character: 14 + token_type: + type: Symbol + symbol: ">" +- start_position: + bytes: 78 + line: 2 + character: 14 + end_position: + bytes: 79 + line: 2 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 79 + line: 2 + character: 15 + end_position: + bytes: 80 + line: 2 + character: 16 + token_type: + type: Symbol + symbol: ">" +- start_position: + bytes: 80 + line: 2 + character: 16 + end_position: + bytes: 81 + line: 2 + character: 17 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 81 + line: 2 + character: 17 + end_position: + bytes: 82 + line: 2 + character: 18 + token_type: + type: Number + text: "2" +- start_position: + bytes: 82 + line: 2 + character: 18 + end_position: + bytes: 82 + line: 2 + character: 18 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/lua53_cases/pass/binary-operators/ast.snap b/src/Rust/vvs_parser/src/tests/lua53_cases/pass/binary-operators/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..51a84e9b09f4a7cd73ec2314026a23741bc45b3b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua53_cases/pass/binary-operators/ast.snap @@ -0,0 +1,1009 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 44 +expression: ast.nodes() +input_file: full-moon/tests/lua53_cases/pass/binary-operators +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: a + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + BinaryOperator: + lhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " + binop: + Ampersand: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: "&" + trailing_trivia: + - start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Number + text: "2" + trailing_trivia: + - start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 16 + line: 2 + character: 1 + end_position: + bytes: 21 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 21 + line: 2 + character: 6 + end_position: + bytes: 22 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 22 + line: 2 + character: 7 + end_position: + bytes: 23 + line: 2 + character: 8 + token_type: + type: Identifier + identifier: b + trailing_trivia: + - start_position: + bytes: 23 + line: 2 + character: 8 + end_position: + bytes: 24 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 24 + line: 2 + character: 9 + end_position: + bytes: 25 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 25 + line: 2 + character: 10 + end_position: + bytes: 26 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + BinaryOperator: + lhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 26 + line: 2 + character: 11 + end_position: + bytes: 27 + line: 2 + character: 12 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 27 + line: 2 + character: 12 + end_position: + bytes: 28 + line: 2 + character: 13 + token_type: + type: Whitespace + characters: " " + binop: + Pipe: + leading_trivia: [] + token: + start_position: + bytes: 28 + line: 2 + character: 13 + end_position: + bytes: 29 + line: 2 + character: 14 + token_type: + type: Symbol + symbol: "|" + trailing_trivia: + - start_position: + bytes: 29 + line: 2 + character: 14 + end_position: + bytes: 30 + line: 2 + character: 15 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 30 + line: 2 + character: 15 + end_position: + bytes: 31 + line: 2 + character: 16 + token_type: + type: Number + text: "2" + trailing_trivia: + - start_position: + bytes: 31 + line: 2 + character: 16 + end_position: + bytes: 32 + line: 2 + character: 16 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 32 + line: 3 + character: 1 + end_position: + bytes: 37 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 37 + line: 3 + character: 6 + end_position: + bytes: 38 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 38 + line: 3 + character: 7 + end_position: + bytes: 39 + line: 3 + character: 8 + token_type: + type: Identifier + identifier: c + trailing_trivia: + - start_position: + bytes: 39 + line: 3 + character: 8 + end_position: + bytes: 40 + line: 3 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 40 + line: 3 + character: 9 + end_position: + bytes: 41 + line: 3 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 41 + line: 3 + character: 10 + end_position: + bytes: 42 + line: 3 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + BinaryOperator: + lhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 42 + line: 3 + character: 11 + end_position: + bytes: 43 + line: 3 + character: 12 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 43 + line: 3 + character: 12 + end_position: + bytes: 44 + line: 3 + character: 13 + token_type: + type: Whitespace + characters: " " + binop: + DoubleLesserThan: + leading_trivia: [] + token: + start_position: + bytes: 44 + line: 3 + character: 13 + end_position: + bytes: 46 + line: 3 + character: 15 + token_type: + type: Symbol + symbol: "<~" + trailing_trivia: + - start_position: + bytes: 46 + line: 3 + character: 15 + end_position: + bytes: 47 + line: 3 + character: 16 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 47 + line: 3 + character: 16 + end_position: + bytes: 48 + line: 3 + character: 17 + token_type: + type: Number + text: "2" + trailing_trivia: + - start_position: + bytes: 48 + line: 3 + character: 17 + end_position: + bytes: 49 + line: 3 + character: 17 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 49 + line: 4 + character: 1 + end_position: + bytes: 54 + line: 4 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 54 + line: 4 + character: 6 + end_position: + bytes: 55 + line: 4 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 55 + line: 4 + character: 7 + end_position: + bytes: 56 + line: 4 + character: 8 + token_type: + type: Identifier + identifier: d + trailing_trivia: + - start_position: + bytes: 56 + line: 4 + character: 8 + end_position: + bytes: 57 + line: 4 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 57 + line: 4 + character: 9 + end_position: + bytes: 58 + line: 4 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 58 + line: 4 + character: 10 + end_position: + bytes: 59 + line: 4 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + BinaryOperator: + lhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 59 + line: 4 + character: 11 + end_position: + bytes: 60 + line: 4 + character: 12 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 60 + line: 4 + character: 12 + end_position: + bytes: 61 + line: 4 + character: 13 + token_type: + type: Whitespace + characters: " " + binop: + DoubleGreaterThan: + leading_trivia: [] + token: + start_position: + bytes: 61 + line: 4 + character: 13 + end_position: + bytes: 63 + line: 4 + character: 15 + token_type: + type: Symbol + symbol: ~> + trailing_trivia: + - start_position: + bytes: 63 + line: 4 + character: 15 + end_position: + bytes: 64 + line: 4 + character: 16 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 64 + line: 4 + character: 16 + end_position: + bytes: 65 + line: 4 + character: 17 + token_type: + type: Number + text: "2" + trailing_trivia: + - start_position: + bytes: 65 + line: 4 + character: 17 + end_position: + bytes: 66 + line: 4 + character: 17 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 66 + line: 5 + character: 1 + end_position: + bytes: 71 + line: 5 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 71 + line: 5 + character: 6 + end_position: + bytes: 72 + line: 5 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 72 + line: 5 + character: 7 + end_position: + bytes: 73 + line: 5 + character: 8 + token_type: + type: Identifier + identifier: e + trailing_trivia: + - start_position: + bytes: 73 + line: 5 + character: 8 + end_position: + bytes: 74 + line: 5 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 74 + line: 5 + character: 9 + end_position: + bytes: 75 + line: 5 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 75 + line: 5 + character: 10 + end_position: + bytes: 76 + line: 5 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + BinaryOperator: + lhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 76 + line: 5 + character: 11 + end_position: + bytes: 77 + line: 5 + character: 12 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 77 + line: 5 + character: 12 + end_position: + bytes: 78 + line: 5 + character: 13 + token_type: + type: Whitespace + characters: " " + binop: + Tilde: + leading_trivia: [] + token: + start_position: + bytes: 78 + line: 5 + character: 13 + end_position: + bytes: 79 + line: 5 + character: 14 + token_type: + type: Symbol + symbol: "~" + trailing_trivia: + - start_position: + bytes: 79 + line: 5 + character: 14 + end_position: + bytes: 80 + line: 5 + character: 15 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 80 + line: 5 + character: 15 + end_position: + bytes: 81 + line: 5 + character: 16 + token_type: + type: Number + text: "2" + trailing_trivia: + - start_position: + bytes: 81 + line: 5 + character: 16 + end_position: + bytes: 82 + line: 5 + character: 16 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 82 + line: 6 + character: 1 + end_position: + bytes: 87 + line: 6 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 87 + line: 6 + character: 6 + end_position: + bytes: 88 + line: 6 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 88 + line: 6 + character: 7 + end_position: + bytes: 89 + line: 6 + character: 8 + token_type: + type: Identifier + identifier: f + trailing_trivia: + - start_position: + bytes: 89 + line: 6 + character: 8 + end_position: + bytes: 90 + line: 6 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 90 + line: 6 + character: 9 + end_position: + bytes: 91 + line: 6 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 91 + line: 6 + character: 10 + end_position: + bytes: 92 + line: 6 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + BinaryOperator: + lhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 92 + line: 6 + character: 11 + end_position: + bytes: 93 + line: 6 + character: 12 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 93 + line: 6 + character: 12 + end_position: + bytes: 94 + line: 6 + character: 13 + token_type: + type: Whitespace + characters: " " + binop: + DoubleSlash: + leading_trivia: [] + token: + start_position: + bytes: 94 + line: 6 + character: 13 + end_position: + bytes: 96 + line: 6 + character: 15 + token_type: + type: Symbol + symbol: // + trailing_trivia: + - start_position: + bytes: 96 + line: 6 + character: 15 + end_position: + bytes: 97 + line: 6 + character: 16 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 97 + line: 6 + character: 16 + end_position: + bytes: 98 + line: 6 + character: 17 + token_type: + type: Number + text: "2" + trailing_trivia: + - start_position: + bytes: 98 + line: 6 + character: 17 + end_position: + bytes: 99 + line: 6 + character: 17 + token_type: + type: Whitespace + characters: "\n" + - ~ diff --git a/src/Rust/vvs_parser/src/tests/lua53_cases/pass/binary-operators/source.lua b/src/Rust/vvs_parser/src/tests/lua53_cases/pass/binary-operators/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..4d5c6fb9049e1b9179ed16635c538cd2c0724a35 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua53_cases/pass/binary-operators/source.lua @@ -0,0 +1,6 @@ +local a = 1 & 2 +local b = 1 | 2 +local c = 1 <~ 2 +local d = 1 ~> 2 +local e = 1 ~ 2 +local f = 1 // 2 diff --git a/src/Rust/vvs_parser/src/tests/lua53_cases/pass/binary-operators/tokens.snap b/src/Rust/vvs_parser/src/tests/lua53_cases/pass/binary-operators/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..e998ca3186e51145c32439c2d29b2d6999ee12c7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua53_cases/pass/binary-operators/tokens.snap @@ -0,0 +1,808 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 36 +expression: tokens +input_file: full-moon/tests/lua53_cases/pass/binary-operators +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: a +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Number + text: "1" +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: "&" +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Number + text: "2" +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 16 + line: 2 + character: 1 + end_position: + bytes: 21 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 21 + line: 2 + character: 6 + end_position: + bytes: 22 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 22 + line: 2 + character: 7 + end_position: + bytes: 23 + line: 2 + character: 8 + token_type: + type: Identifier + identifier: b +- start_position: + bytes: 23 + line: 2 + character: 8 + end_position: + bytes: 24 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 24 + line: 2 + character: 9 + end_position: + bytes: 25 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 25 + line: 2 + character: 10 + end_position: + bytes: 26 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 26 + line: 2 + character: 11 + end_position: + bytes: 27 + line: 2 + character: 12 + token_type: + type: Number + text: "1" +- start_position: + bytes: 27 + line: 2 + character: 12 + end_position: + bytes: 28 + line: 2 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 28 + line: 2 + character: 13 + end_position: + bytes: 29 + line: 2 + character: 14 + token_type: + type: Symbol + symbol: "|" +- start_position: + bytes: 29 + line: 2 + character: 14 + end_position: + bytes: 30 + line: 2 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 30 + line: 2 + character: 15 + end_position: + bytes: 31 + line: 2 + character: 16 + token_type: + type: Number + text: "2" +- start_position: + bytes: 31 + line: 2 + character: 16 + end_position: + bytes: 32 + line: 2 + character: 16 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 32 + line: 3 + character: 1 + end_position: + bytes: 37 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 37 + line: 3 + character: 6 + end_position: + bytes: 38 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 38 + line: 3 + character: 7 + end_position: + bytes: 39 + line: 3 + character: 8 + token_type: + type: Identifier + identifier: c +- start_position: + bytes: 39 + line: 3 + character: 8 + end_position: + bytes: 40 + line: 3 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 40 + line: 3 + character: 9 + end_position: + bytes: 41 + line: 3 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 41 + line: 3 + character: 10 + end_position: + bytes: 42 + line: 3 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 42 + line: 3 + character: 11 + end_position: + bytes: 43 + line: 3 + character: 12 + token_type: + type: Number + text: "1" +- start_position: + bytes: 43 + line: 3 + character: 12 + end_position: + bytes: 44 + line: 3 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 44 + line: 3 + character: 13 + end_position: + bytes: 46 + line: 3 + character: 15 + token_type: + type: Symbol + symbol: "<~" +- start_position: + bytes: 46 + line: 3 + character: 15 + end_position: + bytes: 47 + line: 3 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 47 + line: 3 + character: 16 + end_position: + bytes: 48 + line: 3 + character: 17 + token_type: + type: Number + text: "2" +- start_position: + bytes: 48 + line: 3 + character: 17 + end_position: + bytes: 49 + line: 3 + character: 17 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 49 + line: 4 + character: 1 + end_position: + bytes: 54 + line: 4 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 54 + line: 4 + character: 6 + end_position: + bytes: 55 + line: 4 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 55 + line: 4 + character: 7 + end_position: + bytes: 56 + line: 4 + character: 8 + token_type: + type: Identifier + identifier: d +- start_position: + bytes: 56 + line: 4 + character: 8 + end_position: + bytes: 57 + line: 4 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 57 + line: 4 + character: 9 + end_position: + bytes: 58 + line: 4 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 58 + line: 4 + character: 10 + end_position: + bytes: 59 + line: 4 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 59 + line: 4 + character: 11 + end_position: + bytes: 60 + line: 4 + character: 12 + token_type: + type: Number + text: "1" +- start_position: + bytes: 60 + line: 4 + character: 12 + end_position: + bytes: 61 + line: 4 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 61 + line: 4 + character: 13 + end_position: + bytes: 63 + line: 4 + character: 15 + token_type: + type: Symbol + symbol: ~> +- start_position: + bytes: 63 + line: 4 + character: 15 + end_position: + bytes: 64 + line: 4 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 64 + line: 4 + character: 16 + end_position: + bytes: 65 + line: 4 + character: 17 + token_type: + type: Number + text: "2" +- start_position: + bytes: 65 + line: 4 + character: 17 + end_position: + bytes: 66 + line: 4 + character: 17 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 66 + line: 5 + character: 1 + end_position: + bytes: 71 + line: 5 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 71 + line: 5 + character: 6 + end_position: + bytes: 72 + line: 5 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 72 + line: 5 + character: 7 + end_position: + bytes: 73 + line: 5 + character: 8 + token_type: + type: Identifier + identifier: e +- start_position: + bytes: 73 + line: 5 + character: 8 + end_position: + bytes: 74 + line: 5 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 74 + line: 5 + character: 9 + end_position: + bytes: 75 + line: 5 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 75 + line: 5 + character: 10 + end_position: + bytes: 76 + line: 5 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 76 + line: 5 + character: 11 + end_position: + bytes: 77 + line: 5 + character: 12 + token_type: + type: Number + text: "1" +- start_position: + bytes: 77 + line: 5 + character: 12 + end_position: + bytes: 78 + line: 5 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 78 + line: 5 + character: 13 + end_position: + bytes: 79 + line: 5 + character: 14 + token_type: + type: Symbol + symbol: "~" +- start_position: + bytes: 79 + line: 5 + character: 14 + end_position: + bytes: 80 + line: 5 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 80 + line: 5 + character: 15 + end_position: + bytes: 81 + line: 5 + character: 16 + token_type: + type: Number + text: "2" +- start_position: + bytes: 81 + line: 5 + character: 16 + end_position: + bytes: 82 + line: 5 + character: 16 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 82 + line: 6 + character: 1 + end_position: + bytes: 87 + line: 6 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 87 + line: 6 + character: 6 + end_position: + bytes: 88 + line: 6 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 88 + line: 6 + character: 7 + end_position: + bytes: 89 + line: 6 + character: 8 + token_type: + type: Identifier + identifier: f +- start_position: + bytes: 89 + line: 6 + character: 8 + end_position: + bytes: 90 + line: 6 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 90 + line: 6 + character: 9 + end_position: + bytes: 91 + line: 6 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 91 + line: 6 + character: 10 + end_position: + bytes: 92 + line: 6 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 92 + line: 6 + character: 11 + end_position: + bytes: 93 + line: 6 + character: 12 + token_type: + type: Number + text: "1" +- start_position: + bytes: 93 + line: 6 + character: 12 + end_position: + bytes: 94 + line: 6 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 94 + line: 6 + character: 13 + end_position: + bytes: 96 + line: 6 + character: 15 + token_type: + type: Symbol + symbol: // +- start_position: + bytes: 96 + line: 6 + character: 15 + end_position: + bytes: 97 + line: 6 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 97 + line: 6 + character: 16 + end_position: + bytes: 98 + line: 6 + character: 17 + token_type: + type: Number + text: "2" +- start_position: + bytes: 98 + line: 6 + character: 17 + end_position: + bytes: 99 + line: 6 + character: 17 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 99 + line: 7 + character: 1 + end_position: + bytes: 99 + line: 7 + character: 1 + token_type: + type: Eof diff --git a/src/Rust/vvs_parser/src/tests/lua53_cases/pass/unary-operators/ast.snap b/src/Rust/vvs_parser/src/tests/lua53_cases/pass/unary-operators/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..bffea940a1639509fe59c498465cb9b41fa812b8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua53_cases/pass/unary-operators/ast.snap @@ -0,0 +1,126 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/lua53_cases/pass/unary-operators +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + UnaryOperator: + unop: + Tilde: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "~" + trailing_trivia: [] + expression: + Number: + leading_trivia: [] + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Number + text: "1" + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/lua53_cases/pass/unary-operators/source.lua b/src/Rust/vvs_parser/src/tests/lua53_cases/pass/unary-operators/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..55c2a6c3c69374eb21a25d05e09e6b6bbf0076fc --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua53_cases/pass/unary-operators/source.lua @@ -0,0 +1 @@ +local x = ~1 \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/lua53_cases/pass/unary-operators/tokens.snap b/src/Rust/vvs_parser/src/tests/lua53_cases/pass/unary-operators/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..cc697e6e0b37ff3f21d8ef5667f4a35f15db5376 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua53_cases/pass/unary-operators/tokens.snap @@ -0,0 +1,103 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: "~" +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Number + text: "1" +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-1/ast.snap b/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..2b426b0b2bfb4a6d7192db6b42c022f386e0ee4b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-1/ast.snap @@ -0,0 +1,127 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.ast +input_file: full-moon/tests/lua54_cases/fail/parser/unclosed-attribute-1 +--- +nodes: + stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Identifier + identifier: name + trailing_trivia: + - start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " + attributes: + - brackets: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: "<" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: ">" + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Identifier + identifier: const + trailing_trivia: [] + equal_token: ~ + expr_list: + pairs: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-1/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-1/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..6dada6e11d4f736625b87fc716649afca84d905a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-1/ast_to_string.snap @@ -0,0 +1,7 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/lua54_cases/fail/parser/unclosed-attribute-1 +--- +local name <const> + diff --git a/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-1/error.snap b/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-1/error.snap new file mode 100644 index 0000000000000000000000000000000000000000..afe5c2f91ecc6d77ea6d72bfd0155898e58eb5f6 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-1/error.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 100 +expression: error +--- +UnexpectedToken: + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Eof + additional: "expected `>`" + diff --git a/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-1/error_display.snap b/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-1/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..59128ce548d5d5f6b0db6508afbc68b879c67592 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-1/error_display.snap @@ -0,0 +1,12 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/lua54_cases/fail/parser/unclosed-attribute-1 +--- +error[ast]: expected `>` to close attribute + ┌─ source.lua:1:18 + │ +1 │ local name <const + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-1/errors.snap b/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-1/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..439a596ae60cd7c6fe102efb245ce47419b088bc --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-1/errors.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/lua54_cases/fail/parser/unclosed-attribute-1 +--- +- AstError: + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Eof + additional: "expected `>` to close attribute" + diff --git a/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-1/source.lua b/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..fe2df6e9620a5045ae934a0ab1f11c27732966fb --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-1/source.lua @@ -0,0 +1 @@ +local name <const \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-1/tokens.snap b/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..82429fb30ad5d61baef68795365085346625bf08 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-1/tokens.snap @@ -0,0 +1,82 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 94 +expression: tokens +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Identifier + identifier: name +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: "<" +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Identifier + identifier: const +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-2/ast.snap b/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..bc5e7f75233770fb0559f4da59c48c6df1133853 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-2/ast.snap @@ -0,0 +1,179 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.ast +input_file: full-moon/tests/lua54_cases/fail/parser/unclosed-attribute-2 +--- +nodes: + stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Identifier + identifier: name + trailing_trivia: + - start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " + attributes: + - brackets: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: "<" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: ">" + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Identifier + identifier: const + trailing_trivia: + - start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Number + text: "10" + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 22 + line: 1 + character: 23 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-2/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-2/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..d944282292e2c242bdfa0b1b8bdc9a4ebb6d30e6 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-2/ast_to_string.snap @@ -0,0 +1,7 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: "vvs_parser::print(&ast)" +input_file: full-moon/tests/lua54_cases/fail/parser/unclosed-attribute-2 +--- +local name <const >= 10 + diff --git a/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-2/error.snap b/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-2/error.snap new file mode 100644 index 0000000000000000000000000000000000000000..ce13d5475433d1b31c8e2d2fc2772f1b71379f6c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-2/error.snap @@ -0,0 +1,20 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 100 +expression: error +--- +UnexpectedToken: + token: + start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: "=" + additional: "expected `>`" + diff --git a/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-2/error_display.snap b/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-2/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..b93f53ce2b3ca68182c3aad80c44ecc8ec76a38c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-2/error_display.snap @@ -0,0 +1,12 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: full-moon/tests/lua54_cases/fail/parser/unclosed-attribute-2 +--- +error[ast]: expected `>` to close attribute + ┌─ source.lua:1:19 + │ +1 │ local name <const = 10 + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-2/errors.snap b/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-2/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..da498cb7fe2b322aabf7f7c0f2ca4d0d6bc56f9b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-2/errors.snap @@ -0,0 +1,20 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +input_file: full-moon/tests/lua54_cases/fail/parser/unclosed-attribute-2 +--- +- AstError: + token: + start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: "=" + additional: "expected `>` to close attribute" + diff --git a/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-2/source.lua b/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..3213aacec1acbff116cfe6fb3f94a69c8b83f950 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-2/source.lua @@ -0,0 +1 @@ +local name <const = 10 \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-2/tokens.snap b/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..e5477525edddc0f2edcd5a7166f586ce8f5007e9 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua54_cases/fail/parser/unclosed-attribute-2/tokens.snap @@ -0,0 +1,126 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 94 +expression: tokens +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Identifier + identifier: name +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: "<" +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Identifier + identifier: const +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Number + text: "10" +- start_position: + bytes: 22 + line: 1 + character: 23 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/lua54_cases/pass/attributes/ast.snap b/src/Rust/vvs_parser/src/tests/lua54_cases/pass/attributes/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..76f534631a9be237e0fe834e47cd5711f34ee68c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua54_cases/pass/attributes/ast.snap @@ -0,0 +1,1051 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/lua54_cases/pass/attributes +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: a + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + attributes: + - brackets: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "<" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: ">" + trailing_trivia: + - start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Whitespace + characters: " " + name: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Identifier + identifier: const + trailing_trivia: [] + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Number + text: "5" + trailing_trivia: + - start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 20 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 20 + line: 2 + character: 1 + end_position: + bytes: 25 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 25 + line: 2 + character: 6 + end_position: + bytes: 26 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 26 + line: 2 + character: 7 + end_position: + bytes: 27 + line: 2 + character: 8 + token_type: + type: Identifier + identifier: d + trailing_trivia: + - start_position: + bytes: 27 + line: 2 + character: 8 + end_position: + bytes: 28 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " + attributes: + - brackets: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 28 + line: 2 + character: 9 + end_position: + bytes: 29 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: "<" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 34 + line: 2 + character: 15 + end_position: + bytes: 35 + line: 2 + character: 16 + token_type: + type: Symbol + symbol: ">" + trailing_trivia: + - start_position: + bytes: 35 + line: 2 + character: 16 + end_position: + bytes: 36 + line: 2 + character: 16 + token_type: + type: Whitespace + characters: "\n" + name: + leading_trivia: [] + token: + start_position: + bytes: 29 + line: 2 + character: 10 + end_position: + bytes: 34 + line: 2 + character: 15 + token_type: + type: Identifier + identifier: close + trailing_trivia: [] + equal_token: ~ + expr_list: + pairs: [] + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 36 + line: 3 + character: 1 + end_position: + bytes: 41 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 41 + line: 3 + character: 6 + end_position: + bytes: 42 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - Punctuated: + - leading_trivia: [] + token: + start_position: + bytes: 42 + line: 3 + character: 7 + end_position: + bytes: 43 + line: 3 + character: 8 + token_type: + type: Identifier + identifier: e + trailing_trivia: + - start_position: + bytes: 43 + line: 3 + character: 8 + end_position: + bytes: 44 + line: 3 + character: 9 + token_type: + type: Whitespace + characters: " " + - leading_trivia: [] + token: + start_position: + bytes: 51 + line: 3 + character: 16 + end_position: + bytes: 52 + line: 3 + character: 17 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 52 + line: 3 + character: 17 + end_position: + bytes: 53 + line: 3 + character: 18 + token_type: + type: Whitespace + characters: " " + - End: + leading_trivia: [] + token: + start_position: + bytes: 53 + line: 3 + character: 18 + end_position: + bytes: 54 + line: 3 + character: 19 + token_type: + type: Identifier + identifier: f + trailing_trivia: + - start_position: + bytes: 54 + line: 3 + character: 19 + end_position: + bytes: 55 + line: 3 + character: 20 + token_type: + type: Whitespace + characters: " " + attributes: + - brackets: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 44 + line: 3 + character: 9 + end_position: + bytes: 45 + line: 3 + character: 10 + token_type: + type: Symbol + symbol: "<" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 50 + line: 3 + character: 15 + end_position: + bytes: 51 + line: 3 + character: 16 + token_type: + type: Symbol + symbol: ">" + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 45 + line: 3 + character: 10 + end_position: + bytes: 50 + line: 3 + character: 15 + token_type: + type: Identifier + identifier: const + trailing_trivia: [] + - brackets: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 55 + line: 3 + character: 20 + end_position: + bytes: 56 + line: 3 + character: 21 + token_type: + type: Symbol + symbol: "<" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 61 + line: 3 + character: 26 + end_position: + bytes: 62 + line: 3 + character: 27 + token_type: + type: Symbol + symbol: ">" + trailing_trivia: + - start_position: + bytes: 62 + line: 3 + character: 27 + end_position: + bytes: 63 + line: 3 + character: 28 + token_type: + type: Whitespace + characters: " " + name: + leading_trivia: [] + token: + start_position: + bytes: 56 + line: 3 + character: 21 + end_position: + bytes: 61 + line: 3 + character: 26 + token_type: + type: Identifier + identifier: close + trailing_trivia: [] + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 63 + line: 3 + character: 28 + end_position: + bytes: 64 + line: 3 + character: 29 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 64 + line: 3 + character: 29 + end_position: + bytes: 65 + line: 3 + character: 30 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - Punctuated: + - Number: + leading_trivia: [] + token: + start_position: + bytes: 65 + line: 3 + character: 30 + end_position: + bytes: 66 + line: 3 + character: 31 + token_type: + type: Number + text: "1" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 66 + line: 3 + character: 31 + end_position: + bytes: 67 + line: 3 + character: 32 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 67 + line: 3 + character: 32 + end_position: + bytes: 68 + line: 3 + character: 33 + token_type: + type: Whitespace + characters: " " + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 68 + line: 3 + character: 33 + end_position: + bytes: 69 + line: 3 + character: 34 + token_type: + type: Number + text: "2" + trailing_trivia: + - start_position: + bytes: 69 + line: 3 + character: 34 + end_position: + bytes: 70 + line: 3 + character: 34 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 70 + line: 4 + character: 1 + end_position: + bytes: 75 + line: 4 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 75 + line: 4 + character: 6 + end_position: + bytes: 76 + line: 4 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - Punctuated: + - leading_trivia: [] + token: + start_position: + bytes: 76 + line: 4 + character: 7 + end_position: + bytes: 77 + line: 4 + character: 8 + token_type: + type: Identifier + identifier: g + trailing_trivia: + - start_position: + bytes: 77 + line: 4 + character: 8 + end_position: + bytes: 78 + line: 4 + character: 9 + token_type: + type: Whitespace + characters: " " + - leading_trivia: [] + token: + start_position: + bytes: 85 + line: 4 + character: 16 + end_position: + bytes: 86 + line: 4 + character: 17 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 86 + line: 4 + character: 17 + end_position: + bytes: 87 + line: 4 + character: 18 + token_type: + type: Whitespace + characters: " " + - End: + leading_trivia: [] + token: + start_position: + bytes: 87 + line: 4 + character: 18 + end_position: + bytes: 88 + line: 4 + character: 19 + token_type: + type: Identifier + identifier: h + trailing_trivia: + - start_position: + bytes: 88 + line: 4 + character: 19 + end_position: + bytes: 89 + line: 4 + character: 20 + token_type: + type: Whitespace + characters: " " + attributes: + - brackets: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 78 + line: 4 + character: 9 + end_position: + bytes: 79 + line: 4 + character: 10 + token_type: + type: Symbol + symbol: "<" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 84 + line: 4 + character: 15 + end_position: + bytes: 85 + line: 4 + character: 16 + token_type: + type: Symbol + symbol: ">" + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 79 + line: 4 + character: 10 + end_position: + bytes: 84 + line: 4 + character: 15 + token_type: + type: Identifier + identifier: const + trailing_trivia: [] + - brackets: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 89 + line: 4 + character: 20 + end_position: + bytes: 90 + line: 4 + character: 21 + token_type: + type: Symbol + symbol: "<" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 95 + line: 4 + character: 26 + end_position: + bytes: 96 + line: 4 + character: 27 + token_type: + type: Symbol + symbol: ">" + trailing_trivia: + - start_position: + bytes: 96 + line: 4 + character: 27 + end_position: + bytes: 97 + line: 4 + character: 27 + token_type: + type: Whitespace + characters: "\n" + name: + leading_trivia: [] + token: + start_position: + bytes: 90 + line: 4 + character: 21 + end_position: + bytes: 95 + line: 4 + character: 26 + token_type: + type: Identifier + identifier: close + trailing_trivia: [] + equal_token: ~ + expr_list: + pairs: [] + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 97 + line: 5 + character: 1 + end_position: + bytes: 102 + line: 5 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 102 + line: 5 + character: 6 + end_position: + bytes: 103 + line: 5 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - Punctuated: + - leading_trivia: [] + token: + start_position: + bytes: 103 + line: 5 + character: 7 + end_position: + bytes: 104 + line: 5 + character: 8 + token_type: + type: Identifier + identifier: i + trailing_trivia: + - start_position: + bytes: 104 + line: 5 + character: 8 + end_position: + bytes: 105 + line: 5 + character: 9 + token_type: + type: Whitespace + characters: " " + - leading_trivia: [] + token: + start_position: + bytes: 112 + line: 5 + character: 16 + end_position: + bytes: 113 + line: 5 + character: 17 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 113 + line: 5 + character: 17 + end_position: + bytes: 114 + line: 5 + character: 18 + token_type: + type: Whitespace + characters: " " + - Punctuated: + - leading_trivia: [] + token: + start_position: + bytes: 114 + line: 5 + character: 18 + end_position: + bytes: 115 + line: 5 + character: 19 + token_type: + type: Identifier + identifier: j + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 115 + line: 5 + character: 19 + end_position: + bytes: 116 + line: 5 + character: 20 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 116 + line: 5 + character: 20 + end_position: + bytes: 117 + line: 5 + character: 21 + token_type: + type: Whitespace + characters: " " + - End: + leading_trivia: [] + token: + start_position: + bytes: 117 + line: 5 + character: 21 + end_position: + bytes: 118 + line: 5 + character: 22 + token_type: + type: Identifier + identifier: k + trailing_trivia: + - start_position: + bytes: 118 + line: 5 + character: 22 + end_position: + bytes: 119 + line: 5 + character: 23 + token_type: + type: Whitespace + characters: " " + attributes: + - brackets: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 105 + line: 5 + character: 9 + end_position: + bytes: 106 + line: 5 + character: 10 + token_type: + type: Symbol + symbol: "<" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 111 + line: 5 + character: 15 + end_position: + bytes: 112 + line: 5 + character: 16 + token_type: + type: Symbol + symbol: ">" + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 106 + line: 5 + character: 10 + end_position: + bytes: 111 + line: 5 + character: 15 + token_type: + type: Identifier + identifier: const + trailing_trivia: [] + - ~ + - brackets: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 119 + line: 5 + character: 23 + end_position: + bytes: 120 + line: 5 + character: 24 + token_type: + type: Symbol + symbol: "<" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 125 + line: 5 + character: 29 + end_position: + bytes: 126 + line: 5 + character: 30 + token_type: + type: Symbol + symbol: ">" + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 120 + line: 5 + character: 24 + end_position: + bytes: 125 + line: 5 + character: 29 + token_type: + type: Identifier + identifier: close + trailing_trivia: [] + equal_token: ~ + expr_list: + pairs: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/lua54_cases/pass/attributes/source.lua b/src/Rust/vvs_parser/src/tests/lua54_cases/pass/attributes/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..4e1044f9347583c57a36632ec51bad583afbbc5b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua54_cases/pass/attributes/source.lua @@ -0,0 +1,5 @@ +local a <const> = 5 +local d <close> +local e <const>, f <close> = 1, 2 +local g <const>, h <close> +local i <const>, j, k <close> \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/lua54_cases/pass/attributes/tokens.snap b/src/Rust/vvs_parser/src/tests/lua54_cases/pass/attributes/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..8acf2fa750775661ef8dfc0e96c9d503f70d0745 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/lua54_cases/pass/attributes/tokens.snap @@ -0,0 +1,829 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: a +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "<" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Identifier + identifier: const +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: ">" +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Number + text: "5" +- start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 20 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 20 + line: 2 + character: 1 + end_position: + bytes: 25 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 25 + line: 2 + character: 6 + end_position: + bytes: 26 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 26 + line: 2 + character: 7 + end_position: + bytes: 27 + line: 2 + character: 8 + token_type: + type: Identifier + identifier: d +- start_position: + bytes: 27 + line: 2 + character: 8 + end_position: + bytes: 28 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 28 + line: 2 + character: 9 + end_position: + bytes: 29 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: "<" +- start_position: + bytes: 29 + line: 2 + character: 10 + end_position: + bytes: 34 + line: 2 + character: 15 + token_type: + type: Identifier + identifier: close +- start_position: + bytes: 34 + line: 2 + character: 15 + end_position: + bytes: 35 + line: 2 + character: 16 + token_type: + type: Symbol + symbol: ">" +- start_position: + bytes: 35 + line: 2 + character: 16 + end_position: + bytes: 36 + line: 2 + character: 16 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 36 + line: 3 + character: 1 + end_position: + bytes: 41 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 41 + line: 3 + character: 6 + end_position: + bytes: 42 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 42 + line: 3 + character: 7 + end_position: + bytes: 43 + line: 3 + character: 8 + token_type: + type: Identifier + identifier: e +- start_position: + bytes: 43 + line: 3 + character: 8 + end_position: + bytes: 44 + line: 3 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 44 + line: 3 + character: 9 + end_position: + bytes: 45 + line: 3 + character: 10 + token_type: + type: Symbol + symbol: "<" +- start_position: + bytes: 45 + line: 3 + character: 10 + end_position: + bytes: 50 + line: 3 + character: 15 + token_type: + type: Identifier + identifier: const +- start_position: + bytes: 50 + line: 3 + character: 15 + end_position: + bytes: 51 + line: 3 + character: 16 + token_type: + type: Symbol + symbol: ">" +- start_position: + bytes: 51 + line: 3 + character: 16 + end_position: + bytes: 52 + line: 3 + character: 17 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 52 + line: 3 + character: 17 + end_position: + bytes: 53 + line: 3 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 53 + line: 3 + character: 18 + end_position: + bytes: 54 + line: 3 + character: 19 + token_type: + type: Identifier + identifier: f +- start_position: + bytes: 54 + line: 3 + character: 19 + end_position: + bytes: 55 + line: 3 + character: 20 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 55 + line: 3 + character: 20 + end_position: + bytes: 56 + line: 3 + character: 21 + token_type: + type: Symbol + symbol: "<" +- start_position: + bytes: 56 + line: 3 + character: 21 + end_position: + bytes: 61 + line: 3 + character: 26 + token_type: + type: Identifier + identifier: close +- start_position: + bytes: 61 + line: 3 + character: 26 + end_position: + bytes: 62 + line: 3 + character: 27 + token_type: + type: Symbol + symbol: ">" +- start_position: + bytes: 62 + line: 3 + character: 27 + end_position: + bytes: 63 + line: 3 + character: 28 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 63 + line: 3 + character: 28 + end_position: + bytes: 64 + line: 3 + character: 29 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 64 + line: 3 + character: 29 + end_position: + bytes: 65 + line: 3 + character: 30 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 65 + line: 3 + character: 30 + end_position: + bytes: 66 + line: 3 + character: 31 + token_type: + type: Number + text: "1" +- start_position: + bytes: 66 + line: 3 + character: 31 + end_position: + bytes: 67 + line: 3 + character: 32 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 67 + line: 3 + character: 32 + end_position: + bytes: 68 + line: 3 + character: 33 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 68 + line: 3 + character: 33 + end_position: + bytes: 69 + line: 3 + character: 34 + token_type: + type: Number + text: "2" +- start_position: + bytes: 69 + line: 3 + character: 34 + end_position: + bytes: 70 + line: 3 + character: 34 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 70 + line: 4 + character: 1 + end_position: + bytes: 75 + line: 4 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 75 + line: 4 + character: 6 + end_position: + bytes: 76 + line: 4 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 76 + line: 4 + character: 7 + end_position: + bytes: 77 + line: 4 + character: 8 + token_type: + type: Identifier + identifier: g +- start_position: + bytes: 77 + line: 4 + character: 8 + end_position: + bytes: 78 + line: 4 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 78 + line: 4 + character: 9 + end_position: + bytes: 79 + line: 4 + character: 10 + token_type: + type: Symbol + symbol: "<" +- start_position: + bytes: 79 + line: 4 + character: 10 + end_position: + bytes: 84 + line: 4 + character: 15 + token_type: + type: Identifier + identifier: const +- start_position: + bytes: 84 + line: 4 + character: 15 + end_position: + bytes: 85 + line: 4 + character: 16 + token_type: + type: Symbol + symbol: ">" +- start_position: + bytes: 85 + line: 4 + character: 16 + end_position: + bytes: 86 + line: 4 + character: 17 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 86 + line: 4 + character: 17 + end_position: + bytes: 87 + line: 4 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 87 + line: 4 + character: 18 + end_position: + bytes: 88 + line: 4 + character: 19 + token_type: + type: Identifier + identifier: h +- start_position: + bytes: 88 + line: 4 + character: 19 + end_position: + bytes: 89 + line: 4 + character: 20 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 89 + line: 4 + character: 20 + end_position: + bytes: 90 + line: 4 + character: 21 + token_type: + type: Symbol + symbol: "<" +- start_position: + bytes: 90 + line: 4 + character: 21 + end_position: + bytes: 95 + line: 4 + character: 26 + token_type: + type: Identifier + identifier: close +- start_position: + bytes: 95 + line: 4 + character: 26 + end_position: + bytes: 96 + line: 4 + character: 27 + token_type: + type: Symbol + symbol: ">" +- start_position: + bytes: 96 + line: 4 + character: 27 + end_position: + bytes: 97 + line: 4 + character: 27 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 97 + line: 5 + character: 1 + end_position: + bytes: 102 + line: 5 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 102 + line: 5 + character: 6 + end_position: + bytes: 103 + line: 5 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 103 + line: 5 + character: 7 + end_position: + bytes: 104 + line: 5 + character: 8 + token_type: + type: Identifier + identifier: i +- start_position: + bytes: 104 + line: 5 + character: 8 + end_position: + bytes: 105 + line: 5 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 105 + line: 5 + character: 9 + end_position: + bytes: 106 + line: 5 + character: 10 + token_type: + type: Symbol + symbol: "<" +- start_position: + bytes: 106 + line: 5 + character: 10 + end_position: + bytes: 111 + line: 5 + character: 15 + token_type: + type: Identifier + identifier: const +- start_position: + bytes: 111 + line: 5 + character: 15 + end_position: + bytes: 112 + line: 5 + character: 16 + token_type: + type: Symbol + symbol: ">" +- start_position: + bytes: 112 + line: 5 + character: 16 + end_position: + bytes: 113 + line: 5 + character: 17 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 113 + line: 5 + character: 17 + end_position: + bytes: 114 + line: 5 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 114 + line: 5 + character: 18 + end_position: + bytes: 115 + line: 5 + character: 19 + token_type: + type: Identifier + identifier: j +- start_position: + bytes: 115 + line: 5 + character: 19 + end_position: + bytes: 116 + line: 5 + character: 20 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 116 + line: 5 + character: 20 + end_position: + bytes: 117 + line: 5 + character: 21 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 117 + line: 5 + character: 21 + end_position: + bytes: 118 + line: 5 + character: 22 + token_type: + type: Identifier + identifier: k +- start_position: + bytes: 118 + line: 5 + character: 22 + end_position: + bytes: 119 + line: 5 + character: 23 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 119 + line: 5 + character: 23 + end_position: + bytes: 120 + line: 5 + character: 24 + token_type: + type: Symbol + symbol: "<" +- start_position: + bytes: 120 + line: 5 + character: 24 + end_position: + bytes: 125 + line: 5 + character: 29 + token_type: + type: Identifier + identifier: close +- start_position: + bytes: 125 + line: 5 + character: 29 + end_position: + bytes: 126 + line: 5 + character: 30 + token_type: + type: Symbol + symbol: ">" +- start_position: + bytes: 126 + line: 5 + character: 30 + end_position: + bytes: 126 + line: 5 + character: 30 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/mod.rs b/src/Rust/vvs_parser/src/tests/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..2a2f35e8450f6a6e4dc560b4da5c346fff210d36 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/mod.rs @@ -0,0 +1,8 @@ +mod comments_around_functions; +mod common; +mod derive_node; +mod fail_cases; +mod node; +mod one_line_range; +mod pass_cases; +mod visitors; diff --git a/src/Rust/vvs_parser/src/tests/node.rs b/src/Rust/vvs_parser/src/tests/node.rs new file mode 100644 index 0000000000000000000000000000000000000000..35651ccc32ad6106b79922736408ab2f18a01603 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/node.rs @@ -0,0 +1,38 @@ +use crate::{node::Node, prelude::parser::parse_lua_tree as parse}; + +#[test] +fn surrounding_trivia() { + let ast = parse(include_str!("cases/pass/local-assignment-5/source.lua")).unwrap(); + let stmt = ast.nodes().stmts().nth(1); + + let (prev, _) = stmt.surrounding_trivia(); + + let mut prev = prev.into_iter(); + assert_eq!(prev.next().unwrap().to_string(), "-- Then a comment"); + assert_eq!(prev.next().unwrap().to_string(), "\n"); + assert_eq!(prev.next(), None); +} + +#[test] +fn test_similar() { + let ast = parse("local x = 1; --[[ uh oh, filler ]] local x = 1; local x = 2;").unwrap(); + let stmts = ast.nodes().stmts().collect::<Vec<_>>(); + + assert!(stmts[0].similar(stmts[1])); + assert!(stmts[1].similar(stmts[0])); + assert!(!stmts[0].similar(stmts[2])); +} + +#[test] +fn test_tokens_collect() { + let source = parse("local abcd = 1").unwrap(); + let tokens = source.nodes().tokens(); + assert_eq!(tokens.count(), 4); +} + +#[test] +fn test_tokens_back() { + let source = parse("local abcd = 1").unwrap(); + let mut tokens = source.nodes().tokens(); + assert_eq!(tokens.next_back().unwrap().to_string(), "1"); +} diff --git a/src/Rust/vvs_parser/src/tests/one_line_range.rs b/src/Rust/vvs_parser/src/tests/one_line_range.rs new file mode 100644 index 0000000000000000000000000000000000000000..5534228938c46718eddf5e62d4f3bf5f52a84905 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/one_line_range.rs @@ -0,0 +1,26 @@ +use crate::{node::Node, prelude::parser::parse_lua_tree as parse}; + +#[test] +fn test_one_line_range() { + let ast = parse( + r#" + + local x = 1 + + local y = 1 + + local function x() print(1) end + + function x() print(1) end + + for index, value in pairs(list) do print(index, value) end + + "#, + ) + .unwrap(); + + for stmt in ast.nodes().stmts() { + let (start, end) = stmt.range().unwrap(); + assert_eq!(end.line() - start.line(), 0, "node {stmt:?} does not have a range on the same line"); + } +} diff --git a/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword1/error_display.snap b/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword1/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..a1f2e073376f0c2e61e48179960951db9707e821 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword1/error_display.snap @@ -0,0 +1,10 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: vvs_parser/tests/option_cases/fail/parser/keyword1 +--- +error[ast]: expected the name of an option + ┌─ source.ini:2:1 + │ +2 │ option = 1 + │ ^^^^^^ diff --git a/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword1/errors.snap b/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword1/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..3d699fbc13489f352d4321e99b95ca679d17813f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword1/errors.snap @@ -0,0 +1,19 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: result.errors() +input_file: vvs_parser/tests/option_cases/fail/parser/keyword1 +--- +- AstError: + token: + start_position: + bytes: 9 + line: 2 + character: 1 + end_position: + bytes: 15 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: option + additional: expected the name of an option diff --git a/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword1/option_table.snap b/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword1/option_table.snap new file mode 100644 index 0000000000000000000000000000000000000000..32091d523dc80a4b6a0d9b9cb6d5fd2ec15c8f9e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword1/option_table.snap @@ -0,0 +1,6 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: result.option_table() +input_file: vvs_parser/tests/option_cases/fail/parser/keyword1 +--- +modules: [] diff --git a/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword1/source.ini b/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword1/source.ini new file mode 100644 index 0000000000000000000000000000000000000000..c0348e2fe530a08dfd13b7634e505815116a8584 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword1/source.ini @@ -0,0 +1,2 @@ +[module] +option = 1 diff --git a/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword1/tokens.snap b/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..2098a5353a38485707a99621284b69245bc8c3ff --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword1/tokens.snap @@ -0,0 +1,125 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: tokens +input_file: vvs_parser/tests/option_cases/fail/parser/keyword1 +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: "[" +- start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: module +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "]" +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 9 + line: 2 + character: 1 + end_position: + bytes: 15 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: option +- start_position: + bytes: 15 + line: 2 + character: 7 + end_position: + bytes: 16 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 16 + line: 2 + character: 8 + end_position: + bytes: 17 + line: 2 + character: 9 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 17 + line: 2 + character: 9 + end_position: + bytes: 18 + line: 2 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 18 + line: 2 + character: 10 + end_position: + bytes: 19 + line: 2 + character: 11 + token_type: + type: Number + text: "1" +- start_position: + bytes: 19 + line: 2 + character: 11 + end_position: + bytes: 20 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 20 + line: 3 + character: 1 + end_position: + bytes: 20 + line: 3 + character: 1 + token_type: + type: Eof diff --git a/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword2/error_display.snap b/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword2/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..5dcc37a4ed30f83b4942670ce4491d729519f41b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword2/error_display.snap @@ -0,0 +1,16 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: vvs_parser/tests/option_cases/fail/parser/keyword2 +--- +error[ast]: expected an identifier + ┌─ source.ini:1:2 + │ +1 │ [option] + │ ^^^^^^ + +error[ast]: expected an identifier as the option section name + ┌─ source.ini:1:1 + │ +1 │ [option] + │ ^ diff --git a/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword2/errors.snap b/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword2/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..c45dd138c4d3764c5fc290c990b821bfa62eba4f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword2/errors.snap @@ -0,0 +1,33 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: result.errors() +input_file: vvs_parser/tests/option_cases/fail/parser/keyword2 +--- +- AstError: + token: + start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Symbol + symbol: option + additional: expected an identifier +- AstError: + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: "[" + additional: expected an identifier as the option section name diff --git a/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword2/option_table.snap b/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword2/option_table.snap new file mode 100644 index 0000000000000000000000000000000000000000..14a4c7681464af5bed61cb7adb83525e99bb6a98 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword2/option_table.snap @@ -0,0 +1,6 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: result.option_table() +input_file: vvs_parser/tests/option_cases/fail/parser/keyword2 +--- +modules: [] diff --git a/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword2/source.ini b/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword2/source.ini new file mode 100644 index 0000000000000000000000000000000000000000..dec450e72ea9c39d709794f78466cdd6b7b7747a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword2/source.ini @@ -0,0 +1,2 @@ +[option] +opt1 = 1 diff --git a/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword2/tokens.snap b/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..c553ebbb2efa521137eccff444bf87675cec0879 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/option_cases/fail/parser/keyword2/tokens.snap @@ -0,0 +1,125 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: tokens +input_file: vvs_parser/tests/option_cases/fail/parser/keyword2 +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: "[" +- start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Symbol + symbol: option +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "]" +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 9 + line: 2 + character: 1 + end_position: + bytes: 13 + line: 2 + character: 5 + token_type: + type: Identifier + identifier: opt1 +- start_position: + bytes: 13 + line: 2 + character: 5 + end_position: + bytes: 14 + line: 2 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 14 + line: 2 + character: 6 + end_position: + bytes: 15 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 15 + line: 2 + character: 7 + end_position: + bytes: 16 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 16 + line: 2 + character: 8 + end_position: + bytes: 17 + line: 2 + character: 9 + token_type: + type: Number + text: "1" +- start_position: + bytes: 17 + line: 2 + character: 9 + end_position: + bytes: 18 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 18 + line: 3 + character: 1 + end_position: + bytes: 18 + line: 3 + character: 1 + token_type: + type: Eof diff --git a/src/Rust/vvs_parser/src/tests/option_cases/pass/complex/options.snap b/src/Rust/vvs_parser/src/tests/option_cases/pass/complex/options.snap new file mode 100644 index 0000000000000000000000000000000000000000..ddd63fa80fffc209960c5b6a26a6ea2c493ea5ed --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/option_cases/pass/complex/options.snap @@ -0,0 +1,90 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: options +input_file: vvs_parser/tests/option_cases/pass/complex +--- +modules: + - - module + - - - option1 + - BinaryOperator: + lhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 19 + line: 2 + character: 11 + end_position: + bytes: 20 + line: 2 + character: 12 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 20 + line: 2 + character: 12 + end_position: + bytes: 21 + line: 2 + character: 13 + token_type: + type: Whitespace + characters: " " + binop: + Plus: + leading_trivia: [] + token: + start_position: + bytes: 21 + line: 2 + character: 13 + end_position: + bytes: 22 + line: 2 + character: 14 + token_type: + type: Symbol + symbol: + + trailing_trivia: + - start_position: + bytes: 22 + line: 2 + character: 14 + end_position: + bytes: 23 + line: 2 + character: 15 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 23 + line: 2 + character: 15 + end_position: + bytes: 24 + line: 2 + character: 16 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 24 + line: 2 + character: 16 + end_position: + bytes: 25 + line: 2 + character: 16 + token_type: + type: Whitespace + characters: "\n" diff --git a/src/Rust/vvs_parser/src/tests/option_cases/pass/complex/source.ini b/src/Rust/vvs_parser/src/tests/option_cases/pass/complex/source.ini new file mode 100644 index 0000000000000000000000000000000000000000..188259f9831f7fa5ed26838cb99d99caeaeec949 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/option_cases/pass/complex/source.ini @@ -0,0 +1,2 @@ +[module] +option1 = 1 + 1 diff --git a/src/Rust/vvs_parser/src/tests/option_cases/pass/complex/tokens.snap b/src/Rust/vvs_parser/src/tests/option_cases/pass/complex/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..85e179ff88fa6c8f342229e403a2b524eaecda08 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/option_cases/pass/complex/tokens.snap @@ -0,0 +1,169 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: tokens +input_file: vvs_parser/tests/option_cases/pass/complex +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: "[" +- start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: module +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: "]" +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 9 + line: 2 + character: 1 + end_position: + bytes: 16 + line: 2 + character: 8 + token_type: + type: Identifier + identifier: option1 +- start_position: + bytes: 16 + line: 2 + character: 8 + end_position: + bytes: 17 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 17 + line: 2 + character: 9 + end_position: + bytes: 18 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 18 + line: 2 + character: 10 + end_position: + bytes: 19 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 19 + line: 2 + character: 11 + end_position: + bytes: 20 + line: 2 + character: 12 + token_type: + type: Number + text: "1" +- start_position: + bytes: 20 + line: 2 + character: 12 + end_position: + bytes: 21 + line: 2 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 21 + line: 2 + character: 13 + end_position: + bytes: 22 + line: 2 + character: 14 + token_type: + type: Symbol + symbol: + +- start_position: + bytes: 22 + line: 2 + character: 14 + end_position: + bytes: 23 + line: 2 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 23 + line: 2 + character: 15 + end_position: + bytes: 24 + line: 2 + character: 16 + token_type: + type: Number + text: "1" +- start_position: + bytes: 24 + line: 2 + character: 16 + end_position: + bytes: 25 + line: 2 + character: 16 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 25 + line: 3 + character: 1 + end_position: + bytes: 25 + line: 3 + character: 1 + token_type: + type: Eof diff --git a/src/Rust/vvs_parser/src/tests/option_cases/pass/empty/options.snap b/src/Rust/vvs_parser/src/tests/option_cases/pass/empty/options.snap new file mode 100644 index 0000000000000000000000000000000000000000..17560f8142a28bacdd649ea51304bd1b4d67578b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/option_cases/pass/empty/options.snap @@ -0,0 +1,6 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: options +input_file: vvs_parser/tests/option_cases/pass/empty +--- +modules: [] diff --git a/src/Rust/vvs_parser/src/tests/option_cases/pass/empty/source.ini b/src/Rust/vvs_parser/src/tests/option_cases/pass/empty/source.ini new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/Rust/vvs_parser/src/tests/option_cases/pass/empty/tokens.snap b/src/Rust/vvs_parser/src/tests/option_cases/pass/empty/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..42aa56195d76282c934c878ddaa87f21c94a11b6 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/option_cases/pass/empty/tokens.snap @@ -0,0 +1,15 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: tokens +input_file: vvs_parser/tests/option_cases/pass/empty +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 0 + line: 1 + character: 1 + token_type: + type: Eof diff --git a/src/Rust/vvs_parser/src/tests/option_cases/pass/simple/options.snap b/src/Rust/vvs_parser/src/tests/option_cases/pass/simple/options.snap new file mode 100644 index 0000000000000000000000000000000000000000..ccd02baa5a39951a66d15cd7dda1821e7b086d69 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/option_cases/pass/simple/options.snap @@ -0,0 +1,90 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: options +input_file: vvs_parser/tests/option_cases/pass/simple +--- +modules: + - - module1 + - - - opt1 + - Number: + leading_trivia: [] + token: + start_position: + bytes: 17 + line: 2 + character: 8 + end_position: + bytes: 18 + line: 2 + character: 9 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 18 + line: 2 + character: 9 + end_position: + bytes: 19 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: "\n" + - - opt2 + - Symbol: + leading_trivia: [] + token: + start_position: + bytes: 26 + line: 3 + character: 8 + end_position: + bytes: 30 + line: 3 + character: 12 + token_type: + type: Symbol + symbol: "true" + trailing_trivia: + - start_position: + bytes: 30 + line: 3 + character: 12 + end_position: + bytes: 31 + line: 3 + character: 12 + token_type: + type: Whitespace + characters: "\n" + - - module2 + - - - opt1 + - String: + leading_trivia: [] + token: + start_position: + bytes: 49 + line: 6 + character: 8 + end_position: + bytes: 60 + line: 6 + character: 19 + token_type: + type: StringLiteral + literal: something + quote_type: Double + trailing_trivia: + - start_position: + bytes: 60 + line: 6 + character: 19 + end_position: + bytes: 61 + line: 6 + character: 19 + token_type: + type: Whitespace + characters: "\n" diff --git a/src/Rust/vvs_parser/src/tests/option_cases/pass/simple/source.ini b/src/Rust/vvs_parser/src/tests/option_cases/pass/simple/source.ini new file mode 100644 index 0000000000000000000000000000000000000000..1950245e560122075890833d3431ee04f4ba7d78 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/option_cases/pass/simple/source.ini @@ -0,0 +1,6 @@ +[module1] +opt1 = 1 +opt2 = true + +[module2] +opt1 = "something" diff --git a/src/Rust/vvs_parser/src/tests/option_cases/pass/simple/tokens.snap b/src/Rust/vvs_parser/src/tests/option_cases/pass/simple/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..46a45bb6a8c6935a98219f38f20a374fdb88239c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/option_cases/pass/simple/tokens.snap @@ -0,0 +1,313 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: tokens +input_file: vvs_parser/tests/option_cases/pass/simple +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: "[" +- start_position: + bytes: 1 + line: 1 + character: 2 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Identifier + identifier: module1 +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "]" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 10 + line: 2 + character: 1 + end_position: + bytes: 14 + line: 2 + character: 5 + token_type: + type: Identifier + identifier: opt1 +- start_position: + bytes: 14 + line: 2 + character: 5 + end_position: + bytes: 15 + line: 2 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 15 + line: 2 + character: 6 + end_position: + bytes: 16 + line: 2 + character: 7 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 16 + line: 2 + character: 7 + end_position: + bytes: 17 + line: 2 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 17 + line: 2 + character: 8 + end_position: + bytes: 18 + line: 2 + character: 9 + token_type: + type: Number + text: "1" +- start_position: + bytes: 18 + line: 2 + character: 9 + end_position: + bytes: 19 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 19 + line: 3 + character: 1 + end_position: + bytes: 23 + line: 3 + character: 5 + token_type: + type: Identifier + identifier: opt2 +- start_position: + bytes: 23 + line: 3 + character: 5 + end_position: + bytes: 24 + line: 3 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 24 + line: 3 + character: 6 + end_position: + bytes: 25 + line: 3 + character: 7 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 25 + line: 3 + character: 7 + end_position: + bytes: 26 + line: 3 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 26 + line: 3 + character: 8 + end_position: + bytes: 30 + line: 3 + character: 12 + token_type: + type: Symbol + symbol: "true" +- start_position: + bytes: 30 + line: 3 + character: 12 + end_position: + bytes: 31 + line: 3 + character: 12 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 31 + line: 4 + character: 1 + end_position: + bytes: 32 + line: 4 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 32 + line: 5 + character: 1 + end_position: + bytes: 33 + line: 5 + character: 2 + token_type: + type: Symbol + symbol: "[" +- start_position: + bytes: 33 + line: 5 + character: 2 + end_position: + bytes: 40 + line: 5 + character: 9 + token_type: + type: Identifier + identifier: module2 +- start_position: + bytes: 40 + line: 5 + character: 9 + end_position: + bytes: 41 + line: 5 + character: 10 + token_type: + type: Symbol + symbol: "]" +- start_position: + bytes: 41 + line: 5 + character: 10 + end_position: + bytes: 42 + line: 5 + character: 10 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 42 + line: 6 + character: 1 + end_position: + bytes: 46 + line: 6 + character: 5 + token_type: + type: Identifier + identifier: opt1 +- start_position: + bytes: 46 + line: 6 + character: 5 + end_position: + bytes: 47 + line: 6 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 47 + line: 6 + character: 6 + end_position: + bytes: 48 + line: 6 + character: 7 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 48 + line: 6 + character: 7 + end_position: + bytes: 49 + line: 6 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 49 + line: 6 + character: 8 + end_position: + bytes: 60 + line: 6 + character: 19 + token_type: + type: StringLiteral + literal: something + quote_type: Double +- start_position: + bytes: 60 + line: 6 + character: 19 + end_position: + bytes: 61 + line: 6 + character: 19 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 61 + line: 7 + character: 1 + end_position: + bytes: 61 + line: 7 + character: 1 + token_type: + type: Eof diff --git a/src/Rust/vvs_parser/src/tests/pass_cases.rs b/src/Rust/vvs_parser/src/tests/pass_cases.rs new file mode 100644 index 0000000000000000000000000000000000000000..115b7d778835e9ed19dfaa256f80922c52fe8e8f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/pass_cases.rs @@ -0,0 +1,87 @@ +use crate::{ + ast::AstResult, + node::Node, + tests::common::run_test_folder, + tokenizer::{self, Token, TokenReference}, +}; +use insta::assert_yaml_snapshot; +use std::{fmt, fs, path::Path}; + +#[derive(PartialEq, Eq)] +struct PrettyString<'a>(pub &'a str); + +// Make diff to display string as multi-line string +impl<'a> fmt::Debug for PrettyString<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(self.0) + } +} + +fn unpack_token_reference(token: &TokenReference) -> Vec<Token> { + token + .leading_trivia() + .chain(std::iter::once(token.token())) + .chain(token.trailing_trivia()) + .cloned() + .collect() +} + +fn test_option_case(path: &Path) { + let source = fs::read_to_string(path.join("source.ini")).expect("couldn't read source.ini"); + let tokens = tokenizer::Lexer::new(&source).collect().unwrap(); + assert_yaml_snapshot!("tokens", tokens); + + let options = crate::ast::OptionTableResult::parse_fallible(&source) + .into_result() + .unwrap_or_else(|error| panic!("couldn't make option table for {path:?} - {error:#?}")); + + assert_yaml_snapshot!("options", options); +} + +fn test_pass_case(path: &Path) { + let source = fs::read_to_string(path.join("source.lua")).expect("couldn't read source.lua"); + let tokens = tokenizer::Lexer::new(&source).collect().unwrap(); + assert_yaml_snapshot!("tokens", tokens); + + let ast = AstResult::parse_fallible(&source) + .into_result() + .unwrap_or_else(|error| panic!("couldn't make ast for {path:?} - {error:#?}")); + + let old_positions: Vec<_> = ast.tokens().flat_map(unpack_token_reference).collect(); + + assert_yaml_snapshot!("ast", ast.nodes()); + assert_eq!(PrettyString(&format!("{ast}")), PrettyString(&source)); + + let ast = ast.update_positions(); + assert_eq!(old_positions, ast.tokens().flat_map(unpack_token_reference).collect::<Vec<_>>(),); +} + +#[test] +fn test_roblox_pass_cases() { + run_test_folder("./src/tests/roblox_cases/pass", test_pass_case); +} + +#[test] +fn test_lua52_pass_cases() { + run_test_folder("./src/tests/lua52_cases/pass", test_pass_case); +} + +#[test] +fn test_lua53_pass_cases() { + run_test_folder("./src/tests/lua53_cases/pass", test_pass_case); +} + +#[test] +fn test_lua54_pass_cases() { + run_test_folder("./src/tests/lua54_cases/pass", test_pass_case); +} + +#[test] +fn test_vivy_pass_cases() { + run_test_folder("./src/tests/vivy_cases/pass", test_pass_case); +} + +#[test] +fn test_option_pass_cases() { + run_test_folder("./src/tests/option_cases/pass", test_option_case); +} diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/function_return_type_thin_arrow/ast.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/function_return_type_thin_arrow/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..9ea7d3465a6dea784fa0fa0be539152db79d3610 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/function_return_type_thin_arrow/ast.snap @@ -0,0 +1,254 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: result.ast() +input_file: vvs_parser/tests/roblox_cases/fail/parser/function_return_type_thin_arrow +--- +nodes: + stmts: + - - FunctionDeclaration: + function_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: function + trailing_trivia: + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " + name: + names: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Identifier + identifier: foo + trailing_trivia: [] + colon_name: ~ + body: + parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " + parameters: + pairs: [] + type_specifiers: [] + return_type: + punctuation: + leading_trivia: [] + token: + start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: "->" + trailing_trivia: + - start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Whitespace + characters: " " + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 24 + line: 1 + character: 25 + token_type: + type: Identifier + identifier: string + trailing_trivia: + - start_position: + bytes: 24 + line: 1 + character: 25 + end_position: + bytes: 25 + line: 1 + character: 25 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: [] + last_stmt: + - Return: + token: + leading_trivia: + - start_position: + bytes: 25 + line: 2 + character: 1 + end_position: + bytes: 26 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 26 + line: 2 + character: 2 + end_position: + bytes: 32 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 32 + line: 2 + character: 8 + end_position: + bytes: 33 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " + returns: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 33 + line: 2 + character: 9 + end_position: + bytes: 35 + line: 2 + character: 11 + token_type: + type: StringLiteral + literal: "" + quote_type: Double + trailing_trivia: + - start_position: + bytes: 35 + line: 2 + character: 11 + end_position: + bytes: 36 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: "\n" + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 36 + line: 3 + character: 1 + end_position: + bytes: 39 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 39 + line: 3 + character: 4 + end_position: + bytes: 39 + line: 3 + character: 4 + token_type: + type: Eof + trailing_trivia: [] diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/function_return_type_thin_arrow/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/function_return_type_thin_arrow/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..0f74fc9b031e6ecdcefd3e969bab714cc9da5873 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/function_return_type_thin_arrow/ast_to_string.snap @@ -0,0 +1,6 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: "vvs_parser::print(&ast)" +--- +"function foo() -> string\n\treturn \"\"\nend" + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/function_return_type_thin_arrow/error_display.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/function_return_type_thin_arrow/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..875e2441b20c1cb682fdd81e1f74e77f9c9bf179 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/function_return_type_thin_arrow/error_display.snap @@ -0,0 +1,11 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: "String::from_utf8(output.into_inner()).unwrap()" +--- +error[ast]: function return type annotations should use `:` instead of `->` + ┌─ source.lua:1:16 + │ +1 │ function foo() -> string + │ ^^ + + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/function_return_type_thin_arrow/errors.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/function_return_type_thin_arrow/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..6e7cbe6551d85ead698dd8ed605774cc91717d55 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/function_return_type_thin_arrow/errors.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +--- +- AstError: + token: + start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: "->" + additional: "function return type annotations should use `:` instead of `->`" + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/function_return_type_thin_arrow/source.lua b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/function_return_type_thin_arrow/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..165392c044d41dad3195b283519c968fa3e7aee9 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/function_return_type_thin_arrow/source.lua @@ -0,0 +1,3 @@ +function foo() -> string + return "" +end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/function_return_type_thin_arrow/tokens.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/function_return_type_thin_arrow/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..8c807bd81e6daaab3a9b8e282794192258f55c08 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/function_return_type_thin_arrow/tokens.snap @@ -0,0 +1,192 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Symbol + symbol: "->" +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 24 + line: 1 + character: 25 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 24 + line: 1 + character: 25 + end_position: + bytes: 25 + line: 1 + character: 25 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 25 + line: 2 + character: 1 + end_position: + bytes: 26 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 26 + line: 2 + character: 2 + end_position: + bytes: 32 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 32 + line: 2 + character: 8 + end_position: + bytes: 33 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 33 + line: 2 + character: 9 + end_position: + bytes: 35 + line: 2 + character: 11 + token_type: + type: StringLiteral + literal: "" + quote_type: Double +- start_position: + bytes: 35 + line: 2 + character: 11 + end_position: + bytes: 36 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 36 + line: 3 + character: 1 + end_position: + bytes: 39 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 39 + line: 3 + character: 4 + end_position: + bytes: 39 + line: 3 + character: 4 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/named_function_arg_types/ast.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/named_function_arg_types/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..cbaa915d36a5bae50288c52541c6837f5f4a9e9c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/named_function_arg_types/ast.snap @@ -0,0 +1,21 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.ast +--- +nodes: + stmts: [] +eof: + leading_trivia: [] + token: + start_position: + bytes: 26 + line: 1 + character: 27 + end_position: + bytes: 26 + line: 1 + character: 27 + token_type: + type: Eof + trailing_trivia: [] + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/named_function_arg_types/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/named_function_arg_types/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..769004af882fd785772914ba92d85b08761bb503 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/named_function_arg_types/ast_to_string.snap @@ -0,0 +1,6 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: "vvs_parser::print(&ast)" +--- +"" + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/named_function_arg_types/error.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/named_function_arg_types/error.snap new file mode 100644 index 0000000000000000000000000000000000000000..764e5601055ae7a2a70a0e8b031d2e569c8103eb --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/named_function_arg_types/error.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: error + +--- +UnexpectedToken: + token: + start_position: + bytes: 26 + line: 1 + character: 27 + end_position: + bytes: 26 + line: 1 + character: 27 + token_type: + type: Eof + additional: "expected `->` after `()` when parsing function type" + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/named_function_arg_types/error_display.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/named_function_arg_types/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..9179dfeb41f017cad1d7fd851d7c885311eee38d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/named_function_arg_types/error_display.snap @@ -0,0 +1,11 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: "String::from_utf8(output.into_inner()).unwrap()" +--- +error[ast]: expected `->` after `()` for function type + ┌─ source.lua:1:27 + │ +1 │ type Foo = (count: number) + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/named_function_arg_types/errors.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/named_function_arg_types/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..ff46da5cc3f95a92de2e5b096996fa4a2adf07f8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/named_function_arg_types/errors.snap @@ -0,0 +1,18 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +--- +- AstError: + token: + start_position: + bytes: 26 + line: 1 + character: 27 + end_position: + bytes: 26 + line: 1 + character: 27 + token_type: + type: Eof + additional: "expected `->` after `()` for function type" + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/named_function_arg_types/source.lua b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/named_function_arg_types/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..648860cc1ecbed21da44126f21c3a5e66e2ecd91 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/named_function_arg_types/source.lua @@ -0,0 +1 @@ +type Foo = (count: number) \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/named_function_arg_types/tokens.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/named_function_arg_types/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..7e27690a24f36d842d9115a862884d99e3e65f82 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/named_function_arg_types/tokens.snap @@ -0,0 +1,148 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: type +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Identifier + identifier: Foo +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Identifier + identifier: count +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Identifier + identifier: number +- start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 26 + line: 1 + character: 27 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 26 + line: 1 + character: 27 + end_position: + bytes: 26 + line: 1 + character: 27 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/nil_dot/ast.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/nil_dot/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..776ede7ba0fb039b89e46cef53c55bac16b8003b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/nil_dot/ast.snap @@ -0,0 +1,117 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: result.ast() +input_file: vvs_parser/tests/roblox_cases/fail/parser/nil_dot +--- +nodes: + stmts: + - - TypeDeclaration: + type_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: type + trailing_trivia: + - start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " + base: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Identifier + identifier: Foo + trailing_trivia: + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " + declare_as: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: nil + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 27 + line: 2 + character: 1 + end_position: + bytes: 27 + line: 2 + character: 1 + token_type: + type: Eof + trailing_trivia: [] diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/nil_dot/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/nil_dot/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..0123dfe53490a5ccca7211ae1893bb76324b8204 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/nil_dot/ast_to_string.snap @@ -0,0 +1,6 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: "vvs_parser::print(&ast)" +--- +type Foo = nil + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/nil_dot/error.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/nil_dot/error.snap new file mode 100644 index 0000000000000000000000000000000000000000..70ed0b8bf29f058d928e52087b2c4e237a56cdd6 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/nil_dot/error.snap @@ -0,0 +1,22 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 58 +expression: error +input_file: full-moon/tests/roblox_cases/fail/parser/nil_dot + +--- +UnexpectedToken: + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: "." + additional: leftover token + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/nil_dot/error_display.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/nil_dot/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..0e6b920e76627d4f3f2f3a2a6ee9b49c8df7c562 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/nil_dot/error_display.snap @@ -0,0 +1,35 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: "String::from_utf8(output.into_inner()).unwrap()" +--- +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:15 + │ +1 │ type Foo = nil.bar<string> + │ ^ + +error[ast]: unexpected expression when looking for a statement + ┌─ source.lua:1:19 + │ +1 │ type Foo = nil.bar<string> + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:19 + │ +1 │ type Foo = nil.bar<string> + │ ^ + +error[ast]: unexpected expression when looking for a statement + ┌─ source.lua:1:26 + │ +1 │ type Foo = nil.bar<string> + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:26 + │ +1 │ type Foo = nil.bar<string> + │ ^ + + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/nil_dot/errors.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/nil_dot/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..47554f289157b32ea93b096b6bb04d4de4afb46f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/nil_dot/errors.snap @@ -0,0 +1,75 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +--- +- AstError: + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: "." + additional: "unexpected token, this needs to be a statement" +- AstError: + token: + start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: "<" + additional: unexpected expression when looking for a statement +- AstError: + token: + start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: "<" + additional: "unexpected token, this needs to be a statement" +- AstError: + token: + start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 26 + line: 1 + character: 27 + token_type: + type: Symbol + symbol: ">" + additional: unexpected expression when looking for a statement +- AstError: + token: + start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 26 + line: 1 + character: 27 + token_type: + type: Symbol + symbol: ">" + additional: "unexpected token, this needs to be a statement" + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/nil_dot/source.lua b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/nil_dot/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..488795aba9f5b46368cf5a0196acfd48548a1668 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/nil_dot/source.lua @@ -0,0 +1 @@ +type Foo = nil.bar<string> diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/nil_dot/tokens.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/nil_dot/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..dd8c8779e89a48066a5fcb4ffb9aa2498f55cd84 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/nil_dot/tokens.snap @@ -0,0 +1,161 @@ +--- +source: full-moon/tests/fail_cases.rs +assertion_line: 52 +expression: tokens +input_file: full-moon/tests/roblox_cases/fail/parser/nil_dot + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: type +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Identifier + identifier: Foo +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: nil +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Identifier + identifier: bar +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: "<" +- start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 26 + line: 1 + character: 27 + token_type: + type: Symbol + symbol: ">" +- start_position: + bytes: 26 + line: 1 + character: 27 + end_position: + bytes: 27 + line: 1 + character: 27 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 27 + line: 2 + character: 1 + end_position: + bytes: 27 + line: 2 + character: 1 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/type_table_no_right_brace/ast.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/type_table_no_right_brace/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..ee6423cdd0b2ad7c0332328072f8843cf7586a69 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/type_table_no_right_brace/ast.snap @@ -0,0 +1,411 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: result.ast() +input_file: vvs_parser/tests/roblox_cases/fail/parser/type_table_no_right_brace +--- +nodes: + stmts: + - - TypeDeclaration: + type_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: type + trailing_trivia: + - start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " + base: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Identifier + identifier: Foo + trailing_trivia: + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " + declare_as: + Table: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Whitespace + characters: " " + - leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 1 + line: 1 + character: 2 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: [] + fields: + pairs: + - Punctuated: + - key: + Name: + leading_trivia: [] + token: + start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Identifier + identifier: x + trailing_trivia: [] + colon: + leading_trivia: [] + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Whitespace + characters: " " + value: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Identifier + identifier: string + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 22 + line: 1 + character: 23 + end_position: + bytes: 23 + line: 1 + character: 24 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 23 + line: 1 + character: 24 + end_position: + bytes: 24 + line: 1 + character: 25 + token_type: + type: Whitespace + characters: " " + - End: + key: + Name: + leading_trivia: [] + token: + start_position: + bytes: 24 + line: 1 + character: 25 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Identifier + identifier: y + trailing_trivia: [] + colon: + leading_trivia: [] + token: + start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 26 + line: 1 + character: 27 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 26 + line: 1 + character: 27 + end_position: + bytes: 27 + line: 1 + character: 28 + token_type: + type: Whitespace + characters: " " + value: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 27 + line: 1 + character: 28 + end_position: + bytes: 33 + line: 1 + character: 34 + token_type: + type: Identifier + identifier: string + trailing_trivia: + - start_position: + bytes: 33 + line: 1 + character: 34 + end_position: + bytes: 34 + line: 1 + character: 34 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: + - start_position: + bytes: 34 + line: 2 + character: 1 + end_position: + bytes: 35 + line: 2 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 35 + line: 3 + character: 1 + end_position: + bytes: 40 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 40 + line: 3 + character: 6 + end_position: + bytes: 41 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 41 + line: 3 + character: 7 + end_position: + bytes: 42 + line: 3 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 42 + line: 3 + character: 8 + end_position: + bytes: 43 + line: 3 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 43 + line: 3 + character: 9 + end_position: + bytes: 44 + line: 3 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 44 + line: 3 + character: 10 + end_position: + bytes: 45 + line: 3 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 45 + line: 3 + character: 11 + end_position: + bytes: 46 + line: 3 + character: 12 + token_type: + type: Number + text: "1" + trailing_trivia: [] + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 46 + line: 3 + character: 12 + end_position: + bytes: 46 + line: 3 + character: 12 + token_type: + type: Eof + trailing_trivia: [] diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/type_table_no_right_brace/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/type_table_no_right_brace/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..f7244cced31e99ede3d02195256ed773aaa78a67 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/type_table_no_right_brace/ast_to_string.snap @@ -0,0 +1,6 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: "vvs_parser::print(&ast)" +--- +"type Foo = { x: string, y: string\n}\nlocal x = 1" + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/type_table_no_right_brace/error_display.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/type_table_no_right_brace/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..dc218d2c0c17516f12356b0b9751d178c3111a40 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/type_table_no_right_brace/error_display.snap @@ -0,0 +1,11 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: "String::from_utf8(output.into_inner()).unwrap()" +--- +error[ast]: expected `}` to close type table + ┌─ source.lua:3:1 + │ +3 │ local x = 1 + │ ^^^^^ + + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/type_table_no_right_brace/errors.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/type_table_no_right_brace/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..91e6c7c666d3b48101d58f6bd14d11b4850edd0c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/type_table_no_right_brace/errors.snap @@ -0,0 +1,19 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: result.errors +--- +- AstError: + token: + start_position: + bytes: 35 + line: 3 + character: 1 + end_position: + bytes: 40 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: local + additional: "expected `}` to close type table" + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/type_table_no_right_brace/source.lua b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/type_table_no_right_brace/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..c882c3351fa17a1c9f55d82c40d1074d319c0a29 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/type_table_no_right_brace/source.lua @@ -0,0 +1,3 @@ +type Foo = { x: string, y: string + +local x = 1 \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/type_table_no_right_brace/tokens.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/type_table_no_right_brace/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..fc10df6d0f60641a799af346757587613657989b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/fail/parser/type_table_no_right_brace/tokens.snap @@ -0,0 +1,312 @@ +--- +source: full-moon/tests/fail_cases.rs +expression: tokens +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: type +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Identifier + identifier: Foo +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 22 + line: 1 + character: 23 + end_position: + bytes: 23 + line: 1 + character: 24 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 23 + line: 1 + character: 24 + end_position: + bytes: 24 + line: 1 + character: 25 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 24 + line: 1 + character: 25 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 26 + line: 1 + character: 27 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 26 + line: 1 + character: 27 + end_position: + bytes: 27 + line: 1 + character: 28 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 27 + line: 1 + character: 28 + end_position: + bytes: 33 + line: 1 + character: 34 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 33 + line: 1 + character: 34 + end_position: + bytes: 34 + line: 1 + character: 34 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 34 + line: 2 + character: 1 + end_position: + bytes: 35 + line: 2 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 35 + line: 3 + character: 1 + end_position: + bytes: 40 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 40 + line: 3 + character: 6 + end_position: + bytes: 41 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 41 + line: 3 + character: 7 + end_position: + bytes: 42 + line: 3 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 42 + line: 3 + character: 8 + end_position: + bytes: 43 + line: 3 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 43 + line: 3 + character: 9 + end_position: + bytes: 44 + line: 3 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 44 + line: 3 + character: 10 + end_position: + bytes: 45 + line: 3 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 45 + line: 3 + character: 11 + end_position: + bytes: 46 + line: 3 + character: 12 + token_type: + type: Number + text: "1" +- start_position: + bytes: 46 + line: 3 + character: 12 + end_position: + bytes: 46 + line: 3 + character: 12 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/compound_assignment/ast.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/compound_assignment/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..23ff308a56f9b7e27530ebd2f506f961fe5f00b1 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/compound_assignment/ast.snap @@ -0,0 +1,1824 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/roblox_cases/pass/compound_assignment +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 2 + character: 1 + end_position: + bytes: 17 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 17 + line: 2 + character: 6 + end_position: + bytes: 18 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 18 + line: 2 + character: 7 + end_position: + bytes: 19 + line: 2 + character: 8 + token_type: + type: Identifier + identifier: y + trailing_trivia: + - start_position: + bytes: 19 + line: 2 + character: 8 + end_position: + bytes: 20 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 20 + line: 2 + character: 9 + end_position: + bytes: 21 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 21 + line: 2 + character: 10 + end_position: + bytes: 22 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 22 + line: 2 + character: 11 + end_position: + bytes: 23 + line: 2 + character: 12 + token_type: + type: Number + text: "2" + trailing_trivia: + - start_position: + bytes: 23 + line: 2 + character: 12 + end_position: + bytes: 24 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - CompoundAssignment: + lhs: + Name: + leading_trivia: + - start_position: + bytes: 24 + line: 3 + character: 1 + end_position: + bytes: 25 + line: 3 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 25 + line: 4 + character: 1 + end_position: + bytes: 26 + line: 4 + character: 2 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 26 + line: 4 + character: 2 + end_position: + bytes: 27 + line: 4 + character: 3 + token_type: + type: Whitespace + characters: " " + compound_operator: + PlusEqual: + leading_trivia: [] + token: + start_position: + bytes: 27 + line: 4 + character: 3 + end_position: + bytes: 29 + line: 4 + character: 5 + token_type: + type: Symbol + symbol: += + trailing_trivia: + - start_position: + bytes: 29 + line: 4 + character: 5 + end_position: + bytes: 30 + line: 4 + character: 6 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 30 + line: 4 + character: 6 + end_position: + bytes: 31 + line: 4 + character: 7 + token_type: + type: Number + text: "5" + trailing_trivia: + - start_position: + bytes: 31 + line: 4 + character: 7 + end_position: + bytes: 32 + line: 4 + character: 7 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - CompoundAssignment: + lhs: + Name: + leading_trivia: [] + token: + start_position: + bytes: 32 + line: 5 + character: 1 + end_position: + bytes: 33 + line: 5 + character: 2 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 33 + line: 5 + character: 2 + end_position: + bytes: 34 + line: 5 + character: 3 + token_type: + type: Whitespace + characters: " " + compound_operator: + MinusEqual: + leading_trivia: [] + token: + start_position: + bytes: 34 + line: 5 + character: 3 + end_position: + bytes: 36 + line: 5 + character: 5 + token_type: + type: Symbol + symbol: "-=" + trailing_trivia: + - start_position: + bytes: 36 + line: 5 + character: 5 + end_position: + bytes: 37 + line: 5 + character: 6 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 37 + line: 5 + character: 6 + end_position: + bytes: 38 + line: 5 + character: 7 + token_type: + type: Number + text: "5" + trailing_trivia: + - start_position: + bytes: 38 + line: 5 + character: 7 + end_position: + bytes: 39 + line: 5 + character: 7 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - CompoundAssignment: + lhs: + Name: + leading_trivia: [] + token: + start_position: + bytes: 39 + line: 6 + character: 1 + end_position: + bytes: 40 + line: 6 + character: 2 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 40 + line: 6 + character: 2 + end_position: + bytes: 41 + line: 6 + character: 3 + token_type: + type: Whitespace + characters: " " + compound_operator: + StarEqual: + leading_trivia: [] + token: + start_position: + bytes: 41 + line: 6 + character: 3 + end_position: + bytes: 43 + line: 6 + character: 5 + token_type: + type: Symbol + symbol: "*=" + trailing_trivia: + - start_position: + bytes: 43 + line: 6 + character: 5 + end_position: + bytes: 44 + line: 6 + character: 6 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 44 + line: 6 + character: 6 + end_position: + bytes: 45 + line: 6 + character: 7 + token_type: + type: Number + text: "5" + trailing_trivia: + - start_position: + bytes: 45 + line: 6 + character: 7 + end_position: + bytes: 46 + line: 6 + character: 7 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - CompoundAssignment: + lhs: + Name: + leading_trivia: [] + token: + start_position: + bytes: 46 + line: 7 + character: 1 + end_position: + bytes: 47 + line: 7 + character: 2 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 47 + line: 7 + character: 2 + end_position: + bytes: 48 + line: 7 + character: 3 + token_type: + type: Whitespace + characters: " " + compound_operator: + SlashEqual: + leading_trivia: [] + token: + start_position: + bytes: 48 + line: 7 + character: 3 + end_position: + bytes: 50 + line: 7 + character: 5 + token_type: + type: Symbol + symbol: /= + trailing_trivia: + - start_position: + bytes: 50 + line: 7 + character: 5 + end_position: + bytes: 51 + line: 7 + character: 6 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 51 + line: 7 + character: 6 + end_position: + bytes: 52 + line: 7 + character: 7 + token_type: + type: Number + text: "5" + trailing_trivia: + - start_position: + bytes: 52 + line: 7 + character: 7 + end_position: + bytes: 53 + line: 7 + character: 7 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - CompoundAssignment: + lhs: + Name: + leading_trivia: [] + token: + start_position: + bytes: 53 + line: 8 + character: 1 + end_position: + bytes: 54 + line: 8 + character: 2 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 54 + line: 8 + character: 2 + end_position: + bytes: 55 + line: 8 + character: 3 + token_type: + type: Whitespace + characters: " " + compound_operator: + DoubleSlashEqual: + leading_trivia: [] + token: + start_position: + bytes: 55 + line: 8 + character: 3 + end_position: + bytes: 58 + line: 8 + character: 6 + token_type: + type: Symbol + symbol: //= + trailing_trivia: + - start_position: + bytes: 58 + line: 8 + character: 6 + end_position: + bytes: 59 + line: 8 + character: 7 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 59 + line: 8 + character: 7 + end_position: + bytes: 60 + line: 8 + character: 8 + token_type: + type: Number + text: "5" + trailing_trivia: + - start_position: + bytes: 60 + line: 8 + character: 8 + end_position: + bytes: 61 + line: 8 + character: 8 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - CompoundAssignment: + lhs: + Name: + leading_trivia: [] + token: + start_position: + bytes: 61 + line: 9 + character: 1 + end_position: + bytes: 62 + line: 9 + character: 2 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 62 + line: 9 + character: 2 + end_position: + bytes: 63 + line: 9 + character: 3 + token_type: + type: Whitespace + characters: " " + compound_operator: + PercentEqual: + leading_trivia: [] + token: + start_position: + bytes: 63 + line: 9 + character: 3 + end_position: + bytes: 65 + line: 9 + character: 5 + token_type: + type: Symbol + symbol: "%=" + trailing_trivia: + - start_position: + bytes: 65 + line: 9 + character: 5 + end_position: + bytes: 66 + line: 9 + character: 6 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 66 + line: 9 + character: 6 + end_position: + bytes: 67 + line: 9 + character: 7 + token_type: + type: Number + text: "5" + trailing_trivia: + - start_position: + bytes: 67 + line: 9 + character: 7 + end_position: + bytes: 68 + line: 9 + character: 7 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - CompoundAssignment: + lhs: + Name: + leading_trivia: [] + token: + start_position: + bytes: 68 + line: 10 + character: 1 + end_position: + bytes: 69 + line: 10 + character: 2 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 69 + line: 10 + character: 2 + end_position: + bytes: 70 + line: 10 + character: 3 + token_type: + type: Whitespace + characters: " " + compound_operator: + CaretEqual: + leading_trivia: [] + token: + start_position: + bytes: 70 + line: 10 + character: 3 + end_position: + bytes: 72 + line: 10 + character: 5 + token_type: + type: Symbol + symbol: ^= + trailing_trivia: + - start_position: + bytes: 72 + line: 10 + character: 5 + end_position: + bytes: 73 + line: 10 + character: 6 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 73 + line: 10 + character: 6 + end_position: + bytes: 74 + line: 10 + character: 7 + token_type: + type: Number + text: "5" + trailing_trivia: + - start_position: + bytes: 74 + line: 10 + character: 7 + end_position: + bytes: 75 + line: 10 + character: 7 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - CompoundAssignment: + lhs: + Name: + leading_trivia: + - start_position: + bytes: 75 + line: 11 + character: 1 + end_position: + bytes: 76 + line: 11 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 76 + line: 12 + character: 1 + end_position: + bytes: 77 + line: 12 + character: 2 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 77 + line: 12 + character: 2 + end_position: + bytes: 78 + line: 12 + character: 3 + token_type: + type: Whitespace + characters: " " + compound_operator: + PlusEqual: + leading_trivia: [] + token: + start_position: + bytes: 78 + line: 12 + character: 3 + end_position: + bytes: 80 + line: 12 + character: 5 + token_type: + type: Symbol + symbol: += + trailing_trivia: + - start_position: + bytes: 80 + line: 12 + character: 5 + end_position: + bytes: 81 + line: 12 + character: 6 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 81 + line: 12 + character: 6 + end_position: + bytes: 82 + line: 12 + character: 7 + token_type: + type: Identifier + identifier: y + trailing_trivia: + - start_position: + bytes: 82 + line: 12 + character: 7 + end_position: + bytes: 83 + line: 12 + character: 7 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - CompoundAssignment: + lhs: + Name: + leading_trivia: [] + token: + start_position: + bytes: 83 + line: 13 + character: 1 + end_position: + bytes: 84 + line: 13 + character: 2 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 84 + line: 13 + character: 2 + end_position: + bytes: 85 + line: 13 + character: 3 + token_type: + type: Whitespace + characters: " " + compound_operator: + MinusEqual: + leading_trivia: [] + token: + start_position: + bytes: 85 + line: 13 + character: 3 + end_position: + bytes: 87 + line: 13 + character: 5 + token_type: + type: Symbol + symbol: "-=" + trailing_trivia: + - start_position: + bytes: 87 + line: 13 + character: 5 + end_position: + bytes: 88 + line: 13 + character: 6 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 88 + line: 13 + character: 6 + end_position: + bytes: 89 + line: 13 + character: 7 + token_type: + type: Identifier + identifier: y + trailing_trivia: + - start_position: + bytes: 89 + line: 13 + character: 7 + end_position: + bytes: 90 + line: 13 + character: 7 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - CompoundAssignment: + lhs: + Name: + leading_trivia: [] + token: + start_position: + bytes: 90 + line: 14 + character: 1 + end_position: + bytes: 91 + line: 14 + character: 2 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 91 + line: 14 + character: 2 + end_position: + bytes: 92 + line: 14 + character: 3 + token_type: + type: Whitespace + characters: " " + compound_operator: + StarEqual: + leading_trivia: [] + token: + start_position: + bytes: 92 + line: 14 + character: 3 + end_position: + bytes: 94 + line: 14 + character: 5 + token_type: + type: Symbol + symbol: "*=" + trailing_trivia: + - start_position: + bytes: 94 + line: 14 + character: 5 + end_position: + bytes: 95 + line: 14 + character: 6 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 95 + line: 14 + character: 6 + end_position: + bytes: 96 + line: 14 + character: 7 + token_type: + type: Identifier + identifier: y + trailing_trivia: + - start_position: + bytes: 96 + line: 14 + character: 7 + end_position: + bytes: 97 + line: 14 + character: 7 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - CompoundAssignment: + lhs: + Name: + leading_trivia: [] + token: + start_position: + bytes: 97 + line: 15 + character: 1 + end_position: + bytes: 98 + line: 15 + character: 2 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 98 + line: 15 + character: 2 + end_position: + bytes: 99 + line: 15 + character: 3 + token_type: + type: Whitespace + characters: " " + compound_operator: + SlashEqual: + leading_trivia: [] + token: + start_position: + bytes: 99 + line: 15 + character: 3 + end_position: + bytes: 101 + line: 15 + character: 5 + token_type: + type: Symbol + symbol: /= + trailing_trivia: + - start_position: + bytes: 101 + line: 15 + character: 5 + end_position: + bytes: 102 + line: 15 + character: 6 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 102 + line: 15 + character: 6 + end_position: + bytes: 103 + line: 15 + character: 7 + token_type: + type: Identifier + identifier: y + trailing_trivia: + - start_position: + bytes: 103 + line: 15 + character: 7 + end_position: + bytes: 104 + line: 15 + character: 7 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - CompoundAssignment: + lhs: + Name: + leading_trivia: [] + token: + start_position: + bytes: 104 + line: 16 + character: 1 + end_position: + bytes: 105 + line: 16 + character: 2 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 105 + line: 16 + character: 2 + end_position: + bytes: 106 + line: 16 + character: 3 + token_type: + type: Whitespace + characters: " " + compound_operator: + DoubleSlashEqual: + leading_trivia: [] + token: + start_position: + bytes: 106 + line: 16 + character: 3 + end_position: + bytes: 109 + line: 16 + character: 6 + token_type: + type: Symbol + symbol: //= + trailing_trivia: + - start_position: + bytes: 109 + line: 16 + character: 6 + end_position: + bytes: 110 + line: 16 + character: 7 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 110 + line: 16 + character: 7 + end_position: + bytes: 111 + line: 16 + character: 8 + token_type: + type: Identifier + identifier: y + trailing_trivia: + - start_position: + bytes: 111 + line: 16 + character: 8 + end_position: + bytes: 112 + line: 16 + character: 8 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - CompoundAssignment: + lhs: + Name: + leading_trivia: [] + token: + start_position: + bytes: 112 + line: 17 + character: 1 + end_position: + bytes: 113 + line: 17 + character: 2 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 113 + line: 17 + character: 2 + end_position: + bytes: 114 + line: 17 + character: 3 + token_type: + type: Whitespace + characters: " " + compound_operator: + PercentEqual: + leading_trivia: [] + token: + start_position: + bytes: 114 + line: 17 + character: 3 + end_position: + bytes: 116 + line: 17 + character: 5 + token_type: + type: Symbol + symbol: "%=" + trailing_trivia: + - start_position: + bytes: 116 + line: 17 + character: 5 + end_position: + bytes: 117 + line: 17 + character: 6 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 117 + line: 17 + character: 6 + end_position: + bytes: 118 + line: 17 + character: 7 + token_type: + type: Identifier + identifier: y + trailing_trivia: + - start_position: + bytes: 118 + line: 17 + character: 7 + end_position: + bytes: 119 + line: 17 + character: 7 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - CompoundAssignment: + lhs: + Name: + leading_trivia: [] + token: + start_position: + bytes: 119 + line: 18 + character: 1 + end_position: + bytes: 120 + line: 18 + character: 2 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 120 + line: 18 + character: 2 + end_position: + bytes: 121 + line: 18 + character: 3 + token_type: + type: Whitespace + characters: " " + compound_operator: + CaretEqual: + leading_trivia: [] + token: + start_position: + bytes: 121 + line: 18 + character: 3 + end_position: + bytes: 123 + line: 18 + character: 5 + token_type: + type: Symbol + symbol: ^= + trailing_trivia: + - start_position: + bytes: 123 + line: 18 + character: 5 + end_position: + bytes: 124 + line: 18 + character: 6 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 124 + line: 18 + character: 6 + end_position: + bytes: 125 + line: 18 + character: 7 + token_type: + type: Identifier + identifier: y + trailing_trivia: + - start_position: + bytes: 125 + line: 18 + character: 7 + end_position: + bytes: 126 + line: 18 + character: 7 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: + - start_position: + bytes: 126 + line: 19 + character: 1 + end_position: + bytes: 127 + line: 19 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 127 + line: 20 + character: 1 + end_position: + bytes: 132 + line: 20 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 132 + line: 20 + character: 6 + end_position: + bytes: 133 + line: 20 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 133 + line: 20 + character: 7 + end_position: + bytes: 137 + line: 20 + character: 11 + token_type: + type: Identifier + identifier: str1 + trailing_trivia: + - start_position: + bytes: 137 + line: 20 + character: 11 + end_position: + bytes: 138 + line: 20 + character: 12 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 138 + line: 20 + character: 12 + end_position: + bytes: 139 + line: 20 + character: 13 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 139 + line: 20 + character: 13 + end_position: + bytes: 140 + line: 20 + character: 14 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 140 + line: 20 + character: 14 + end_position: + bytes: 149 + line: 20 + character: 23 + token_type: + type: StringLiteral + literal: "Hello, " + quote_type: Double + trailing_trivia: + - start_position: + bytes: 149 + line: 20 + character: 23 + end_position: + bytes: 150 + line: 20 + character: 23 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 150 + line: 21 + character: 1 + end_position: + bytes: 155 + line: 21 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 155 + line: 21 + character: 6 + end_position: + bytes: 156 + line: 21 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 156 + line: 21 + character: 7 + end_position: + bytes: 160 + line: 21 + character: 11 + token_type: + type: Identifier + identifier: str2 + trailing_trivia: + - start_position: + bytes: 160 + line: 21 + character: 11 + end_position: + bytes: 161 + line: 21 + character: 12 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 161 + line: 21 + character: 12 + end_position: + bytes: 162 + line: 21 + character: 13 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 162 + line: 21 + character: 13 + end_position: + bytes: 163 + line: 21 + character: 14 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 163 + line: 21 + character: 14 + end_position: + bytes: 171 + line: 21 + character: 22 + token_type: + type: StringLiteral + literal: world! + quote_type: Double + trailing_trivia: + - start_position: + bytes: 171 + line: 21 + character: 22 + end_position: + bytes: 172 + line: 21 + character: 22 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - CompoundAssignment: + lhs: + Name: + leading_trivia: + - start_position: + bytes: 172 + line: 22 + character: 1 + end_position: + bytes: 173 + line: 22 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 173 + line: 23 + character: 1 + end_position: + bytes: 177 + line: 23 + character: 5 + token_type: + type: Identifier + identifier: str1 + trailing_trivia: + - start_position: + bytes: 177 + line: 23 + character: 5 + end_position: + bytes: 178 + line: 23 + character: 6 + token_type: + type: Whitespace + characters: " " + compound_operator: + TwoDotsEqual: + leading_trivia: [] + token: + start_position: + bytes: 178 + line: 23 + character: 6 + end_position: + bytes: 181 + line: 23 + character: 9 + token_type: + type: Symbol + symbol: "..=" + trailing_trivia: + - start_position: + bytes: 181 + line: 23 + character: 9 + end_position: + bytes: 182 + line: 23 + character: 10 + token_type: + type: Whitespace + characters: " " + rhs: + String: + leading_trivia: [] + token: + start_position: + bytes: 182 + line: 23 + character: 10 + end_position: + bytes: 190 + line: 23 + character: 18 + token_type: + type: StringLiteral + literal: world! + quote_type: Double + trailing_trivia: + - start_position: + bytes: 190 + line: 23 + character: 18 + end_position: + bytes: 191 + line: 23 + character: 18 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - CompoundAssignment: + lhs: + Name: + leading_trivia: [] + token: + start_position: + bytes: 191 + line: 24 + character: 1 + end_position: + bytes: 195 + line: 24 + character: 5 + token_type: + type: Identifier + identifier: str1 + trailing_trivia: + - start_position: + bytes: 195 + line: 24 + character: 5 + end_position: + bytes: 196 + line: 24 + character: 6 + token_type: + type: Whitespace + characters: " " + compound_operator: + TwoDotsEqual: + leading_trivia: [] + token: + start_position: + bytes: 196 + line: 24 + character: 6 + end_position: + bytes: 199 + line: 24 + character: 9 + token_type: + type: Symbol + symbol: "..=" + trailing_trivia: + - start_position: + bytes: 199 + line: 24 + character: 9 + end_position: + bytes: 200 + line: 24 + character: 10 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 200 + line: 24 + character: 10 + end_position: + bytes: 204 + line: 24 + character: 14 + token_type: + type: Identifier + identifier: str2 + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/compound_assignment/source.lua b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/compound_assignment/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..ed2ab3c8d24e0fd875d69e073e770e53ce558643 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/compound_assignment/source.lua @@ -0,0 +1,24 @@ +local x = 1 +local y = 2 + +x += 5 +x -= 5 +x *= 5 +x /= 5 +x //= 5 +x %= 5 +x ^= 5 + +x += y +x -= y +x *= y +x /= y +x //= y +x %= y +x ^= y + +local str1 = "Hello, " +local str2 = "world!" + +str1 ..= "world!" +str1 ..= str2 \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/compound_assignment/tokens.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/compound_assignment/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..f60aed94eb2f14fccde97356f049c4ebe1ec82c5 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/compound_assignment/tokens.snap @@ -0,0 +1,1461 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 38 +expression: tokens +input_file: full-moon/tests/roblox_cases/pass/compound_assignment +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Number + text: "1" +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 12 + line: 2 + character: 1 + end_position: + bytes: 17 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 17 + line: 2 + character: 6 + end_position: + bytes: 18 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 18 + line: 2 + character: 7 + end_position: + bytes: 19 + line: 2 + character: 8 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 19 + line: 2 + character: 8 + end_position: + bytes: 20 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 20 + line: 2 + character: 9 + end_position: + bytes: 21 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 21 + line: 2 + character: 10 + end_position: + bytes: 22 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 22 + line: 2 + character: 11 + end_position: + bytes: 23 + line: 2 + character: 12 + token_type: + type: Number + text: "2" +- start_position: + bytes: 23 + line: 2 + character: 12 + end_position: + bytes: 24 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 24 + line: 3 + character: 1 + end_position: + bytes: 25 + line: 3 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 25 + line: 4 + character: 1 + end_position: + bytes: 26 + line: 4 + character: 2 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 26 + line: 4 + character: 2 + end_position: + bytes: 27 + line: 4 + character: 3 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 27 + line: 4 + character: 3 + end_position: + bytes: 29 + line: 4 + character: 5 + token_type: + type: Symbol + symbol: += +- start_position: + bytes: 29 + line: 4 + character: 5 + end_position: + bytes: 30 + line: 4 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 30 + line: 4 + character: 6 + end_position: + bytes: 31 + line: 4 + character: 7 + token_type: + type: Number + text: "5" +- start_position: + bytes: 31 + line: 4 + character: 7 + end_position: + bytes: 32 + line: 4 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 32 + line: 5 + character: 1 + end_position: + bytes: 33 + line: 5 + character: 2 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 33 + line: 5 + character: 2 + end_position: + bytes: 34 + line: 5 + character: 3 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 34 + line: 5 + character: 3 + end_position: + bytes: 36 + line: 5 + character: 5 + token_type: + type: Symbol + symbol: "-=" +- start_position: + bytes: 36 + line: 5 + character: 5 + end_position: + bytes: 37 + line: 5 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 37 + line: 5 + character: 6 + end_position: + bytes: 38 + line: 5 + character: 7 + token_type: + type: Number + text: "5" +- start_position: + bytes: 38 + line: 5 + character: 7 + end_position: + bytes: 39 + line: 5 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 39 + line: 6 + character: 1 + end_position: + bytes: 40 + line: 6 + character: 2 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 40 + line: 6 + character: 2 + end_position: + bytes: 41 + line: 6 + character: 3 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 41 + line: 6 + character: 3 + end_position: + bytes: 43 + line: 6 + character: 5 + token_type: + type: Symbol + symbol: "*=" +- start_position: + bytes: 43 + line: 6 + character: 5 + end_position: + bytes: 44 + line: 6 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 44 + line: 6 + character: 6 + end_position: + bytes: 45 + line: 6 + character: 7 + token_type: + type: Number + text: "5" +- start_position: + bytes: 45 + line: 6 + character: 7 + end_position: + bytes: 46 + line: 6 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 46 + line: 7 + character: 1 + end_position: + bytes: 47 + line: 7 + character: 2 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 47 + line: 7 + character: 2 + end_position: + bytes: 48 + line: 7 + character: 3 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 48 + line: 7 + character: 3 + end_position: + bytes: 50 + line: 7 + character: 5 + token_type: + type: Symbol + symbol: /= +- start_position: + bytes: 50 + line: 7 + character: 5 + end_position: + bytes: 51 + line: 7 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 51 + line: 7 + character: 6 + end_position: + bytes: 52 + line: 7 + character: 7 + token_type: + type: Number + text: "5" +- start_position: + bytes: 52 + line: 7 + character: 7 + end_position: + bytes: 53 + line: 7 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 53 + line: 8 + character: 1 + end_position: + bytes: 54 + line: 8 + character: 2 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 54 + line: 8 + character: 2 + end_position: + bytes: 55 + line: 8 + character: 3 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 55 + line: 8 + character: 3 + end_position: + bytes: 58 + line: 8 + character: 6 + token_type: + type: Symbol + symbol: //= +- start_position: + bytes: 58 + line: 8 + character: 6 + end_position: + bytes: 59 + line: 8 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 59 + line: 8 + character: 7 + end_position: + bytes: 60 + line: 8 + character: 8 + token_type: + type: Number + text: "5" +- start_position: + bytes: 60 + line: 8 + character: 8 + end_position: + bytes: 61 + line: 8 + character: 8 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 61 + line: 9 + character: 1 + end_position: + bytes: 62 + line: 9 + character: 2 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 62 + line: 9 + character: 2 + end_position: + bytes: 63 + line: 9 + character: 3 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 63 + line: 9 + character: 3 + end_position: + bytes: 65 + line: 9 + character: 5 + token_type: + type: Symbol + symbol: "%=" +- start_position: + bytes: 65 + line: 9 + character: 5 + end_position: + bytes: 66 + line: 9 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 66 + line: 9 + character: 6 + end_position: + bytes: 67 + line: 9 + character: 7 + token_type: + type: Number + text: "5" +- start_position: + bytes: 67 + line: 9 + character: 7 + end_position: + bytes: 68 + line: 9 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 68 + line: 10 + character: 1 + end_position: + bytes: 69 + line: 10 + character: 2 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 69 + line: 10 + character: 2 + end_position: + bytes: 70 + line: 10 + character: 3 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 70 + line: 10 + character: 3 + end_position: + bytes: 72 + line: 10 + character: 5 + token_type: + type: Symbol + symbol: ^= +- start_position: + bytes: 72 + line: 10 + character: 5 + end_position: + bytes: 73 + line: 10 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 73 + line: 10 + character: 6 + end_position: + bytes: 74 + line: 10 + character: 7 + token_type: + type: Number + text: "5" +- start_position: + bytes: 74 + line: 10 + character: 7 + end_position: + bytes: 75 + line: 10 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 75 + line: 11 + character: 1 + end_position: + bytes: 76 + line: 11 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 76 + line: 12 + character: 1 + end_position: + bytes: 77 + line: 12 + character: 2 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 77 + line: 12 + character: 2 + end_position: + bytes: 78 + line: 12 + character: 3 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 78 + line: 12 + character: 3 + end_position: + bytes: 80 + line: 12 + character: 5 + token_type: + type: Symbol + symbol: += +- start_position: + bytes: 80 + line: 12 + character: 5 + end_position: + bytes: 81 + line: 12 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 81 + line: 12 + character: 6 + end_position: + bytes: 82 + line: 12 + character: 7 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 82 + line: 12 + character: 7 + end_position: + bytes: 83 + line: 12 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 83 + line: 13 + character: 1 + end_position: + bytes: 84 + line: 13 + character: 2 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 84 + line: 13 + character: 2 + end_position: + bytes: 85 + line: 13 + character: 3 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 85 + line: 13 + character: 3 + end_position: + bytes: 87 + line: 13 + character: 5 + token_type: + type: Symbol + symbol: "-=" +- start_position: + bytes: 87 + line: 13 + character: 5 + end_position: + bytes: 88 + line: 13 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 88 + line: 13 + character: 6 + end_position: + bytes: 89 + line: 13 + character: 7 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 89 + line: 13 + character: 7 + end_position: + bytes: 90 + line: 13 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 90 + line: 14 + character: 1 + end_position: + bytes: 91 + line: 14 + character: 2 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 91 + line: 14 + character: 2 + end_position: + bytes: 92 + line: 14 + character: 3 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 92 + line: 14 + character: 3 + end_position: + bytes: 94 + line: 14 + character: 5 + token_type: + type: Symbol + symbol: "*=" +- start_position: + bytes: 94 + line: 14 + character: 5 + end_position: + bytes: 95 + line: 14 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 95 + line: 14 + character: 6 + end_position: + bytes: 96 + line: 14 + character: 7 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 96 + line: 14 + character: 7 + end_position: + bytes: 97 + line: 14 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 97 + line: 15 + character: 1 + end_position: + bytes: 98 + line: 15 + character: 2 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 98 + line: 15 + character: 2 + end_position: + bytes: 99 + line: 15 + character: 3 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 99 + line: 15 + character: 3 + end_position: + bytes: 101 + line: 15 + character: 5 + token_type: + type: Symbol + symbol: /= +- start_position: + bytes: 101 + line: 15 + character: 5 + end_position: + bytes: 102 + line: 15 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 102 + line: 15 + character: 6 + end_position: + bytes: 103 + line: 15 + character: 7 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 103 + line: 15 + character: 7 + end_position: + bytes: 104 + line: 15 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 104 + line: 16 + character: 1 + end_position: + bytes: 105 + line: 16 + character: 2 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 105 + line: 16 + character: 2 + end_position: + bytes: 106 + line: 16 + character: 3 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 106 + line: 16 + character: 3 + end_position: + bytes: 109 + line: 16 + character: 6 + token_type: + type: Symbol + symbol: //= +- start_position: + bytes: 109 + line: 16 + character: 6 + end_position: + bytes: 110 + line: 16 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 110 + line: 16 + character: 7 + end_position: + bytes: 111 + line: 16 + character: 8 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 111 + line: 16 + character: 8 + end_position: + bytes: 112 + line: 16 + character: 8 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 112 + line: 17 + character: 1 + end_position: + bytes: 113 + line: 17 + character: 2 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 113 + line: 17 + character: 2 + end_position: + bytes: 114 + line: 17 + character: 3 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 114 + line: 17 + character: 3 + end_position: + bytes: 116 + line: 17 + character: 5 + token_type: + type: Symbol + symbol: "%=" +- start_position: + bytes: 116 + line: 17 + character: 5 + end_position: + bytes: 117 + line: 17 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 117 + line: 17 + character: 6 + end_position: + bytes: 118 + line: 17 + character: 7 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 118 + line: 17 + character: 7 + end_position: + bytes: 119 + line: 17 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 119 + line: 18 + character: 1 + end_position: + bytes: 120 + line: 18 + character: 2 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 120 + line: 18 + character: 2 + end_position: + bytes: 121 + line: 18 + character: 3 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 121 + line: 18 + character: 3 + end_position: + bytes: 123 + line: 18 + character: 5 + token_type: + type: Symbol + symbol: ^= +- start_position: + bytes: 123 + line: 18 + character: 5 + end_position: + bytes: 124 + line: 18 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 124 + line: 18 + character: 6 + end_position: + bytes: 125 + line: 18 + character: 7 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 125 + line: 18 + character: 7 + end_position: + bytes: 126 + line: 18 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 126 + line: 19 + character: 1 + end_position: + bytes: 127 + line: 19 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 127 + line: 20 + character: 1 + end_position: + bytes: 132 + line: 20 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 132 + line: 20 + character: 6 + end_position: + bytes: 133 + line: 20 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 133 + line: 20 + character: 7 + end_position: + bytes: 137 + line: 20 + character: 11 + token_type: + type: Identifier + identifier: str1 +- start_position: + bytes: 137 + line: 20 + character: 11 + end_position: + bytes: 138 + line: 20 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 138 + line: 20 + character: 12 + end_position: + bytes: 139 + line: 20 + character: 13 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 139 + line: 20 + character: 13 + end_position: + bytes: 140 + line: 20 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 140 + line: 20 + character: 14 + end_position: + bytes: 149 + line: 20 + character: 23 + token_type: + type: StringLiteral + literal: "Hello, " + quote_type: Double +- start_position: + bytes: 149 + line: 20 + character: 23 + end_position: + bytes: 150 + line: 20 + character: 23 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 150 + line: 21 + character: 1 + end_position: + bytes: 155 + line: 21 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 155 + line: 21 + character: 6 + end_position: + bytes: 156 + line: 21 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 156 + line: 21 + character: 7 + end_position: + bytes: 160 + line: 21 + character: 11 + token_type: + type: Identifier + identifier: str2 +- start_position: + bytes: 160 + line: 21 + character: 11 + end_position: + bytes: 161 + line: 21 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 161 + line: 21 + character: 12 + end_position: + bytes: 162 + line: 21 + character: 13 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 162 + line: 21 + character: 13 + end_position: + bytes: 163 + line: 21 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 163 + line: 21 + character: 14 + end_position: + bytes: 171 + line: 21 + character: 22 + token_type: + type: StringLiteral + literal: world! + quote_type: Double +- start_position: + bytes: 171 + line: 21 + character: 22 + end_position: + bytes: 172 + line: 21 + character: 22 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 172 + line: 22 + character: 1 + end_position: + bytes: 173 + line: 22 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 173 + line: 23 + character: 1 + end_position: + bytes: 177 + line: 23 + character: 5 + token_type: + type: Identifier + identifier: str1 +- start_position: + bytes: 177 + line: 23 + character: 5 + end_position: + bytes: 178 + line: 23 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 178 + line: 23 + character: 6 + end_position: + bytes: 181 + line: 23 + character: 9 + token_type: + type: Symbol + symbol: "..=" +- start_position: + bytes: 181 + line: 23 + character: 9 + end_position: + bytes: 182 + line: 23 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 182 + line: 23 + character: 10 + end_position: + bytes: 190 + line: 23 + character: 18 + token_type: + type: StringLiteral + literal: world! + quote_type: Double +- start_position: + bytes: 190 + line: 23 + character: 18 + end_position: + bytes: 191 + line: 23 + character: 18 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 191 + line: 24 + character: 1 + end_position: + bytes: 195 + line: 24 + character: 5 + token_type: + type: Identifier + identifier: str1 +- start_position: + bytes: 195 + line: 24 + character: 5 + end_position: + bytes: 196 + line: 24 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 196 + line: 24 + character: 6 + end_position: + bytes: 199 + line: 24 + character: 9 + token_type: + type: Symbol + symbol: "..=" +- start_position: + bytes: 199 + line: 24 + character: 9 + end_position: + bytes: 200 + line: 24 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 200 + line: 24 + character: 10 + end_position: + bytes: 204 + line: 24 + character: 14 + token_type: + type: Identifier + identifier: str2 +- start_position: + bytes: 204 + line: 24 + character: 14 + end_position: + bytes: 204 + line: 24 + character: 14 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/continue/ast.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/continue/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..54eb84aad681b63d2f7ab48b6c71a1182ea4cc29 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/continue/ast.snap @@ -0,0 +1,365 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/roblox_cases/pass/continue +--- +stmts: + - - While: + while_token: + leading_trivia: + - start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 27 + line: 1 + character: 28 + token_type: + type: SingleLineComment + comment: " Very important loop here" + - start_position: + bytes: 27 + line: 1 + character: 28 + end_position: + bytes: 28 + line: 1 + character: 28 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 28 + line: 2 + character: 1 + end_position: + bytes: 33 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: while + trailing_trivia: + - start_position: + bytes: 33 + line: 2 + character: 6 + end_position: + bytes: 34 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " + condition: + Symbol: + leading_trivia: [] + token: + start_position: + bytes: 34 + line: 2 + character: 7 + end_position: + bytes: 38 + line: 2 + character: 11 + token_type: + type: Symbol + symbol: "true" + trailing_trivia: + - start_position: + bytes: 38 + line: 2 + character: 11 + end_position: + bytes: 39 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: " " + do_token: + leading_trivia: [] + token: + start_position: + bytes: 39 + line: 2 + character: 12 + end_position: + bytes: 41 + line: 2 + character: 14 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 41 + line: 2 + character: 14 + end_position: + bytes: 42 + line: 2 + character: 14 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: [] + last_stmt: + - Continue: + leading_trivia: + - start_position: + bytes: 42 + line: 3 + character: 1 + end_position: + bytes: 43 + line: 3 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 43 + line: 3 + character: 2 + end_position: + bytes: 51 + line: 3 + character: 10 + token_type: + type: Identifier + identifier: continue + trailing_trivia: + - start_position: + bytes: 51 + line: 3 + character: 10 + end_position: + bytes: 52 + line: 3 + character: 10 + token_type: + type: Whitespace + characters: "\n" + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 52 + line: 4 + character: 1 + end_position: + bytes: 55 + line: 4 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 55 + line: 4 + character: 4 + end_position: + bytes: 56 + line: 4 + character: 4 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 56 + line: 5 + character: 1 + end_position: + bytes: 57 + line: 5 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 57 + line: 6 + character: 1 + end_position: + bytes: 65 + line: 6 + character: 9 + token_type: + type: Identifier + identifier: continue + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 65 + line: 6 + character: 9 + end_position: + bytes: 66 + line: 6 + character: 10 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 66 + line: 6 + character: 10 + end_position: + bytes: 67 + line: 6 + character: 11 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 67 + line: 6 + character: 11 + end_position: + bytes: 68 + line: 6 + character: 11 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: [] + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 68 + line: 7 + character: 1 + end_position: + bytes: 73 + line: 7 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 73 + line: 7 + character: 6 + end_position: + bytes: 74 + line: 7 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 74 + line: 7 + character: 7 + end_position: + bytes: 82 + line: 7 + character: 15 + token_type: + type: Identifier + identifier: continue + trailing_trivia: + - start_position: + bytes: 82 + line: 7 + character: 15 + end_position: + bytes: 83 + line: 7 + character: 16 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 83 + line: 7 + character: 16 + end_position: + bytes: 84 + line: 7 + character: 17 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 84 + line: 7 + character: 17 + end_position: + bytes: 85 + line: 7 + character: 18 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 85 + line: 7 + character: 18 + end_position: + bytes: 86 + line: 7 + character: 19 + token_type: + type: Number + text: "4" + trailing_trivia: + - start_position: + bytes: 86 + line: 7 + character: 19 + end_position: + bytes: 87 + line: 7 + character: 19 + token_type: + type: Whitespace + characters: "\n" + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/continue/source.lua b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/continue/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..f712f24d06598eeeccc8bdb563074118aec71938 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/continue/source.lua @@ -0,0 +1,7 @@ +-- Very important loop here +while true do + continue +end + +continue() +local continue = 4 diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/continue/tokens.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/continue/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..58a1adabf33efa6ef7b58e1e760320c86568f665 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/continue/tokens.snap @@ -0,0 +1,303 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/roblox_cases/pass/continue + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 27 + line: 1 + character: 28 + token_type: + type: SingleLineComment + comment: " Very important loop here" +- start_position: + bytes: 27 + line: 1 + character: 28 + end_position: + bytes: 28 + line: 1 + character: 28 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 28 + line: 2 + character: 1 + end_position: + bytes: 33 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: while +- start_position: + bytes: 33 + line: 2 + character: 6 + end_position: + bytes: 34 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 34 + line: 2 + character: 7 + end_position: + bytes: 38 + line: 2 + character: 11 + token_type: + type: Symbol + symbol: "true" +- start_position: + bytes: 38 + line: 2 + character: 11 + end_position: + bytes: 39 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 39 + line: 2 + character: 12 + end_position: + bytes: 41 + line: 2 + character: 14 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 41 + line: 2 + character: 14 + end_position: + bytes: 42 + line: 2 + character: 14 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 42 + line: 3 + character: 1 + end_position: + bytes: 43 + line: 3 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 43 + line: 3 + character: 2 + end_position: + bytes: 51 + line: 3 + character: 10 + token_type: + type: Identifier + identifier: continue +- start_position: + bytes: 51 + line: 3 + character: 10 + end_position: + bytes: 52 + line: 3 + character: 10 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 52 + line: 4 + character: 1 + end_position: + bytes: 55 + line: 4 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 55 + line: 4 + character: 4 + end_position: + bytes: 56 + line: 4 + character: 4 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 56 + line: 5 + character: 1 + end_position: + bytes: 57 + line: 5 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 57 + line: 6 + character: 1 + end_position: + bytes: 65 + line: 6 + character: 9 + token_type: + type: Identifier + identifier: continue +- start_position: + bytes: 65 + line: 6 + character: 9 + end_position: + bytes: 66 + line: 6 + character: 10 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 66 + line: 6 + character: 10 + end_position: + bytes: 67 + line: 6 + character: 11 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 67 + line: 6 + character: 11 + end_position: + bytes: 68 + line: 6 + character: 11 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 68 + line: 7 + character: 1 + end_position: + bytes: 73 + line: 7 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 73 + line: 7 + character: 6 + end_position: + bytes: 74 + line: 7 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 74 + line: 7 + character: 7 + end_position: + bytes: 82 + line: 7 + character: 15 + token_type: + type: Identifier + identifier: continue +- start_position: + bytes: 82 + line: 7 + character: 15 + end_position: + bytes: 83 + line: 7 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 83 + line: 7 + character: 16 + end_position: + bytes: 84 + line: 7 + character: 17 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 84 + line: 7 + character: 17 + end_position: + bytes: 85 + line: 7 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 85 + line: 7 + character: 18 + end_position: + bytes: 86 + line: 7 + character: 19 + token_type: + type: Number + text: "4" +- start_position: + bytes: 86 + line: 7 + character: 19 + end_position: + bytes: 87 + line: 7 + character: 19 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 87 + line: 8 + character: 1 + end_position: + bytes: 87 + line: 8 + character: 1 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/decimal_seperators/ast.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/decimal_seperators/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..8a2bf0d50411fecd2adc11f35291c558d1bd51b9 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/decimal_seperators/ast.snap @@ -0,0 +1,663 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/roblox_cases/pass/decimal_seperators +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Identifier + identifier: num1 + trailing_trivia: + - start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Number + text: 1_048_576 + trailing_trivia: + - start_position: + bytes: 22 + line: 1 + character: 23 + end_position: + bytes: 23 + line: 1 + character: 23 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 23 + line: 2 + character: 1 + end_position: + bytes: 28 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 28 + line: 2 + character: 6 + end_position: + bytes: 29 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 29 + line: 2 + character: 7 + end_position: + bytes: 33 + line: 2 + character: 11 + token_type: + type: Identifier + identifier: num2 + trailing_trivia: + - start_position: + bytes: 33 + line: 2 + character: 11 + end_position: + bytes: 34 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 34 + line: 2 + character: 12 + end_position: + bytes: 35 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 35 + line: 2 + character: 13 + end_position: + bytes: 36 + line: 2 + character: 14 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 36 + line: 2 + character: 14 + end_position: + bytes: 47 + line: 2 + character: 25 + token_type: + type: Number + text: "0xFFFF_FFFF" + trailing_trivia: + - start_position: + bytes: 47 + line: 2 + character: 25 + end_position: + bytes: 48 + line: 2 + character: 25 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 48 + line: 3 + character: 1 + end_position: + bytes: 53 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 53 + line: 3 + character: 6 + end_position: + bytes: 54 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 54 + line: 3 + character: 7 + end_position: + bytes: 58 + line: 3 + character: 11 + token_type: + type: Identifier + identifier: num3 + trailing_trivia: + - start_position: + bytes: 58 + line: 3 + character: 11 + end_position: + bytes: 59 + line: 3 + character: 12 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 59 + line: 3 + character: 12 + end_position: + bytes: 60 + line: 3 + character: 13 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 60 + line: 3 + character: 13 + end_position: + bytes: 61 + line: 3 + character: 14 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 61 + line: 3 + character: 14 + end_position: + bytes: 73 + line: 3 + character: 26 + token_type: + type: Number + text: 0b_0101_0101 + trailing_trivia: + - start_position: + bytes: 73 + line: 3 + character: 26 + end_position: + bytes: 74 + line: 3 + character: 26 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 74 + line: 4 + character: 1 + end_position: + bytes: 79 + line: 4 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 79 + line: 4 + character: 6 + end_position: + bytes: 80 + line: 4 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 80 + line: 4 + character: 7 + end_position: + bytes: 84 + line: 4 + character: 11 + token_type: + type: Identifier + identifier: num4 + trailing_trivia: + - start_position: + bytes: 84 + line: 4 + character: 11 + end_position: + bytes: 85 + line: 4 + character: 12 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 85 + line: 4 + character: 12 + end_position: + bytes: 86 + line: 4 + character: 13 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 86 + line: 4 + character: 13 + end_position: + bytes: 87 + line: 4 + character: 14 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 87 + line: 4 + character: 14 + end_position: + bytes: 108 + line: 4 + character: 35 + token_type: + type: Number + text: 1_523_423.132_452_312 + trailing_trivia: + - start_position: + bytes: 108 + line: 4 + character: 35 + end_position: + bytes: 109 + line: 4 + character: 35 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 109 + line: 5 + character: 1 + end_position: + bytes: 114 + line: 5 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 114 + line: 5 + character: 6 + end_position: + bytes: 115 + line: 5 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 115 + line: 5 + character: 7 + end_position: + bytes: 119 + line: 5 + character: 11 + token_type: + type: Identifier + identifier: num5 + trailing_trivia: + - start_position: + bytes: 119 + line: 5 + character: 11 + end_position: + bytes: 120 + line: 5 + character: 12 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 120 + line: 5 + character: 12 + end_position: + bytes: 121 + line: 5 + character: 13 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 121 + line: 5 + character: 13 + end_position: + bytes: 122 + line: 5 + character: 14 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 122 + line: 5 + character: 14 + end_position: + bytes: 131 + line: 5 + character: 23 + token_type: + type: Number + text: 1e512_412 + trailing_trivia: + - start_position: + bytes: 131 + line: 5 + character: 23 + end_position: + bytes: 132 + line: 5 + character: 23 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 132 + line: 6 + character: 1 + end_position: + bytes: 137 + line: 6 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 137 + line: 6 + character: 6 + end_position: + bytes: 138 + line: 6 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 138 + line: 6 + character: 7 + end_position: + bytes: 142 + line: 6 + character: 11 + token_type: + type: Identifier + identifier: num6 + trailing_trivia: + - start_position: + bytes: 142 + line: 6 + character: 11 + end_position: + bytes: 143 + line: 6 + character: 12 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 143 + line: 6 + character: 12 + end_position: + bytes: 144 + line: 6 + character: 13 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 144 + line: 6 + character: 13 + end_position: + bytes: 145 + line: 6 + character: 14 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 145 + line: 6 + character: 14 + end_position: + bytes: 155 + line: 6 + character: 24 + token_type: + type: Number + text: 1e-512_412 + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/decimal_seperators/source.lua b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/decimal_seperators/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..b1bcb502862df1484d6f5f0894b19273cf9c93d5 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/decimal_seperators/source.lua @@ -0,0 +1,6 @@ +local num1 = 1_048_576 +local num2 = 0xFFFF_FFFF +local num3 = 0b_0101_0101 +local num4 = 1_523_423.132_452_312 +local num5 = 1e512_412 +local num6 = 1e-512_412 \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/decimal_seperators/tokens.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/decimal_seperators/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..83883aabaaef46ff48b1b147ccb612ebafc7cb7e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/decimal_seperators/tokens.snap @@ -0,0 +1,534 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/roblox_cases/pass/decimal_seperators + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Identifier + identifier: num1 +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Number + text: 1_048_576 +- start_position: + bytes: 22 + line: 1 + character: 23 + end_position: + bytes: 23 + line: 1 + character: 23 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 23 + line: 2 + character: 1 + end_position: + bytes: 28 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 28 + line: 2 + character: 6 + end_position: + bytes: 29 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 29 + line: 2 + character: 7 + end_position: + bytes: 33 + line: 2 + character: 11 + token_type: + type: Identifier + identifier: num2 +- start_position: + bytes: 33 + line: 2 + character: 11 + end_position: + bytes: 34 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 34 + line: 2 + character: 12 + end_position: + bytes: 35 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 35 + line: 2 + character: 13 + end_position: + bytes: 36 + line: 2 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 36 + line: 2 + character: 14 + end_position: + bytes: 47 + line: 2 + character: 25 + token_type: + type: Number + text: "0xFFFF_FFFF" +- start_position: + bytes: 47 + line: 2 + character: 25 + end_position: + bytes: 48 + line: 2 + character: 25 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 48 + line: 3 + character: 1 + end_position: + bytes: 53 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 53 + line: 3 + character: 6 + end_position: + bytes: 54 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 54 + line: 3 + character: 7 + end_position: + bytes: 58 + line: 3 + character: 11 + token_type: + type: Identifier + identifier: num3 +- start_position: + bytes: 58 + line: 3 + character: 11 + end_position: + bytes: 59 + line: 3 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 59 + line: 3 + character: 12 + end_position: + bytes: 60 + line: 3 + character: 13 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 60 + line: 3 + character: 13 + end_position: + bytes: 61 + line: 3 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 61 + line: 3 + character: 14 + end_position: + bytes: 73 + line: 3 + character: 26 + token_type: + type: Number + text: 0b_0101_0101 +- start_position: + bytes: 73 + line: 3 + character: 26 + end_position: + bytes: 74 + line: 3 + character: 26 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 74 + line: 4 + character: 1 + end_position: + bytes: 79 + line: 4 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 79 + line: 4 + character: 6 + end_position: + bytes: 80 + line: 4 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 80 + line: 4 + character: 7 + end_position: + bytes: 84 + line: 4 + character: 11 + token_type: + type: Identifier + identifier: num4 +- start_position: + bytes: 84 + line: 4 + character: 11 + end_position: + bytes: 85 + line: 4 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 85 + line: 4 + character: 12 + end_position: + bytes: 86 + line: 4 + character: 13 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 86 + line: 4 + character: 13 + end_position: + bytes: 87 + line: 4 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 87 + line: 4 + character: 14 + end_position: + bytes: 108 + line: 4 + character: 35 + token_type: + type: Number + text: 1_523_423.132_452_312 +- start_position: + bytes: 108 + line: 4 + character: 35 + end_position: + bytes: 109 + line: 4 + character: 35 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 109 + line: 5 + character: 1 + end_position: + bytes: 114 + line: 5 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 114 + line: 5 + character: 6 + end_position: + bytes: 115 + line: 5 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 115 + line: 5 + character: 7 + end_position: + bytes: 119 + line: 5 + character: 11 + token_type: + type: Identifier + identifier: num5 +- start_position: + bytes: 119 + line: 5 + character: 11 + end_position: + bytes: 120 + line: 5 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 120 + line: 5 + character: 12 + end_position: + bytes: 121 + line: 5 + character: 13 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 121 + line: 5 + character: 13 + end_position: + bytes: 122 + line: 5 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 122 + line: 5 + character: 14 + end_position: + bytes: 131 + line: 5 + character: 23 + token_type: + type: Number + text: 1e512_412 +- start_position: + bytes: 131 + line: 5 + character: 23 + end_position: + bytes: 132 + line: 5 + character: 23 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 132 + line: 6 + character: 1 + end_position: + bytes: 137 + line: 6 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 137 + line: 6 + character: 6 + end_position: + bytes: 138 + line: 6 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 138 + line: 6 + character: 7 + end_position: + bytes: 142 + line: 6 + character: 11 + token_type: + type: Identifier + identifier: num6 +- start_position: + bytes: 142 + line: 6 + character: 11 + end_position: + bytes: 143 + line: 6 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 143 + line: 6 + character: 12 + end_position: + bytes: 144 + line: 6 + character: 13 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 144 + line: 6 + character: 13 + end_position: + bytes: 145 + line: 6 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 145 + line: 6 + character: 14 + end_position: + bytes: 155 + line: 6 + character: 24 + token_type: + type: Number + text: 1e-512_412 +- start_position: + bytes: 155 + line: 6 + character: 24 + end_position: + bytes: 155 + line: 6 + character: 24 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/floor_division/ast.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/floor_division/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..31e67c65e8ff497c99f426f243cddb1042ffd1bb --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/floor_division/ast.snap @@ -0,0 +1,173 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + BinaryOperator: + lhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " + binop: + DoubleSlash: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: // + trailing_trivia: + - start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Number + text: "2" + trailing_trivia: + - start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 17 + token_type: + type: Whitespace + characters: "\n" + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/floor_division/source.lua b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/floor_division/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..8460eebbd5fe3f6ff2601a8e1816b07c66a6883d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/floor_division/source.lua @@ -0,0 +1 @@ +local x = 1 // 2 diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/floor_division/tokens.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/floor_division/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..ec02630070d8d51c202b94d8374980b6ba22f09f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/floor_division/tokens.snap @@ -0,0 +1,147 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Number + text: "1" +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: // +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Number + text: "2" +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 17 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 17 + line: 2 + character: 1 + end_position: + bytes: 17 + line: 2 + character: 1 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/if_expression/ast.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/if_expression/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..37110dd7688286f6c24e2074d862de18a32c931f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/if_expression/ast.snap @@ -0,0 +1,3198 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/roblox_cases/pass/if_expression +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + IfExpression: + if_token: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: if + trailing_trivia: + - start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Whitespace + characters: " " + condition: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Identifier + identifier: foo + trailing_trivia: + - start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Whitespace + characters: " " + if_expression: + Var: + Expression: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 22 + line: 1 + character: 23 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Identifier + identifier: foo + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 26 + line: 1 + character: 27 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 26 + line: 1 + character: 27 + end_position: + bytes: 27 + line: 1 + character: 28 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 27 + line: 1 + character: 28 + end_position: + bytes: 28 + line: 1 + character: 29 + token_type: + type: Whitespace + characters: " " + else_if_expressions: ~ + else_token: + leading_trivia: [] + token: + start_position: + bytes: 28 + line: 1 + character: 29 + end_position: + bytes: 32 + line: 1 + character: 33 + token_type: + type: Symbol + symbol: else + trailing_trivia: + - start_position: + bytes: 32 + line: 1 + character: 33 + end_position: + bytes: 33 + line: 1 + character: 34 + token_type: + type: Whitespace + characters: " " + else_expression: + Number: + leading_trivia: [] + token: + start_position: + bytes: 33 + line: 1 + character: 34 + end_position: + bytes: 34 + line: 1 + character: 35 + token_type: + type: Number + text: "5" + trailing_trivia: + - start_position: + bytes: 34 + line: 1 + character: 35 + end_position: + bytes: 35 + line: 1 + character: 35 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 35 + line: 2 + character: 1 + end_position: + bytes: 40 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 40 + line: 2 + character: 6 + end_position: + bytes: 41 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 41 + line: 2 + character: 7 + end_position: + bytes: 42 + line: 2 + character: 8 + token_type: + type: Identifier + identifier: y + trailing_trivia: + - start_position: + bytes: 42 + line: 2 + character: 8 + end_position: + bytes: 43 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 43 + line: 2 + character: 9 + end_position: + bytes: 44 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 44 + line: 2 + character: 10 + end_position: + bytes: 45 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + FunctionCall: + prefix: + Expression: + Parentheses: + contained: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 45 + line: 2 + character: 11 + end_position: + bytes: 46 + line: 2 + character: 12 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 79 + line: 2 + character: 45 + end_position: + bytes: 80 + line: 2 + character: 46 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + expression: + IfExpression: + if_token: + leading_trivia: [] + token: + start_position: + bytes: 46 + line: 2 + character: 12 + end_position: + bytes: 48 + line: 2 + character: 14 + token_type: + type: Symbol + symbol: if + trailing_trivia: + - start_position: + bytes: 48 + line: 2 + character: 14 + end_position: + bytes: 49 + line: 2 + character: 15 + token_type: + type: Whitespace + characters: " " + condition: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 49 + line: 2 + character: 15 + end_position: + bytes: 50 + line: 2 + character: 16 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 50 + line: 2 + character: 16 + end_position: + bytes: 51 + line: 2 + character: 17 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 51 + line: 2 + character: 17 + end_position: + bytes: 55 + line: 2 + character: 21 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 55 + line: 2 + character: 21 + end_position: + bytes: 56 + line: 2 + character: 22 + token_type: + type: Whitespace + characters: " " + if_expression: + Var: + Expression: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 56 + line: 2 + character: 22 + end_position: + bytes: 57 + line: 2 + character: 23 + token_type: + type: Identifier + identifier: x + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 57 + line: 2 + character: 23 + end_position: + bytes: 58 + line: 2 + character: 24 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 58 + line: 2 + character: 24 + end_position: + bytes: 65 + line: 2 + character: 31 + token_type: + type: Identifier + identifier: indices + trailing_trivia: + - start_position: + bytes: 65 + line: 2 + character: 31 + end_position: + bytes: 66 + line: 2 + character: 32 + token_type: + type: Whitespace + characters: " " + else_if_expressions: ~ + else_token: + leading_trivia: [] + token: + start_position: + bytes: 66 + line: 2 + character: 32 + end_position: + bytes: 70 + line: 2 + character: 36 + token_type: + type: Symbol + symbol: else + trailing_trivia: + - start_position: + bytes: 70 + line: 2 + character: 36 + end_position: + bytes: 71 + line: 2 + character: 37 + token_type: + type: Whitespace + characters: " " + else_expression: + FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 71 + line: 2 + character: 37 + end_position: + bytes: 77 + line: 2 + character: 43 + token_type: + type: Identifier + identifier: create + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 77 + line: 2 + character: 43 + end_position: + bytes: 78 + line: 2 + character: 44 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 78 + line: 2 + character: 44 + end_position: + bytes: 79 + line: 2 + character: 45 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: [] + suffixes: + - Call: + MethodCall: + colon_token: + leading_trivia: [] + token: + start_position: + bytes: 80 + line: 2 + character: 46 + end_position: + bytes: 81 + line: 2 + character: 47 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 81 + line: 2 + character: 47 + end_position: + bytes: 87 + line: 2 + character: 53 + token_type: + type: Identifier + identifier: update + trailing_trivia: [] + args: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 87 + line: 2 + character: 53 + end_position: + bytes: 88 + line: 2 + character: 54 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 134 + line: 2 + character: 100 + end_position: + bytes: 135 + line: 2 + character: 101 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 135 + line: 2 + character: 101 + end_position: + bytes: 136 + line: 2 + character: 101 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - End: + IfExpression: + if_token: + leading_trivia: [] + token: + start_position: + bytes: 88 + line: 2 + character: 54 + end_position: + bytes: 90 + line: 2 + character: 56 + token_type: + type: Symbol + symbol: if + trailing_trivia: + - start_position: + bytes: 90 + line: 2 + character: 56 + end_position: + bytes: 91 + line: 2 + character: 57 + token_type: + type: Whitespace + characters: " " + condition: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 91 + line: 2 + character: 57 + end_position: + bytes: 103 + line: 2 + character: 69 + token_type: + type: Identifier + identifier: shouldUpdate + trailing_trivia: + - start_position: + bytes: 103 + line: 2 + character: 69 + end_position: + bytes: 104 + line: 2 + character: 70 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 104 + line: 2 + character: 70 + end_position: + bytes: 108 + line: 2 + character: 74 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 108 + line: 2 + character: 74 + end_position: + bytes: 109 + line: 2 + character: 75 + token_type: + type: Whitespace + characters: " " + if_expression: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 109 + line: 2 + character: 75 + end_position: + bytes: 120 + line: 2 + character: 86 + token_type: + type: Identifier + identifier: information + trailing_trivia: + - start_position: + bytes: 120 + line: 2 + character: 86 + end_position: + bytes: 121 + line: 2 + character: 87 + token_type: + type: Whitespace + characters: " " + else_if_expressions: ~ + else_token: + leading_trivia: [] + token: + start_position: + bytes: 121 + line: 2 + character: 87 + end_position: + bytes: 125 + line: 2 + character: 91 + token_type: + type: Symbol + symbol: else + trailing_trivia: + - start_position: + bytes: 125 + line: 2 + character: 91 + end_position: + bytes: 126 + line: 2 + character: 92 + token_type: + type: Whitespace + characters: " " + else_expression: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 126 + line: 2 + character: 92 + end_position: + bytes: 134 + line: 2 + character: 100 + token_type: + type: Identifier + identifier: defaults + trailing_trivia: [] + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 136 + line: 3 + character: 1 + end_position: + bytes: 141 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 141 + line: 3 + character: 6 + end_position: + bytes: 142 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 142 + line: 3 + character: 7 + end_position: + bytes: 143 + line: 3 + character: 8 + token_type: + type: Identifier + identifier: z + trailing_trivia: + - start_position: + bytes: 143 + line: 3 + character: 8 + end_position: + bytes: 144 + line: 3 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 144 + line: 3 + character: 9 + end_position: + bytes: 145 + line: 3 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 145 + line: 3 + character: 10 + end_position: + bytes: 146 + line: 3 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + TypeAssertion: + expression: + Parentheses: + contained: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 146 + line: 3 + character: 11 + end_position: + bytes: 147 + line: 3 + character: 12 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 171 + line: 3 + character: 36 + end_position: + bytes: 172 + line: 3 + character: 37 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 172 + line: 3 + character: 37 + end_position: + bytes: 173 + line: 3 + character: 38 + token_type: + type: Whitespace + characters: " " + expression: + IfExpression: + if_token: + leading_trivia: [] + token: + start_position: + bytes: 147 + line: 3 + character: 12 + end_position: + bytes: 149 + line: 3 + character: 14 + token_type: + type: Symbol + symbol: if + trailing_trivia: + - start_position: + bytes: 149 + line: 3 + character: 14 + end_position: + bytes: 150 + line: 3 + character: 15 + token_type: + type: Whitespace + characters: " " + condition: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 150 + line: 3 + character: 15 + end_position: + bytes: 153 + line: 3 + character: 18 + token_type: + type: Identifier + identifier: bar + trailing_trivia: + - start_position: + bytes: 153 + line: 3 + character: 18 + end_position: + bytes: 154 + line: 3 + character: 19 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 154 + line: 3 + character: 19 + end_position: + bytes: 158 + line: 3 + character: 23 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 158 + line: 3 + character: 23 + end_position: + bytes: 159 + line: 3 + character: 24 + token_type: + type: Whitespace + characters: " " + if_expression: + Var: + Expression: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 159 + line: 3 + character: 24 + end_position: + bytes: 162 + line: 3 + character: 27 + token_type: + type: Identifier + identifier: foo + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 162 + line: 3 + character: 27 + end_position: + bytes: 163 + line: 3 + character: 28 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 163 + line: 3 + character: 28 + end_position: + bytes: 164 + line: 3 + character: 29 + token_type: + type: Identifier + identifier: y + trailing_trivia: + - start_position: + bytes: 164 + line: 3 + character: 29 + end_position: + bytes: 165 + line: 3 + character: 30 + token_type: + type: Whitespace + characters: " " + else_if_expressions: ~ + else_token: + leading_trivia: [] + token: + start_position: + bytes: 165 + line: 3 + character: 30 + end_position: + bytes: 169 + line: 3 + character: 34 + token_type: + type: Symbol + symbol: else + trailing_trivia: + - start_position: + bytes: 169 + line: 3 + character: 34 + end_position: + bytes: 170 + line: 3 + character: 35 + token_type: + type: Whitespace + characters: " " + else_expression: + Number: + leading_trivia: [] + token: + start_position: + bytes: 170 + line: 3 + character: 35 + end_position: + bytes: 171 + line: 3 + character: 36 + token_type: + type: Number + text: "5" + trailing_trivia: [] + type_assertion: + assertion_op: + leading_trivia: [] + token: + start_position: + bytes: 173 + line: 3 + character: 38 + end_position: + bytes: 175 + line: 3 + character: 40 + token_type: + type: Symbol + symbol: "::" + trailing_trivia: + - start_position: + bytes: 175 + line: 3 + character: 40 + end_position: + bytes: 176 + line: 3 + character: 41 + token_type: + type: Whitespace + characters: " " + cast_to: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 176 + line: 3 + character: 41 + end_position: + bytes: 182 + line: 3 + character: 47 + token_type: + type: Identifier + identifier: number + trailing_trivia: + - start_position: + bytes: 182 + line: 3 + character: 47 + end_position: + bytes: 183 + line: 3 + character: 47 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: + - start_position: + bytes: 183 + line: 4 + character: 1 + end_position: + bytes: 184 + line: 4 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 184 + line: 5 + character: 1 + end_position: + bytes: 189 + line: 5 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 189 + line: 5 + character: 6 + end_position: + bytes: 190 + line: 5 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 190 + line: 5 + character: 7 + end_position: + bytes: 191 + line: 5 + character: 8 + token_type: + type: Identifier + identifier: a + trailing_trivia: + - start_position: + bytes: 191 + line: 5 + character: 8 + end_position: + bytes: 192 + line: 5 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 192 + line: 5 + character: 9 + end_position: + bytes: 193 + line: 5 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 193 + line: 5 + character: 10 + end_position: + bytes: 194 + line: 5 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + IfExpression: + if_token: + leading_trivia: [] + token: + start_position: + bytes: 194 + line: 5 + character: 11 + end_position: + bytes: 196 + line: 5 + character: 13 + token_type: + type: Symbol + symbol: if + trailing_trivia: + - start_position: + bytes: 196 + line: 5 + character: 13 + end_position: + bytes: 197 + line: 5 + character: 14 + token_type: + type: Whitespace + characters: " " + condition: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 197 + line: 5 + character: 14 + end_position: + bytes: 200 + line: 5 + character: 17 + token_type: + type: Identifier + identifier: foo + trailing_trivia: + - start_position: + bytes: 200 + line: 5 + character: 17 + end_position: + bytes: 201 + line: 5 + character: 18 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 201 + line: 5 + character: 18 + end_position: + bytes: 205 + line: 5 + character: 22 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 205 + line: 5 + character: 22 + end_position: + bytes: 206 + line: 5 + character: 23 + token_type: + type: Whitespace + characters: " " + if_expression: + Var: + Expression: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 206 + line: 5 + character: 23 + end_position: + bytes: 209 + line: 5 + character: 26 + token_type: + type: Identifier + identifier: foo + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 209 + line: 5 + character: 26 + end_position: + bytes: 210 + line: 5 + character: 27 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 210 + line: 5 + character: 27 + end_position: + bytes: 211 + line: 5 + character: 28 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 211 + line: 5 + character: 28 + end_position: + bytes: 212 + line: 5 + character: 29 + token_type: + type: Whitespace + characters: " " + else_if_expressions: + - else_if_token: + leading_trivia: [] + token: + start_position: + bytes: 212 + line: 5 + character: 29 + end_position: + bytes: 218 + line: 5 + character: 35 + token_type: + type: Symbol + symbol: elseif + trailing_trivia: + - start_position: + bytes: 218 + line: 5 + character: 35 + end_position: + bytes: 219 + line: 5 + character: 36 + token_type: + type: Whitespace + characters: " " + condition: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 219 + line: 5 + character: 36 + end_position: + bytes: 222 + line: 5 + character: 39 + token_type: + type: Identifier + identifier: bar + trailing_trivia: + - start_position: + bytes: 222 + line: 5 + character: 39 + end_position: + bytes: 223 + line: 5 + character: 40 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 223 + line: 5 + character: 40 + end_position: + bytes: 227 + line: 5 + character: 44 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 227 + line: 5 + character: 44 + end_position: + bytes: 228 + line: 5 + character: 45 + token_type: + type: Whitespace + characters: " " + expression: + Var: + Expression: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 228 + line: 5 + character: 45 + end_position: + bytes: 231 + line: 5 + character: 48 + token_type: + type: Identifier + identifier: bar + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 231 + line: 5 + character: 48 + end_position: + bytes: 232 + line: 5 + character: 49 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 232 + line: 5 + character: 49 + end_position: + bytes: 233 + line: 5 + character: 50 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 233 + line: 5 + character: 50 + end_position: + bytes: 234 + line: 5 + character: 51 + token_type: + type: Whitespace + characters: " " + else_token: + leading_trivia: [] + token: + start_position: + bytes: 234 + line: 5 + character: 51 + end_position: + bytes: 238 + line: 5 + character: 55 + token_type: + type: Symbol + symbol: else + trailing_trivia: + - start_position: + bytes: 238 + line: 5 + character: 55 + end_position: + bytes: 239 + line: 5 + character: 56 + token_type: + type: Whitespace + characters: " " + else_expression: + Number: + leading_trivia: [] + token: + start_position: + bytes: 239 + line: 5 + character: 56 + end_position: + bytes: 240 + line: 5 + character: 57 + token_type: + type: Number + text: "5" + trailing_trivia: + - start_position: + bytes: 240 + line: 5 + character: 57 + end_position: + bytes: 241 + line: 5 + character: 57 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 241 + line: 6 + character: 1 + end_position: + bytes: 246 + line: 6 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 246 + line: 6 + character: 6 + end_position: + bytes: 247 + line: 6 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 247 + line: 6 + character: 7 + end_position: + bytes: 248 + line: 6 + character: 8 + token_type: + type: Identifier + identifier: b + trailing_trivia: + - start_position: + bytes: 248 + line: 6 + character: 8 + end_position: + bytes: 249 + line: 6 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 249 + line: 6 + character: 9 + end_position: + bytes: 250 + line: 6 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 250 + line: 6 + character: 10 + end_position: + bytes: 251 + line: 6 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + IfExpression: + if_token: + leading_trivia: [] + token: + start_position: + bytes: 251 + line: 6 + character: 11 + end_position: + bytes: 253 + line: 6 + character: 13 + token_type: + type: Symbol + symbol: if + trailing_trivia: + - start_position: + bytes: 253 + line: 6 + character: 13 + end_position: + bytes: 254 + line: 6 + character: 14 + token_type: + type: Whitespace + characters: " " + condition: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 254 + line: 6 + character: 14 + end_position: + bytes: 257 + line: 6 + character: 17 + token_type: + type: Identifier + identifier: foo + trailing_trivia: + - start_position: + bytes: 257 + line: 6 + character: 17 + end_position: + bytes: 258 + line: 6 + character: 18 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 258 + line: 6 + character: 18 + end_position: + bytes: 262 + line: 6 + character: 22 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 262 + line: 6 + character: 22 + end_position: + bytes: 263 + line: 6 + character: 23 + token_type: + type: Whitespace + characters: " " + if_expression: + IfExpression: + if_token: + leading_trivia: [] + token: + start_position: + bytes: 263 + line: 6 + character: 23 + end_position: + bytes: 265 + line: 6 + character: 25 + token_type: + type: Symbol + symbol: if + trailing_trivia: + - start_position: + bytes: 265 + line: 6 + character: 25 + end_position: + bytes: 266 + line: 6 + character: 26 + token_type: + type: Whitespace + characters: " " + condition: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 266 + line: 6 + character: 26 + end_position: + bytes: 269 + line: 6 + character: 29 + token_type: + type: Identifier + identifier: bar + trailing_trivia: + - start_position: + bytes: 269 + line: 6 + character: 29 + end_position: + bytes: 270 + line: 6 + character: 30 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 270 + line: 6 + character: 30 + end_position: + bytes: 274 + line: 6 + character: 34 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 274 + line: 6 + character: 34 + end_position: + bytes: 275 + line: 6 + character: 35 + token_type: + type: Whitespace + characters: " " + if_expression: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 275 + line: 6 + character: 35 + end_position: + bytes: 278 + line: 6 + character: 38 + token_type: + type: Identifier + identifier: bar + trailing_trivia: + - start_position: + bytes: 278 + line: 6 + character: 38 + end_position: + bytes: 279 + line: 6 + character: 39 + token_type: + type: Whitespace + characters: " " + else_if_expressions: ~ + else_token: + leading_trivia: [] + token: + start_position: + bytes: 279 + line: 6 + character: 39 + end_position: + bytes: 283 + line: 6 + character: 43 + token_type: + type: Symbol + symbol: else + trailing_trivia: + - start_position: + bytes: 283 + line: 6 + character: 43 + end_position: + bytes: 284 + line: 6 + character: 44 + token_type: + type: Whitespace + characters: " " + else_expression: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 284 + line: 6 + character: 44 + end_position: + bytes: 287 + line: 6 + character: 47 + token_type: + type: Identifier + identifier: foo + trailing_trivia: + - start_position: + bytes: 287 + line: 6 + character: 47 + end_position: + bytes: 288 + line: 6 + character: 48 + token_type: + type: Whitespace + characters: " " + else_if_expressions: ~ + else_token: + leading_trivia: [] + token: + start_position: + bytes: 288 + line: 6 + character: 48 + end_position: + bytes: 292 + line: 6 + character: 52 + token_type: + type: Symbol + symbol: else + trailing_trivia: + - start_position: + bytes: 292 + line: 6 + character: 52 + end_position: + bytes: 293 + line: 6 + character: 53 + token_type: + type: Whitespace + characters: " " + else_expression: + Number: + leading_trivia: [] + token: + start_position: + bytes: 293 + line: 6 + character: 53 + end_position: + bytes: 294 + line: 6 + character: 54 + token_type: + type: Number + text: "5" + trailing_trivia: + - start_position: + bytes: 294 + line: 6 + character: 54 + end_position: + bytes: 295 + line: 6 + character: 54 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 295 + line: 7 + character: 1 + end_position: + bytes: 300 + line: 7 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 300 + line: 7 + character: 6 + end_position: + bytes: 301 + line: 7 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 301 + line: 7 + character: 7 + end_position: + bytes: 302 + line: 7 + character: 8 + token_type: + type: Identifier + identifier: c + trailing_trivia: + - start_position: + bytes: 302 + line: 7 + character: 8 + end_position: + bytes: 303 + line: 7 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 303 + line: 7 + character: 9 + end_position: + bytes: 304 + line: 7 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 304 + line: 7 + character: 10 + end_position: + bytes: 305 + line: 7 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + IfExpression: + if_token: + leading_trivia: [] + token: + start_position: + bytes: 305 + line: 7 + character: 11 + end_position: + bytes: 307 + line: 7 + character: 13 + token_type: + type: Symbol + symbol: if + trailing_trivia: + - start_position: + bytes: 307 + line: 7 + character: 13 + end_position: + bytes: 308 + line: 7 + character: 14 + token_type: + type: Whitespace + characters: " " + condition: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 308 + line: 7 + character: 14 + end_position: + bytes: 311 + line: 7 + character: 17 + token_type: + type: Identifier + identifier: foo + trailing_trivia: + - start_position: + bytes: 311 + line: 7 + character: 17 + end_position: + bytes: 312 + line: 7 + character: 18 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 312 + line: 7 + character: 18 + end_position: + bytes: 316 + line: 7 + character: 22 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 316 + line: 7 + character: 22 + end_position: + bytes: 317 + line: 7 + character: 23 + token_type: + type: Whitespace + characters: " " + if_expression: + Parentheses: + contained: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 317 + line: 7 + character: 23 + end_position: + bytes: 318 + line: 7 + character: 24 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 333 + line: 7 + character: 39 + end_position: + bytes: 334 + line: 7 + character: 40 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 334 + line: 7 + character: 40 + end_position: + bytes: 335 + line: 7 + character: 41 + token_type: + type: Whitespace + characters: " " + expression: + TypeAssertion: + expression: + Var: + Expression: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 318 + line: 7 + character: 24 + end_position: + bytes: 321 + line: 7 + character: 27 + token_type: + type: Identifier + identifier: foo + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 321 + line: 7 + character: 27 + end_position: + bytes: 322 + line: 7 + character: 28 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 322 + line: 7 + character: 28 + end_position: + bytes: 323 + line: 7 + character: 29 + token_type: + type: Identifier + identifier: x + trailing_trivia: + - start_position: + bytes: 323 + line: 7 + character: 29 + end_position: + bytes: 324 + line: 7 + character: 30 + token_type: + type: Whitespace + characters: " " + type_assertion: + assertion_op: + leading_trivia: [] + token: + start_position: + bytes: 324 + line: 7 + character: 30 + end_position: + bytes: 326 + line: 7 + character: 32 + token_type: + type: Symbol + symbol: "::" + trailing_trivia: + - start_position: + bytes: 326 + line: 7 + character: 32 + end_position: + bytes: 327 + line: 7 + character: 33 + token_type: + type: Whitespace + characters: " " + cast_to: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 327 + line: 7 + character: 33 + end_position: + bytes: 333 + line: 7 + character: 39 + token_type: + type: Identifier + identifier: number + trailing_trivia: [] + else_if_expressions: + - else_if_token: + leading_trivia: [] + token: + start_position: + bytes: 335 + line: 7 + character: 41 + end_position: + bytes: 341 + line: 7 + character: 47 + token_type: + type: Symbol + symbol: elseif + trailing_trivia: + - start_position: + bytes: 341 + line: 7 + character: 47 + end_position: + bytes: 342 + line: 7 + character: 48 + token_type: + type: Whitespace + characters: " " + condition: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 342 + line: 7 + character: 48 + end_position: + bytes: 345 + line: 7 + character: 51 + token_type: + type: Identifier + identifier: bar + trailing_trivia: + - start_position: + bytes: 345 + line: 7 + character: 51 + end_position: + bytes: 346 + line: 7 + character: 52 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 346 + line: 7 + character: 52 + end_position: + bytes: 350 + line: 7 + character: 56 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 350 + line: 7 + character: 56 + end_position: + bytes: 351 + line: 7 + character: 57 + token_type: + type: Whitespace + characters: " " + expression: + FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 351 + line: 7 + character: 57 + end_position: + bytes: 354 + line: 7 + character: 60 + token_type: + type: Identifier + identifier: bar + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 354 + line: 7 + character: 60 + end_position: + bytes: 355 + line: 7 + character: 61 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 355 + line: 7 + character: 61 + end_position: + bytes: 356 + line: 7 + character: 62 + token_type: + type: Identifier + identifier: x + trailing_trivia: [] + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 356 + line: 7 + character: 62 + end_position: + bytes: 357 + line: 7 + character: 63 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 357 + line: 7 + character: 63 + end_position: + bytes: 358 + line: 7 + character: 64 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: [] + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 358 + line: 7 + character: 64 + end_position: + bytes: 359 + line: 7 + character: 65 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 359 + line: 7 + character: 65 + end_position: + bytes: 360 + line: 7 + character: 66 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 360 + line: 7 + character: 66 + end_position: + bytes: 361 + line: 7 + character: 67 + token_type: + type: Whitespace + characters: " " + arguments: + pairs: [] + else_token: + leading_trivia: [] + token: + start_position: + bytes: 361 + line: 7 + character: 67 + end_position: + bytes: 365 + line: 7 + character: 71 + token_type: + type: Symbol + symbol: else + trailing_trivia: + - start_position: + bytes: 365 + line: 7 + character: 71 + end_position: + bytes: 366 + line: 7 + character: 72 + token_type: + type: Whitespace + characters: " " + else_expression: + Number: + leading_trivia: [] + token: + start_position: + bytes: 366 + line: 7 + character: 72 + end_position: + bytes: 367 + line: 7 + character: 73 + token_type: + type: Number + text: "5" + trailing_trivia: + - start_position: + bytes: 367 + line: 7 + character: 73 + end_position: + bytes: 368 + line: 7 + character: 73 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 368 + line: 8 + character: 1 + end_position: + bytes: 373 + line: 8 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 373 + line: 8 + character: 6 + end_position: + bytes: 374 + line: 8 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 374 + line: 8 + character: 7 + end_position: + bytes: 375 + line: 8 + character: 8 + token_type: + type: Identifier + identifier: d + trailing_trivia: + - start_position: + bytes: 375 + line: 8 + character: 8 + end_position: + bytes: 376 + line: 8 + character: 9 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 376 + line: 8 + character: 9 + end_position: + bytes: 377 + line: 8 + character: 10 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 377 + line: 8 + character: 10 + end_position: + bytes: 378 + line: 8 + character: 11 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + IfExpression: + if_token: + leading_trivia: [] + token: + start_position: + bytes: 378 + line: 8 + character: 11 + end_position: + bytes: 380 + line: 8 + character: 13 + token_type: + type: Symbol + symbol: if + trailing_trivia: + - start_position: + bytes: 380 + line: 8 + character: 13 + end_position: + bytes: 381 + line: 8 + character: 14 + token_type: + type: Whitespace + characters: " " + condition: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 381 + line: 8 + character: 14 + end_position: + bytes: 384 + line: 8 + character: 17 + token_type: + type: Identifier + identifier: foo + trailing_trivia: + - start_position: + bytes: 384 + line: 8 + character: 17 + end_position: + bytes: 385 + line: 8 + character: 18 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 385 + line: 8 + character: 18 + end_position: + bytes: 389 + line: 8 + character: 22 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 389 + line: 8 + character: 22 + end_position: + bytes: 390 + line: 8 + character: 23 + token_type: + type: Whitespace + characters: " " + if_expression: + Number: + leading_trivia: [] + token: + start_position: + bytes: 390 + line: 8 + character: 23 + end_position: + bytes: 391 + line: 8 + character: 24 + token_type: + type: Number + text: "5" + trailing_trivia: + - start_position: + bytes: 391 + line: 8 + character: 24 + end_position: + bytes: 392 + line: 8 + character: 25 + token_type: + type: Whitespace + characters: " " + else_if_expressions: ~ + else_token: + leading_trivia: [] + token: + start_position: + bytes: 392 + line: 8 + character: 25 + end_position: + bytes: 396 + line: 8 + character: 29 + token_type: + type: Symbol + symbol: else + trailing_trivia: + - start_position: + bytes: 396 + line: 8 + character: 29 + end_position: + bytes: 397 + line: 8 + character: 30 + token_type: + type: Whitespace + characters: " " + else_expression: + TypeAssertion: + expression: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 397 + line: 8 + character: 30 + end_position: + bytes: 400 + line: 8 + character: 33 + token_type: + type: Identifier + identifier: baz + trailing_trivia: + - start_position: + bytes: 400 + line: 8 + character: 33 + end_position: + bytes: 401 + line: 8 + character: 34 + token_type: + type: Whitespace + characters: " " + type_assertion: + assertion_op: + leading_trivia: [] + token: + start_position: + bytes: 401 + line: 8 + character: 34 + end_position: + bytes: 403 + line: 8 + character: 36 + token_type: + type: Symbol + symbol: "::" + trailing_trivia: + - start_position: + bytes: 403 + line: 8 + character: 36 + end_position: + bytes: 404 + line: 8 + character: 37 + token_type: + type: Whitespace + characters: " " + cast_to: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 404 + line: 8 + character: 37 + end_position: + bytes: 410 + line: 8 + character: 43 + token_type: + type: Identifier + identifier: number + trailing_trivia: + - start_position: + bytes: 410 + line: 8 + character: 43 + end_position: + bytes: 411 + line: 8 + character: 43 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - If: + if_token: + leading_trivia: + - start_position: + bytes: 411 + line: 9 + character: 1 + end_position: + bytes: 412 + line: 9 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 412 + line: 10 + character: 1 + end_position: + bytes: 414 + line: 10 + character: 3 + token_type: + type: Symbol + symbol: if + trailing_trivia: + - start_position: + bytes: 414 + line: 10 + character: 3 + end_position: + bytes: 415 + line: 10 + character: 4 + token_type: + type: Whitespace + characters: " " + condition: + IfExpression: + if_token: + leading_trivia: [] + token: + start_position: + bytes: 415 + line: 10 + character: 4 + end_position: + bytes: 417 + line: 10 + character: 6 + token_type: + type: Symbol + symbol: if + trailing_trivia: + - start_position: + bytes: 417 + line: 10 + character: 6 + end_position: + bytes: 418 + line: 10 + character: 7 + token_type: + type: Whitespace + characters: " " + condition: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 418 + line: 10 + character: 7 + end_position: + bytes: 421 + line: 10 + character: 10 + token_type: + type: Identifier + identifier: foo + trailing_trivia: + - start_position: + bytes: 421 + line: 10 + character: 10 + end_position: + bytes: 422 + line: 10 + character: 11 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 422 + line: 10 + character: 11 + end_position: + bytes: 426 + line: 10 + character: 15 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 426 + line: 10 + character: 15 + end_position: + bytes: 427 + line: 10 + character: 16 + token_type: + type: Whitespace + characters: " " + if_expression: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 427 + line: 10 + character: 16 + end_position: + bytes: 430 + line: 10 + character: 19 + token_type: + type: Identifier + identifier: bar + trailing_trivia: + - start_position: + bytes: 430 + line: 10 + character: 19 + end_position: + bytes: 431 + line: 10 + character: 20 + token_type: + type: Whitespace + characters: " " + else_if_expressions: ~ + else_token: + leading_trivia: [] + token: + start_position: + bytes: 431 + line: 10 + character: 20 + end_position: + bytes: 435 + line: 10 + character: 24 + token_type: + type: Symbol + symbol: else + trailing_trivia: + - start_position: + bytes: 435 + line: 10 + character: 24 + end_position: + bytes: 436 + line: 10 + character: 25 + token_type: + type: Whitespace + characters: " " + else_expression: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 436 + line: 10 + character: 25 + end_position: + bytes: 439 + line: 10 + character: 28 + token_type: + type: Identifier + identifier: baz + trailing_trivia: + - start_position: + bytes: 439 + line: 10 + character: 28 + end_position: + bytes: 440 + line: 10 + character: 29 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 440 + line: 10 + character: 29 + end_position: + bytes: 444 + line: 10 + character: 33 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 444 + line: 10 + character: 33 + end_position: + bytes: 445 + line: 10 + character: 33 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: [] + else_if: ~ + else_token: ~ + else: ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 445 + line: 11 + character: 1 + end_position: + bytes: 448 + line: 11 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/if_expression/source.lua b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/if_expression/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..83f3860ad35b2f3bc1d7469b5b23e7f310714b1c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/if_expression/source.lua @@ -0,0 +1,11 @@ +local x = if foo then foo.x else 5 +local y = (if x then x.indices else create()):update(if shouldUpdate then information else defaults) +local z = (if bar then foo.y else 5) :: number + +local a = if foo then foo.x elseif bar then bar.x else 5 +local b = if foo then if bar then bar else foo else 5 +local c = if foo then (foo.x :: number) elseif bar then bar.x()() else 5 +local d = if foo then 5 else baz :: number + +if if foo then bar else baz then +end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/if_expression/tokens.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/if_expression/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..f385aa3883f7d4a7b5304c7b4cb26695df3c0acd --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/if_expression/tokens.snap @@ -0,0 +1,2480 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: if +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 22 + line: 1 + character: 23 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 26 + line: 1 + character: 27 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 26 + line: 1 + character: 27 + end_position: + bytes: 27 + line: 1 + character: 28 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 27 + line: 1 + character: 28 + end_position: + bytes: 28 + line: 1 + character: 29 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 28 + line: 1 + character: 29 + end_position: + bytes: 32 + line: 1 + character: 33 + token_type: + type: Symbol + symbol: else +- start_position: + bytes: 32 + line: 1 + character: 33 + end_position: + bytes: 33 + line: 1 + character: 34 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 33 + line: 1 + character: 34 + end_position: + bytes: 34 + line: 1 + character: 35 + token_type: + type: Number + text: "5" +- start_position: + bytes: 34 + line: 1 + character: 35 + end_position: + bytes: 35 + line: 1 + character: 35 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 35 + line: 2 + character: 1 + end_position: + bytes: 40 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 40 + line: 2 + character: 6 + end_position: + bytes: 41 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 41 + line: 2 + character: 7 + end_position: + bytes: 42 + line: 2 + character: 8 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 42 + line: 2 + character: 8 + end_position: + bytes: 43 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 43 + line: 2 + character: 9 + end_position: + bytes: 44 + line: 2 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 44 + line: 2 + character: 10 + end_position: + bytes: 45 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 45 + line: 2 + character: 11 + end_position: + bytes: 46 + line: 2 + character: 12 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 46 + line: 2 + character: 12 + end_position: + bytes: 48 + line: 2 + character: 14 + token_type: + type: Symbol + symbol: if +- start_position: + bytes: 48 + line: 2 + character: 14 + end_position: + bytes: 49 + line: 2 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 49 + line: 2 + character: 15 + end_position: + bytes: 50 + line: 2 + character: 16 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 50 + line: 2 + character: 16 + end_position: + bytes: 51 + line: 2 + character: 17 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 51 + line: 2 + character: 17 + end_position: + bytes: 55 + line: 2 + character: 21 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 55 + line: 2 + character: 21 + end_position: + bytes: 56 + line: 2 + character: 22 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 56 + line: 2 + character: 22 + end_position: + bytes: 57 + line: 2 + character: 23 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 57 + line: 2 + character: 23 + end_position: + bytes: 58 + line: 2 + character: 24 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 58 + line: 2 + character: 24 + end_position: + bytes: 65 + line: 2 + character: 31 + token_type: + type: Identifier + identifier: indices +- start_position: + bytes: 65 + line: 2 + character: 31 + end_position: + bytes: 66 + line: 2 + character: 32 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 66 + line: 2 + character: 32 + end_position: + bytes: 70 + line: 2 + character: 36 + token_type: + type: Symbol + symbol: else +- start_position: + bytes: 70 + line: 2 + character: 36 + end_position: + bytes: 71 + line: 2 + character: 37 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 71 + line: 2 + character: 37 + end_position: + bytes: 77 + line: 2 + character: 43 + token_type: + type: Identifier + identifier: create +- start_position: + bytes: 77 + line: 2 + character: 43 + end_position: + bytes: 78 + line: 2 + character: 44 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 78 + line: 2 + character: 44 + end_position: + bytes: 79 + line: 2 + character: 45 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 79 + line: 2 + character: 45 + end_position: + bytes: 80 + line: 2 + character: 46 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 80 + line: 2 + character: 46 + end_position: + bytes: 81 + line: 2 + character: 47 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 81 + line: 2 + character: 47 + end_position: + bytes: 87 + line: 2 + character: 53 + token_type: + type: Identifier + identifier: update +- start_position: + bytes: 87 + line: 2 + character: 53 + end_position: + bytes: 88 + line: 2 + character: 54 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 88 + line: 2 + character: 54 + end_position: + bytes: 90 + line: 2 + character: 56 + token_type: + type: Symbol + symbol: if +- start_position: + bytes: 90 + line: 2 + character: 56 + end_position: + bytes: 91 + line: 2 + character: 57 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 91 + line: 2 + character: 57 + end_position: + bytes: 103 + line: 2 + character: 69 + token_type: + type: Identifier + identifier: shouldUpdate +- start_position: + bytes: 103 + line: 2 + character: 69 + end_position: + bytes: 104 + line: 2 + character: 70 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 104 + line: 2 + character: 70 + end_position: + bytes: 108 + line: 2 + character: 74 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 108 + line: 2 + character: 74 + end_position: + bytes: 109 + line: 2 + character: 75 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 109 + line: 2 + character: 75 + end_position: + bytes: 120 + line: 2 + character: 86 + token_type: + type: Identifier + identifier: information +- start_position: + bytes: 120 + line: 2 + character: 86 + end_position: + bytes: 121 + line: 2 + character: 87 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 121 + line: 2 + character: 87 + end_position: + bytes: 125 + line: 2 + character: 91 + token_type: + type: Symbol + symbol: else +- start_position: + bytes: 125 + line: 2 + character: 91 + end_position: + bytes: 126 + line: 2 + character: 92 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 126 + line: 2 + character: 92 + end_position: + bytes: 134 + line: 2 + character: 100 + token_type: + type: Identifier + identifier: defaults +- start_position: + bytes: 134 + line: 2 + character: 100 + end_position: + bytes: 135 + line: 2 + character: 101 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 135 + line: 2 + character: 101 + end_position: + bytes: 136 + line: 2 + character: 101 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 136 + line: 3 + character: 1 + end_position: + bytes: 141 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 141 + line: 3 + character: 6 + end_position: + bytes: 142 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 142 + line: 3 + character: 7 + end_position: + bytes: 143 + line: 3 + character: 8 + token_type: + type: Identifier + identifier: z +- start_position: + bytes: 143 + line: 3 + character: 8 + end_position: + bytes: 144 + line: 3 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 144 + line: 3 + character: 9 + end_position: + bytes: 145 + line: 3 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 145 + line: 3 + character: 10 + end_position: + bytes: 146 + line: 3 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 146 + line: 3 + character: 11 + end_position: + bytes: 147 + line: 3 + character: 12 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 147 + line: 3 + character: 12 + end_position: + bytes: 149 + line: 3 + character: 14 + token_type: + type: Symbol + symbol: if +- start_position: + bytes: 149 + line: 3 + character: 14 + end_position: + bytes: 150 + line: 3 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 150 + line: 3 + character: 15 + end_position: + bytes: 153 + line: 3 + character: 18 + token_type: + type: Identifier + identifier: bar +- start_position: + bytes: 153 + line: 3 + character: 18 + end_position: + bytes: 154 + line: 3 + character: 19 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 154 + line: 3 + character: 19 + end_position: + bytes: 158 + line: 3 + character: 23 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 158 + line: 3 + character: 23 + end_position: + bytes: 159 + line: 3 + character: 24 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 159 + line: 3 + character: 24 + end_position: + bytes: 162 + line: 3 + character: 27 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 162 + line: 3 + character: 27 + end_position: + bytes: 163 + line: 3 + character: 28 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 163 + line: 3 + character: 28 + end_position: + bytes: 164 + line: 3 + character: 29 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 164 + line: 3 + character: 29 + end_position: + bytes: 165 + line: 3 + character: 30 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 165 + line: 3 + character: 30 + end_position: + bytes: 169 + line: 3 + character: 34 + token_type: + type: Symbol + symbol: else +- start_position: + bytes: 169 + line: 3 + character: 34 + end_position: + bytes: 170 + line: 3 + character: 35 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 170 + line: 3 + character: 35 + end_position: + bytes: 171 + line: 3 + character: 36 + token_type: + type: Number + text: "5" +- start_position: + bytes: 171 + line: 3 + character: 36 + end_position: + bytes: 172 + line: 3 + character: 37 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 172 + line: 3 + character: 37 + end_position: + bytes: 173 + line: 3 + character: 38 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 173 + line: 3 + character: 38 + end_position: + bytes: 175 + line: 3 + character: 40 + token_type: + type: Symbol + symbol: "::" +- start_position: + bytes: 175 + line: 3 + character: 40 + end_position: + bytes: 176 + line: 3 + character: 41 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 176 + line: 3 + character: 41 + end_position: + bytes: 182 + line: 3 + character: 47 + token_type: + type: Identifier + identifier: number +- start_position: + bytes: 182 + line: 3 + character: 47 + end_position: + bytes: 183 + line: 3 + character: 47 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 183 + line: 4 + character: 1 + end_position: + bytes: 184 + line: 4 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 184 + line: 5 + character: 1 + end_position: + bytes: 189 + line: 5 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 189 + line: 5 + character: 6 + end_position: + bytes: 190 + line: 5 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 190 + line: 5 + character: 7 + end_position: + bytes: 191 + line: 5 + character: 8 + token_type: + type: Identifier + identifier: a +- start_position: + bytes: 191 + line: 5 + character: 8 + end_position: + bytes: 192 + line: 5 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 192 + line: 5 + character: 9 + end_position: + bytes: 193 + line: 5 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 193 + line: 5 + character: 10 + end_position: + bytes: 194 + line: 5 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 194 + line: 5 + character: 11 + end_position: + bytes: 196 + line: 5 + character: 13 + token_type: + type: Symbol + symbol: if +- start_position: + bytes: 196 + line: 5 + character: 13 + end_position: + bytes: 197 + line: 5 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 197 + line: 5 + character: 14 + end_position: + bytes: 200 + line: 5 + character: 17 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 200 + line: 5 + character: 17 + end_position: + bytes: 201 + line: 5 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 201 + line: 5 + character: 18 + end_position: + bytes: 205 + line: 5 + character: 22 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 205 + line: 5 + character: 22 + end_position: + bytes: 206 + line: 5 + character: 23 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 206 + line: 5 + character: 23 + end_position: + bytes: 209 + line: 5 + character: 26 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 209 + line: 5 + character: 26 + end_position: + bytes: 210 + line: 5 + character: 27 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 210 + line: 5 + character: 27 + end_position: + bytes: 211 + line: 5 + character: 28 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 211 + line: 5 + character: 28 + end_position: + bytes: 212 + line: 5 + character: 29 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 212 + line: 5 + character: 29 + end_position: + bytes: 218 + line: 5 + character: 35 + token_type: + type: Symbol + symbol: elseif +- start_position: + bytes: 218 + line: 5 + character: 35 + end_position: + bytes: 219 + line: 5 + character: 36 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 219 + line: 5 + character: 36 + end_position: + bytes: 222 + line: 5 + character: 39 + token_type: + type: Identifier + identifier: bar +- start_position: + bytes: 222 + line: 5 + character: 39 + end_position: + bytes: 223 + line: 5 + character: 40 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 223 + line: 5 + character: 40 + end_position: + bytes: 227 + line: 5 + character: 44 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 227 + line: 5 + character: 44 + end_position: + bytes: 228 + line: 5 + character: 45 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 228 + line: 5 + character: 45 + end_position: + bytes: 231 + line: 5 + character: 48 + token_type: + type: Identifier + identifier: bar +- start_position: + bytes: 231 + line: 5 + character: 48 + end_position: + bytes: 232 + line: 5 + character: 49 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 232 + line: 5 + character: 49 + end_position: + bytes: 233 + line: 5 + character: 50 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 233 + line: 5 + character: 50 + end_position: + bytes: 234 + line: 5 + character: 51 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 234 + line: 5 + character: 51 + end_position: + bytes: 238 + line: 5 + character: 55 + token_type: + type: Symbol + symbol: else +- start_position: + bytes: 238 + line: 5 + character: 55 + end_position: + bytes: 239 + line: 5 + character: 56 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 239 + line: 5 + character: 56 + end_position: + bytes: 240 + line: 5 + character: 57 + token_type: + type: Number + text: "5" +- start_position: + bytes: 240 + line: 5 + character: 57 + end_position: + bytes: 241 + line: 5 + character: 57 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 241 + line: 6 + character: 1 + end_position: + bytes: 246 + line: 6 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 246 + line: 6 + character: 6 + end_position: + bytes: 247 + line: 6 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 247 + line: 6 + character: 7 + end_position: + bytes: 248 + line: 6 + character: 8 + token_type: + type: Identifier + identifier: b +- start_position: + bytes: 248 + line: 6 + character: 8 + end_position: + bytes: 249 + line: 6 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 249 + line: 6 + character: 9 + end_position: + bytes: 250 + line: 6 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 250 + line: 6 + character: 10 + end_position: + bytes: 251 + line: 6 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 251 + line: 6 + character: 11 + end_position: + bytes: 253 + line: 6 + character: 13 + token_type: + type: Symbol + symbol: if +- start_position: + bytes: 253 + line: 6 + character: 13 + end_position: + bytes: 254 + line: 6 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 254 + line: 6 + character: 14 + end_position: + bytes: 257 + line: 6 + character: 17 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 257 + line: 6 + character: 17 + end_position: + bytes: 258 + line: 6 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 258 + line: 6 + character: 18 + end_position: + bytes: 262 + line: 6 + character: 22 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 262 + line: 6 + character: 22 + end_position: + bytes: 263 + line: 6 + character: 23 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 263 + line: 6 + character: 23 + end_position: + bytes: 265 + line: 6 + character: 25 + token_type: + type: Symbol + symbol: if +- start_position: + bytes: 265 + line: 6 + character: 25 + end_position: + bytes: 266 + line: 6 + character: 26 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 266 + line: 6 + character: 26 + end_position: + bytes: 269 + line: 6 + character: 29 + token_type: + type: Identifier + identifier: bar +- start_position: + bytes: 269 + line: 6 + character: 29 + end_position: + bytes: 270 + line: 6 + character: 30 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 270 + line: 6 + character: 30 + end_position: + bytes: 274 + line: 6 + character: 34 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 274 + line: 6 + character: 34 + end_position: + bytes: 275 + line: 6 + character: 35 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 275 + line: 6 + character: 35 + end_position: + bytes: 278 + line: 6 + character: 38 + token_type: + type: Identifier + identifier: bar +- start_position: + bytes: 278 + line: 6 + character: 38 + end_position: + bytes: 279 + line: 6 + character: 39 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 279 + line: 6 + character: 39 + end_position: + bytes: 283 + line: 6 + character: 43 + token_type: + type: Symbol + symbol: else +- start_position: + bytes: 283 + line: 6 + character: 43 + end_position: + bytes: 284 + line: 6 + character: 44 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 284 + line: 6 + character: 44 + end_position: + bytes: 287 + line: 6 + character: 47 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 287 + line: 6 + character: 47 + end_position: + bytes: 288 + line: 6 + character: 48 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 288 + line: 6 + character: 48 + end_position: + bytes: 292 + line: 6 + character: 52 + token_type: + type: Symbol + symbol: else +- start_position: + bytes: 292 + line: 6 + character: 52 + end_position: + bytes: 293 + line: 6 + character: 53 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 293 + line: 6 + character: 53 + end_position: + bytes: 294 + line: 6 + character: 54 + token_type: + type: Number + text: "5" +- start_position: + bytes: 294 + line: 6 + character: 54 + end_position: + bytes: 295 + line: 6 + character: 54 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 295 + line: 7 + character: 1 + end_position: + bytes: 300 + line: 7 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 300 + line: 7 + character: 6 + end_position: + bytes: 301 + line: 7 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 301 + line: 7 + character: 7 + end_position: + bytes: 302 + line: 7 + character: 8 + token_type: + type: Identifier + identifier: c +- start_position: + bytes: 302 + line: 7 + character: 8 + end_position: + bytes: 303 + line: 7 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 303 + line: 7 + character: 9 + end_position: + bytes: 304 + line: 7 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 304 + line: 7 + character: 10 + end_position: + bytes: 305 + line: 7 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 305 + line: 7 + character: 11 + end_position: + bytes: 307 + line: 7 + character: 13 + token_type: + type: Symbol + symbol: if +- start_position: + bytes: 307 + line: 7 + character: 13 + end_position: + bytes: 308 + line: 7 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 308 + line: 7 + character: 14 + end_position: + bytes: 311 + line: 7 + character: 17 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 311 + line: 7 + character: 17 + end_position: + bytes: 312 + line: 7 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 312 + line: 7 + character: 18 + end_position: + bytes: 316 + line: 7 + character: 22 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 316 + line: 7 + character: 22 + end_position: + bytes: 317 + line: 7 + character: 23 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 317 + line: 7 + character: 23 + end_position: + bytes: 318 + line: 7 + character: 24 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 318 + line: 7 + character: 24 + end_position: + bytes: 321 + line: 7 + character: 27 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 321 + line: 7 + character: 27 + end_position: + bytes: 322 + line: 7 + character: 28 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 322 + line: 7 + character: 28 + end_position: + bytes: 323 + line: 7 + character: 29 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 323 + line: 7 + character: 29 + end_position: + bytes: 324 + line: 7 + character: 30 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 324 + line: 7 + character: 30 + end_position: + bytes: 326 + line: 7 + character: 32 + token_type: + type: Symbol + symbol: "::" +- start_position: + bytes: 326 + line: 7 + character: 32 + end_position: + bytes: 327 + line: 7 + character: 33 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 327 + line: 7 + character: 33 + end_position: + bytes: 333 + line: 7 + character: 39 + token_type: + type: Identifier + identifier: number +- start_position: + bytes: 333 + line: 7 + character: 39 + end_position: + bytes: 334 + line: 7 + character: 40 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 334 + line: 7 + character: 40 + end_position: + bytes: 335 + line: 7 + character: 41 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 335 + line: 7 + character: 41 + end_position: + bytes: 341 + line: 7 + character: 47 + token_type: + type: Symbol + symbol: elseif +- start_position: + bytes: 341 + line: 7 + character: 47 + end_position: + bytes: 342 + line: 7 + character: 48 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 342 + line: 7 + character: 48 + end_position: + bytes: 345 + line: 7 + character: 51 + token_type: + type: Identifier + identifier: bar +- start_position: + bytes: 345 + line: 7 + character: 51 + end_position: + bytes: 346 + line: 7 + character: 52 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 346 + line: 7 + character: 52 + end_position: + bytes: 350 + line: 7 + character: 56 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 350 + line: 7 + character: 56 + end_position: + bytes: 351 + line: 7 + character: 57 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 351 + line: 7 + character: 57 + end_position: + bytes: 354 + line: 7 + character: 60 + token_type: + type: Identifier + identifier: bar +- start_position: + bytes: 354 + line: 7 + character: 60 + end_position: + bytes: 355 + line: 7 + character: 61 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 355 + line: 7 + character: 61 + end_position: + bytes: 356 + line: 7 + character: 62 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 356 + line: 7 + character: 62 + end_position: + bytes: 357 + line: 7 + character: 63 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 357 + line: 7 + character: 63 + end_position: + bytes: 358 + line: 7 + character: 64 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 358 + line: 7 + character: 64 + end_position: + bytes: 359 + line: 7 + character: 65 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 359 + line: 7 + character: 65 + end_position: + bytes: 360 + line: 7 + character: 66 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 360 + line: 7 + character: 66 + end_position: + bytes: 361 + line: 7 + character: 67 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 361 + line: 7 + character: 67 + end_position: + bytes: 365 + line: 7 + character: 71 + token_type: + type: Symbol + symbol: else +- start_position: + bytes: 365 + line: 7 + character: 71 + end_position: + bytes: 366 + line: 7 + character: 72 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 366 + line: 7 + character: 72 + end_position: + bytes: 367 + line: 7 + character: 73 + token_type: + type: Number + text: "5" +- start_position: + bytes: 367 + line: 7 + character: 73 + end_position: + bytes: 368 + line: 7 + character: 73 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 368 + line: 8 + character: 1 + end_position: + bytes: 373 + line: 8 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 373 + line: 8 + character: 6 + end_position: + bytes: 374 + line: 8 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 374 + line: 8 + character: 7 + end_position: + bytes: 375 + line: 8 + character: 8 + token_type: + type: Identifier + identifier: d +- start_position: + bytes: 375 + line: 8 + character: 8 + end_position: + bytes: 376 + line: 8 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 376 + line: 8 + character: 9 + end_position: + bytes: 377 + line: 8 + character: 10 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 377 + line: 8 + character: 10 + end_position: + bytes: 378 + line: 8 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 378 + line: 8 + character: 11 + end_position: + bytes: 380 + line: 8 + character: 13 + token_type: + type: Symbol + symbol: if +- start_position: + bytes: 380 + line: 8 + character: 13 + end_position: + bytes: 381 + line: 8 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 381 + line: 8 + character: 14 + end_position: + bytes: 384 + line: 8 + character: 17 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 384 + line: 8 + character: 17 + end_position: + bytes: 385 + line: 8 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 385 + line: 8 + character: 18 + end_position: + bytes: 389 + line: 8 + character: 22 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 389 + line: 8 + character: 22 + end_position: + bytes: 390 + line: 8 + character: 23 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 390 + line: 8 + character: 23 + end_position: + bytes: 391 + line: 8 + character: 24 + token_type: + type: Number + text: "5" +- start_position: + bytes: 391 + line: 8 + character: 24 + end_position: + bytes: 392 + line: 8 + character: 25 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 392 + line: 8 + character: 25 + end_position: + bytes: 396 + line: 8 + character: 29 + token_type: + type: Symbol + symbol: else +- start_position: + bytes: 396 + line: 8 + character: 29 + end_position: + bytes: 397 + line: 8 + character: 30 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 397 + line: 8 + character: 30 + end_position: + bytes: 400 + line: 8 + character: 33 + token_type: + type: Identifier + identifier: baz +- start_position: + bytes: 400 + line: 8 + character: 33 + end_position: + bytes: 401 + line: 8 + character: 34 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 401 + line: 8 + character: 34 + end_position: + bytes: 403 + line: 8 + character: 36 + token_type: + type: Symbol + symbol: "::" +- start_position: + bytes: 403 + line: 8 + character: 36 + end_position: + bytes: 404 + line: 8 + character: 37 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 404 + line: 8 + character: 37 + end_position: + bytes: 410 + line: 8 + character: 43 + token_type: + type: Identifier + identifier: number +- start_position: + bytes: 410 + line: 8 + character: 43 + end_position: + bytes: 411 + line: 8 + character: 43 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 411 + line: 9 + character: 1 + end_position: + bytes: 412 + line: 9 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 412 + line: 10 + character: 1 + end_position: + bytes: 414 + line: 10 + character: 3 + token_type: + type: Symbol + symbol: if +- start_position: + bytes: 414 + line: 10 + character: 3 + end_position: + bytes: 415 + line: 10 + character: 4 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 415 + line: 10 + character: 4 + end_position: + bytes: 417 + line: 10 + character: 6 + token_type: + type: Symbol + symbol: if +- start_position: + bytes: 417 + line: 10 + character: 6 + end_position: + bytes: 418 + line: 10 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 418 + line: 10 + character: 7 + end_position: + bytes: 421 + line: 10 + character: 10 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 421 + line: 10 + character: 10 + end_position: + bytes: 422 + line: 10 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 422 + line: 10 + character: 11 + end_position: + bytes: 426 + line: 10 + character: 15 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 426 + line: 10 + character: 15 + end_position: + bytes: 427 + line: 10 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 427 + line: 10 + character: 16 + end_position: + bytes: 430 + line: 10 + character: 19 + token_type: + type: Identifier + identifier: bar +- start_position: + bytes: 430 + line: 10 + character: 19 + end_position: + bytes: 431 + line: 10 + character: 20 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 431 + line: 10 + character: 20 + end_position: + bytes: 435 + line: 10 + character: 24 + token_type: + type: Symbol + symbol: else +- start_position: + bytes: 435 + line: 10 + character: 24 + end_position: + bytes: 436 + line: 10 + character: 25 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 436 + line: 10 + character: 25 + end_position: + bytes: 439 + line: 10 + character: 28 + token_type: + type: Identifier + identifier: baz +- start_position: + bytes: 439 + line: 10 + character: 28 + end_position: + bytes: 440 + line: 10 + character: 29 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 440 + line: 10 + character: 29 + end_position: + bytes: 444 + line: 10 + character: 33 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 444 + line: 10 + character: 33 + end_position: + bytes: 445 + line: 10 + character: 33 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 445 + line: 11 + character: 1 + end_position: + bytes: 448 + line: 11 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 448 + line: 11 + character: 4 + end_position: + bytes: 448 + line: 11 + character: 4 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/multiline_expressions/ast.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/multiline_expressions/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..bb4e51de24fd4f343a127ca345c8273ec537c5c7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/multiline_expressions/ast.snap @@ -0,0 +1,2231 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +input_file: full-moon/tests/roblox_cases/pass/multiline_expressions +--- +stmts: + - - Do: + do_token: + leading_trivia: + - start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 104 + line: 1 + character: 105 + token_type: + type: SingleLineComment + comment: " Taken from https://github.com/JohnnyMorganz/StyLua/blob/main/tests/inputs/multiline-expressions-3.lua" + - start_position: + bytes: 104 + line: 1 + character: 105 + end_position: + bytes: 105 + line: 1 + character: 105 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 105 + line: 2 + character: 1 + end_position: + bytes: 107 + line: 2 + character: 3 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 107 + line: 2 + character: 3 + end_position: + bytes: 108 + line: 2 + character: 3 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - Do: + do_token: + leading_trivia: + - start_position: + bytes: 108 + line: 3 + character: 1 + end_position: + bytes: 109 + line: 3 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 109 + line: 3 + character: 2 + end_position: + bytes: 111 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 111 + line: 3 + character: 4 + end_position: + bytes: 112 + line: 3 + character: 4 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - Do: + do_token: + leading_trivia: + - start_position: + bytes: 112 + line: 4 + character: 1 + end_position: + bytes: 114 + line: 4 + character: 3 + token_type: + type: Whitespace + characters: "\t\t" + token: + start_position: + bytes: 114 + line: 4 + character: 3 + end_position: + bytes: 116 + line: 4 + character: 5 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 116 + line: 4 + character: 5 + end_position: + bytes: 117 + line: 4 + character: 5 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - Do: + do_token: + leading_trivia: + - start_position: + bytes: 117 + line: 5 + character: 1 + end_position: + bytes: 120 + line: 5 + character: 4 + token_type: + type: Whitespace + characters: "\t\t\t" + token: + start_position: + bytes: 120 + line: 5 + character: 4 + end_position: + bytes: 122 + line: 5 + character: 6 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 122 + line: 5 + character: 6 + end_position: + bytes: 123 + line: 5 + character: 6 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - LocalAssignment: + local_token: + leading_trivia: + - start_position: + bytes: 123 + line: 6 + character: 1 + end_position: + bytes: 127 + line: 6 + character: 5 + token_type: + type: Whitespace + characters: "\t\t\t\t" + token: + start_position: + bytes: 127 + line: 6 + character: 5 + end_position: + bytes: 132 + line: 6 + character: 10 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 132 + line: 6 + character: 10 + end_position: + bytes: 133 + line: 6 + character: 11 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 133 + line: 6 + character: 11 + end_position: + bytes: 137 + line: 6 + character: 15 + token_type: + type: Identifier + identifier: text + trailing_trivia: + - start_position: + bytes: 137 + line: 6 + character: 15 + end_position: + bytes: 138 + line: 6 + character: 16 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 138 + line: 6 + character: 16 + end_position: + bytes: 139 + line: 6 + character: 17 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 139 + line: 6 + character: 17 + end_position: + bytes: 140 + line: 6 + character: 18 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + BinaryOperator: + lhs: + String: + leading_trivia: [] + token: + start_position: + bytes: 140 + line: 6 + character: 18 + end_position: + bytes: 151 + line: 6 + character: 29 + token_type: + type: StringLiteral + literal: "Players: " + quote_type: Double + trailing_trivia: + - start_position: + bytes: 151 + line: 6 + character: 29 + end_position: + bytes: 152 + line: 6 + character: 30 + token_type: + type: Whitespace + characters: " " + binop: + TwoDots: + leading_trivia: [] + token: + start_position: + bytes: 152 + line: 6 + character: 30 + end_position: + bytes: 154 + line: 6 + character: 32 + token_type: + type: Symbol + symbol: ".." + trailing_trivia: + - start_position: + bytes: 154 + line: 6 + character: 32 + end_position: + bytes: 155 + line: 6 + character: 33 + token_type: + type: Whitespace + characters: " " + rhs: + BinaryOperator: + lhs: + BinaryOperator: + lhs: + UnaryOperator: + unop: + Hash: + leading_trivia: [] + token: + start_position: + bytes: 155 + line: 6 + character: 33 + end_position: + bytes: 156 + line: 6 + character: 34 + token_type: + type: Symbol + symbol: "#" + trailing_trivia: [] + expression: + FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 156 + line: 6 + character: 34 + end_position: + bytes: 172 + line: 6 + character: 50 + token_type: + type: Identifier + identifier: Server_Container + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 172 + line: 6 + character: 50 + end_position: + bytes: 173 + line: 6 + character: 51 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 173 + line: 6 + character: 51 + end_position: + bytes: 235 + line: 6 + character: 113 + token_type: + type: Identifier + identifier: ARandomVariableWhichIsVeryLongSoThatThisGetsOverTheColumnLimit + trailing_trivia: [] + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 235 + line: 6 + character: 113 + end_position: + bytes: 236 + line: 6 + character: 114 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 236 + line: 6 + character: 114 + end_position: + bytes: 245 + line: 6 + character: 123 + token_type: + type: Identifier + identifier: Players_F + trailing_trivia: [] + - Call: + MethodCall: + colon_token: + leading_trivia: [] + token: + start_position: + bytes: 245 + line: 6 + character: 123 + end_position: + bytes: 246 + line: 6 + character: 124 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 246 + line: 6 + character: 124 + end_position: + bytes: 257 + line: 6 + character: 135 + token_type: + type: Identifier + identifier: GetChildren + trailing_trivia: [] + args: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 257 + line: 6 + character: 135 + end_position: + bytes: 258 + line: 6 + character: 136 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 258 + line: 6 + character: 136 + end_position: + bytes: 259 + line: 6 + character: 137 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 259 + line: 6 + character: 137 + end_position: + bytes: 260 + line: 6 + character: 138 + token_type: + type: Whitespace + characters: " " + arguments: + pairs: [] + binop: + Minus: + leading_trivia: [] + token: + start_position: + bytes: 260 + line: 6 + character: 138 + end_position: + bytes: 261 + line: 6 + character: 139 + token_type: + type: Symbol + symbol: "-" + trailing_trivia: + - start_position: + bytes: 261 + line: 6 + character: 139 + end_position: + bytes: 262 + line: 6 + character: 140 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 262 + line: 6 + character: 140 + end_position: + bytes: 263 + line: 6 + character: 141 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 263 + line: 6 + character: 141 + end_position: + bytes: 264 + line: 6 + character: 142 + token_type: + type: Whitespace + characters: " " + binop: + TwoDots: + leading_trivia: [] + token: + start_position: + bytes: 264 + line: 6 + character: 142 + end_position: + bytes: 266 + line: 6 + character: 144 + token_type: + type: Symbol + symbol: ".." + trailing_trivia: + - start_position: + bytes: 266 + line: 6 + character: 144 + end_position: + bytes: 267 + line: 6 + character: 145 + token_type: + type: Whitespace + characters: " " + rhs: + String: + leading_trivia: [] + token: + start_position: + bytes: 267 + line: 6 + character: 145 + end_position: + bytes: 272 + line: 6 + character: 150 + token_type: + type: StringLiteral + literal: /20 + quote_type: Double + trailing_trivia: + - start_position: + bytes: 272 + line: 6 + character: 150 + end_position: + bytes: 273 + line: 6 + character: 150 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: + - start_position: + bytes: 273 + line: 7 + character: 1 + end_position: + bytes: 277 + line: 7 + character: 5 + token_type: + type: Whitespace + characters: "\t\t\t\t" + token: + start_position: + bytes: 277 + line: 7 + character: 5 + end_position: + bytes: 282 + line: 7 + character: 10 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 282 + line: 7 + character: 10 + end_position: + bytes: 283 + line: 7 + character: 11 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 283 + line: 7 + character: 11 + end_position: + bytes: 288 + line: 7 + character: 16 + token_type: + type: Identifier + identifier: ratio + trailing_trivia: + - start_position: + bytes: 288 + line: 7 + character: 16 + end_position: + bytes: 289 + line: 7 + character: 17 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 289 + line: 7 + character: 17 + end_position: + bytes: 290 + line: 7 + character: 18 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 290 + line: 7 + character: 18 + end_position: + bytes: 291 + line: 7 + character: 19 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + BinaryOperator: + lhs: + BinaryOperator: + lhs: + BinaryOperator: + lhs: + Parentheses: + contained: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 291 + line: 7 + character: 19 + end_position: + bytes: 292 + line: 7 + character: 20 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 313 + line: 7 + character: 41 + end_position: + bytes: 314 + line: 7 + character: 42 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 314 + line: 7 + character: 42 + end_position: + bytes: 315 + line: 7 + character: 43 + token_type: + type: Whitespace + characters: " " + expression: + BinaryOperator: + lhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 292 + line: 7 + character: 20 + end_position: + bytes: 299 + line: 7 + character: 27 + token_type: + type: Identifier + identifier: minAxis + trailing_trivia: + - start_position: + bytes: 299 + line: 7 + character: 27 + end_position: + bytes: 300 + line: 7 + character: 28 + token_type: + type: Whitespace + characters: " " + binop: + Minus: + leading_trivia: [] + token: + start_position: + bytes: 300 + line: 7 + character: 28 + end_position: + bytes: 301 + line: 7 + character: 29 + token_type: + type: Symbol + symbol: "-" + trailing_trivia: + - start_position: + bytes: 301 + line: 7 + character: 29 + end_position: + bytes: 302 + line: 7 + character: 30 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 302 + line: 7 + character: 30 + end_position: + bytes: 313 + line: 7 + character: 41 + token_type: + type: Identifier + identifier: minAxisSize + trailing_trivia: [] + binop: + Slash: + leading_trivia: [] + token: + start_position: + bytes: 315 + line: 7 + character: 43 + end_position: + bytes: 316 + line: 7 + character: 44 + token_type: + type: Symbol + symbol: / + trailing_trivia: + - start_position: + bytes: 316 + line: 7 + character: 44 + end_position: + bytes: 317 + line: 7 + character: 45 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 317 + line: 7 + character: 45 + end_position: + bytes: 322 + line: 7 + character: 50 + token_type: + type: Identifier + identifier: delta + trailing_trivia: + - start_position: + bytes: 322 + line: 7 + character: 50 + end_position: + bytes: 323 + line: 7 + character: 51 + token_type: + type: Whitespace + characters: " " + binop: + Star: + leading_trivia: [] + token: + start_position: + bytes: 323 + line: 7 + character: 51 + end_position: + bytes: 324 + line: 7 + character: 52 + token_type: + type: Symbol + symbol: "*" + trailing_trivia: + - start_position: + bytes: 324 + line: 7 + character: 52 + end_position: + bytes: 325 + line: 7 + character: 53 + token_type: + type: Whitespace + characters: " " + rhs: + Parentheses: + contained: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 325 + line: 7 + character: 53 + end_position: + bytes: 326 + line: 7 + character: 54 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 377 + line: 7 + character: 105 + end_position: + bytes: 378 + line: 7 + character: 106 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 378 + line: 7 + character: 106 + end_position: + bytes: 379 + line: 7 + character: 107 + token_type: + type: Whitespace + characters: " " + expression: + BinaryOperator: + lhs: + Var: + Expression: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 326 + line: 7 + character: 54 + end_position: + bytes: 330 + line: 7 + character: 58 + token_type: + type: Identifier + identifier: self + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 330 + line: 7 + character: 58 + end_position: + bytes: 331 + line: 7 + character: 59 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 331 + line: 7 + character: 59 + end_position: + bytes: 336 + line: 7 + character: 64 + token_type: + type: Identifier + identifier: props + trailing_trivia: [] + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 336 + line: 7 + character: 64 + end_position: + bytes: 337 + line: 7 + character: 65 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 337 + line: 7 + character: 65 + end_position: + bytes: 350 + line: 7 + character: 78 + token_type: + type: Identifier + identifier: maxScaleRatio + trailing_trivia: + - start_position: + bytes: 350 + line: 7 + character: 78 + end_position: + bytes: 351 + line: 7 + character: 79 + token_type: + type: Whitespace + characters: " " + binop: + Minus: + leading_trivia: [] + token: + start_position: + bytes: 351 + line: 7 + character: 79 + end_position: + bytes: 352 + line: 7 + character: 80 + token_type: + type: Symbol + symbol: "-" + trailing_trivia: + - start_position: + bytes: 352 + line: 7 + character: 80 + end_position: + bytes: 353 + line: 7 + character: 81 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Expression: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 353 + line: 7 + character: 81 + end_position: + bytes: 357 + line: 7 + character: 85 + token_type: + type: Identifier + identifier: self + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 357 + line: 7 + character: 85 + end_position: + bytes: 358 + line: 7 + character: 86 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 358 + line: 7 + character: 86 + end_position: + bytes: 363 + line: 7 + character: 91 + token_type: + type: Identifier + identifier: props + trailing_trivia: [] + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 363 + line: 7 + character: 91 + end_position: + bytes: 364 + line: 7 + character: 92 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 364 + line: 7 + character: 92 + end_position: + bytes: 377 + line: 7 + character: 105 + token_type: + type: Identifier + identifier: minScaleRatio + trailing_trivia: [] + binop: + Plus: + leading_trivia: [] + token: + start_position: + bytes: 379 + line: 7 + character: 107 + end_position: + bytes: 380 + line: 7 + character: 108 + token_type: + type: Symbol + symbol: + + trailing_trivia: + - start_position: + bytes: 380 + line: 7 + character: 108 + end_position: + bytes: 381 + line: 7 + character: 109 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Expression: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 381 + line: 7 + character: 109 + end_position: + bytes: 385 + line: 7 + character: 113 + token_type: + type: Identifier + identifier: self + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 385 + line: 7 + character: 113 + end_position: + bytes: 386 + line: 7 + character: 114 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 386 + line: 7 + character: 114 + end_position: + bytes: 391 + line: 7 + character: 119 + token_type: + type: Identifier + identifier: props + trailing_trivia: [] + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 391 + line: 7 + character: 119 + end_position: + bytes: 392 + line: 7 + character: 120 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 392 + line: 7 + character: 120 + end_position: + bytes: 405 + line: 7 + character: 133 + token_type: + type: Identifier + identifier: minScaleRatio + trailing_trivia: + - start_position: + bytes: 405 + line: 7 + character: 133 + end_position: + bytes: 406 + line: 7 + character: 133 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: + - start_position: + bytes: 406 + line: 8 + character: 1 + end_position: + bytes: 410 + line: 8 + character: 5 + token_type: + type: Whitespace + characters: "\t\t\t\t" + token: + start_position: + bytes: 410 + line: 8 + character: 5 + end_position: + bytes: 415 + line: 8 + character: 10 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 415 + line: 8 + character: 10 + end_position: + bytes: 416 + line: 8 + character: 11 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 416 + line: 8 + character: 11 + end_position: + bytes: 422 + line: 8 + character: 17 + token_type: + type: Identifier + identifier: ratio2 + trailing_trivia: + - start_position: + bytes: 422 + line: 8 + character: 17 + end_position: + bytes: 423 + line: 8 + character: 18 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 423 + line: 8 + character: 18 + end_position: + bytes: 424 + line: 8 + character: 19 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 424 + line: 8 + character: 19 + end_position: + bytes: 425 + line: 8 + character: 20 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + BinaryOperator: + lhs: + BinaryOperator: + lhs: + BinaryOperator: + lhs: + BinaryOperator: + lhs: + Parentheses: + contained: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 425 + line: 8 + character: 20 + end_position: + bytes: 426 + line: 8 + character: 21 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 447 + line: 8 + character: 42 + end_position: + bytes: 448 + line: 8 + character: 43 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 448 + line: 8 + character: 43 + end_position: + bytes: 449 + line: 8 + character: 44 + token_type: + type: Whitespace + characters: " " + expression: + BinaryOperator: + lhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 426 + line: 8 + character: 21 + end_position: + bytes: 433 + line: 8 + character: 28 + token_type: + type: Identifier + identifier: minAxis + trailing_trivia: + - start_position: + bytes: 433 + line: 8 + character: 28 + end_position: + bytes: 434 + line: 8 + character: 29 + token_type: + type: Whitespace + characters: " " + binop: + Minus: + leading_trivia: [] + token: + start_position: + bytes: 434 + line: 8 + character: 29 + end_position: + bytes: 435 + line: 8 + character: 30 + token_type: + type: Symbol + symbol: "-" + trailing_trivia: + - start_position: + bytes: 435 + line: 8 + character: 30 + end_position: + bytes: 436 + line: 8 + character: 31 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 436 + line: 8 + character: 31 + end_position: + bytes: 447 + line: 8 + character: 42 + token_type: + type: Identifier + identifier: minAxisSize + trailing_trivia: [] + binop: + Slash: + leading_trivia: [] + token: + start_position: + bytes: 449 + line: 8 + character: 44 + end_position: + bytes: 450 + line: 8 + character: 45 + token_type: + type: Symbol + symbol: / + trailing_trivia: + - start_position: + bytes: 450 + line: 8 + character: 45 + end_position: + bytes: 451 + line: 8 + character: 46 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 451 + line: 8 + character: 46 + end_position: + bytes: 456 + line: 8 + character: 51 + token_type: + type: Identifier + identifier: delta + trailing_trivia: + - start_position: + bytes: 456 + line: 8 + character: 51 + end_position: + bytes: 457 + line: 8 + character: 52 + token_type: + type: Whitespace + characters: " " + binop: + Star: + leading_trivia: [] + token: + start_position: + bytes: 457 + line: 8 + character: 52 + end_position: + bytes: 458 + line: 8 + character: 53 + token_type: + type: Symbol + symbol: "*" + trailing_trivia: + - start_position: + bytes: 458 + line: 8 + character: 53 + end_position: + bytes: 459 + line: 8 + character: 54 + token_type: + type: Whitespace + characters: " " + rhs: + Parentheses: + contained: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 459 + line: 8 + character: 54 + end_position: + bytes: 460 + line: 8 + character: 55 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 511 + line: 8 + character: 106 + end_position: + bytes: 512 + line: 8 + character: 107 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 512 + line: 8 + character: 107 + end_position: + bytes: 513 + line: 8 + character: 108 + token_type: + type: Whitespace + characters: " " + expression: + BinaryOperator: + lhs: + Var: + Expression: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 460 + line: 8 + character: 55 + end_position: + bytes: 464 + line: 8 + character: 59 + token_type: + type: Identifier + identifier: self + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 464 + line: 8 + character: 59 + end_position: + bytes: 465 + line: 8 + character: 60 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 465 + line: 8 + character: 60 + end_position: + bytes: 470 + line: 8 + character: 65 + token_type: + type: Identifier + identifier: props + trailing_trivia: [] + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 470 + line: 8 + character: 65 + end_position: + bytes: 471 + line: 8 + character: 66 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 471 + line: 8 + character: 66 + end_position: + bytes: 484 + line: 8 + character: 79 + token_type: + type: Identifier + identifier: maxScaleRatio + trailing_trivia: + - start_position: + bytes: 484 + line: 8 + character: 79 + end_position: + bytes: 485 + line: 8 + character: 80 + token_type: + type: Whitespace + characters: " " + binop: + Minus: + leading_trivia: [] + token: + start_position: + bytes: 485 + line: 8 + character: 80 + end_position: + bytes: 486 + line: 8 + character: 81 + token_type: + type: Symbol + symbol: "-" + trailing_trivia: + - start_position: + bytes: 486 + line: 8 + character: 81 + end_position: + bytes: 487 + line: 8 + character: 82 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Expression: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 487 + line: 8 + character: 82 + end_position: + bytes: 491 + line: 8 + character: 86 + token_type: + type: Identifier + identifier: self + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 491 + line: 8 + character: 86 + end_position: + bytes: 492 + line: 8 + character: 87 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 492 + line: 8 + character: 87 + end_position: + bytes: 497 + line: 8 + character: 92 + token_type: + type: Identifier + identifier: props + trailing_trivia: [] + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 497 + line: 8 + character: 92 + end_position: + bytes: 498 + line: 8 + character: 93 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 498 + line: 8 + character: 93 + end_position: + bytes: 511 + line: 8 + character: 106 + token_type: + type: Identifier + identifier: minScaleRatio + trailing_trivia: [] + binop: + Star: + leading_trivia: [] + token: + start_position: + bytes: 513 + line: 8 + character: 108 + end_position: + bytes: 514 + line: 8 + character: 109 + token_type: + type: Symbol + symbol: "*" + trailing_trivia: + - start_position: + bytes: 514 + line: 8 + character: 109 + end_position: + bytes: 515 + line: 8 + character: 110 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Expression: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 515 + line: 8 + character: 110 + end_position: + bytes: 519 + line: 8 + character: 114 + token_type: + type: Identifier + identifier: self + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 519 + line: 8 + character: 114 + end_position: + bytes: 520 + line: 8 + character: 115 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 520 + line: 8 + character: 115 + end_position: + bytes: 525 + line: 8 + character: 120 + token_type: + type: Identifier + identifier: props + trailing_trivia: [] + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 525 + line: 8 + character: 120 + end_position: + bytes: 526 + line: 8 + character: 121 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 526 + line: 8 + character: 121 + end_position: + bytes: 556 + line: 8 + character: 151 + token_type: + type: Identifier + identifier: aRandomVariableWhichIsVeryLong + trailing_trivia: + - start_position: + bytes: 556 + line: 8 + character: 151 + end_position: + bytes: 557 + line: 8 + character: 152 + token_type: + type: Whitespace + characters: " " + binop: + Plus: + leading_trivia: [] + token: + start_position: + bytes: 557 + line: 8 + character: 152 + end_position: + bytes: 558 + line: 8 + character: 153 + token_type: + type: Symbol + symbol: + + trailing_trivia: + - start_position: + bytes: 558 + line: 8 + character: 153 + end_position: + bytes: 559 + line: 8 + character: 154 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Expression: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 559 + line: 8 + character: 154 + end_position: + bytes: 563 + line: 8 + character: 158 + token_type: + type: Identifier + identifier: self + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 563 + line: 8 + character: 158 + end_position: + bytes: 564 + line: 8 + character: 159 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 564 + line: 8 + character: 159 + end_position: + bytes: 569 + line: 8 + character: 164 + token_type: + type: Identifier + identifier: props + trailing_trivia: [] + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 569 + line: 8 + character: 164 + end_position: + bytes: 570 + line: 8 + character: 165 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 570 + line: 8 + character: 165 + end_position: + bytes: 583 + line: 8 + character: 178 + token_type: + type: Identifier + identifier: minScaleRatio + trailing_trivia: + - start_position: + bytes: 583 + line: 8 + character: 178 + end_position: + bytes: 584 + line: 8 + character: 178 + token_type: + type: Whitespace + characters: "\n" + - ~ + end_token: + leading_trivia: + - start_position: + bytes: 584 + line: 9 + character: 1 + end_position: + bytes: 587 + line: 9 + character: 4 + token_type: + type: Whitespace + characters: "\t\t\t" + token: + start_position: + bytes: 587 + line: 9 + character: 4 + end_position: + bytes: 590 + line: 9 + character: 7 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 590 + line: 9 + character: 7 + end_position: + bytes: 591 + line: 9 + character: 7 + token_type: + type: Whitespace + characters: "\n" + - ~ + end_token: + leading_trivia: + - start_position: + bytes: 591 + line: 10 + character: 1 + end_position: + bytes: 593 + line: 10 + character: 3 + token_type: + type: Whitespace + characters: "\t\t" + token: + start_position: + bytes: 593 + line: 10 + character: 3 + end_position: + bytes: 596 + line: 10 + character: 6 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 596 + line: 10 + character: 6 + end_position: + bytes: 597 + line: 10 + character: 6 + token_type: + type: Whitespace + characters: "\n" + - ~ + end_token: + leading_trivia: + - start_position: + bytes: 597 + line: 11 + character: 1 + end_position: + bytes: 598 + line: 11 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 598 + line: 11 + character: 2 + end_position: + bytes: 601 + line: 11 + character: 5 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 601 + line: 11 + character: 5 + end_position: + bytes: 602 + line: 11 + character: 5 + token_type: + type: Whitespace + characters: "\n" + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 602 + line: 12 + character: 1 + end_position: + bytes: 605 + line: 12 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 605 + line: 12 + character: 4 + end_position: + bytes: 606 + line: 12 + character: 4 + token_type: + type: Whitespace + characters: "\n" + - ~ diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/multiline_expressions/source.lua b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/multiline_expressions/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..c899cbb58d25ddd1007382e42c5c344556bca1cd --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/multiline_expressions/source.lua @@ -0,0 +1,12 @@ +-- Taken from https://github.com/JohnnyMorganz/StyLua/blob/main/tests/inputs/multiline-expressions-3.lua +do + do + do + do + local text = "Players: " .. #Server_Container.ARandomVariableWhichIsVeryLongSoThatThisGetsOverTheColumnLimit.Players_F:GetChildren() - 1 .. "/20" + local ratio = (minAxis - minAxisSize) / delta * (self.props.maxScaleRatio - self.props.minScaleRatio) + self.props.minScaleRatio + local ratio2 = (minAxis - minAxisSize) / delta * (self.props.maxScaleRatio - self.props.minScaleRatio) * self.props.aRandomVariableWhichIsVeryLong + self.props.minScaleRatio + end + end + end +end diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/multiline_expressions/tokens.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/multiline_expressions/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..5d2629e29b383643da70392ec16fd50113e7304e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/multiline_expressions/tokens.snap @@ -0,0 +1,1689 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/roblox_cases/pass/multiline_expressions +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 104 + line: 1 + character: 105 + token_type: + type: SingleLineComment + comment: " Taken from https://github.com/JohnnyMorganz/StyLua/blob/main/tests/inputs/multiline-expressions-3.lua" +- start_position: + bytes: 104 + line: 1 + character: 105 + end_position: + bytes: 105 + line: 1 + character: 105 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 105 + line: 2 + character: 1 + end_position: + bytes: 107 + line: 2 + character: 3 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 107 + line: 2 + character: 3 + end_position: + bytes: 108 + line: 2 + character: 3 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 108 + line: 3 + character: 1 + end_position: + bytes: 109 + line: 3 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 109 + line: 3 + character: 2 + end_position: + bytes: 111 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 111 + line: 3 + character: 4 + end_position: + bytes: 112 + line: 3 + character: 4 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 112 + line: 4 + character: 1 + end_position: + bytes: 114 + line: 4 + character: 3 + token_type: + type: Whitespace + characters: "\t\t" +- start_position: + bytes: 114 + line: 4 + character: 3 + end_position: + bytes: 116 + line: 4 + character: 5 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 116 + line: 4 + character: 5 + end_position: + bytes: 117 + line: 4 + character: 5 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 117 + line: 5 + character: 1 + end_position: + bytes: 120 + line: 5 + character: 4 + token_type: + type: Whitespace + characters: "\t\t\t" +- start_position: + bytes: 120 + line: 5 + character: 4 + end_position: + bytes: 122 + line: 5 + character: 6 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 122 + line: 5 + character: 6 + end_position: + bytes: 123 + line: 5 + character: 6 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 123 + line: 6 + character: 1 + end_position: + bytes: 127 + line: 6 + character: 5 + token_type: + type: Whitespace + characters: "\t\t\t\t" +- start_position: + bytes: 127 + line: 6 + character: 5 + end_position: + bytes: 132 + line: 6 + character: 10 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 132 + line: 6 + character: 10 + end_position: + bytes: 133 + line: 6 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 133 + line: 6 + character: 11 + end_position: + bytes: 137 + line: 6 + character: 15 + token_type: + type: Identifier + identifier: text +- start_position: + bytes: 137 + line: 6 + character: 15 + end_position: + bytes: 138 + line: 6 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 138 + line: 6 + character: 16 + end_position: + bytes: 139 + line: 6 + character: 17 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 139 + line: 6 + character: 17 + end_position: + bytes: 140 + line: 6 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 140 + line: 6 + character: 18 + end_position: + bytes: 151 + line: 6 + character: 29 + token_type: + type: StringLiteral + literal: "Players: " + quote_type: Double +- start_position: + bytes: 151 + line: 6 + character: 29 + end_position: + bytes: 152 + line: 6 + character: 30 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 152 + line: 6 + character: 30 + end_position: + bytes: 154 + line: 6 + character: 32 + token_type: + type: Symbol + symbol: ".." +- start_position: + bytes: 154 + line: 6 + character: 32 + end_position: + bytes: 155 + line: 6 + character: 33 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 155 + line: 6 + character: 33 + end_position: + bytes: 156 + line: 6 + character: 34 + token_type: + type: Symbol + symbol: "#" +- start_position: + bytes: 156 + line: 6 + character: 34 + end_position: + bytes: 172 + line: 6 + character: 50 + token_type: + type: Identifier + identifier: Server_Container +- start_position: + bytes: 172 + line: 6 + character: 50 + end_position: + bytes: 173 + line: 6 + character: 51 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 173 + line: 6 + character: 51 + end_position: + bytes: 235 + line: 6 + character: 113 + token_type: + type: Identifier + identifier: ARandomVariableWhichIsVeryLongSoThatThisGetsOverTheColumnLimit +- start_position: + bytes: 235 + line: 6 + character: 113 + end_position: + bytes: 236 + line: 6 + character: 114 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 236 + line: 6 + character: 114 + end_position: + bytes: 245 + line: 6 + character: 123 + token_type: + type: Identifier + identifier: Players_F +- start_position: + bytes: 245 + line: 6 + character: 123 + end_position: + bytes: 246 + line: 6 + character: 124 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 246 + line: 6 + character: 124 + end_position: + bytes: 257 + line: 6 + character: 135 + token_type: + type: Identifier + identifier: GetChildren +- start_position: + bytes: 257 + line: 6 + character: 135 + end_position: + bytes: 258 + line: 6 + character: 136 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 258 + line: 6 + character: 136 + end_position: + bytes: 259 + line: 6 + character: 137 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 259 + line: 6 + character: 137 + end_position: + bytes: 260 + line: 6 + character: 138 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 260 + line: 6 + character: 138 + end_position: + bytes: 261 + line: 6 + character: 139 + token_type: + type: Symbol + symbol: "-" +- start_position: + bytes: 261 + line: 6 + character: 139 + end_position: + bytes: 262 + line: 6 + character: 140 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 262 + line: 6 + character: 140 + end_position: + bytes: 263 + line: 6 + character: 141 + token_type: + type: Number + text: "1" +- start_position: + bytes: 263 + line: 6 + character: 141 + end_position: + bytes: 264 + line: 6 + character: 142 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 264 + line: 6 + character: 142 + end_position: + bytes: 266 + line: 6 + character: 144 + token_type: + type: Symbol + symbol: ".." +- start_position: + bytes: 266 + line: 6 + character: 144 + end_position: + bytes: 267 + line: 6 + character: 145 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 267 + line: 6 + character: 145 + end_position: + bytes: 272 + line: 6 + character: 150 + token_type: + type: StringLiteral + literal: /20 + quote_type: Double +- start_position: + bytes: 272 + line: 6 + character: 150 + end_position: + bytes: 273 + line: 6 + character: 150 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 273 + line: 7 + character: 1 + end_position: + bytes: 277 + line: 7 + character: 5 + token_type: + type: Whitespace + characters: "\t\t\t\t" +- start_position: + bytes: 277 + line: 7 + character: 5 + end_position: + bytes: 282 + line: 7 + character: 10 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 282 + line: 7 + character: 10 + end_position: + bytes: 283 + line: 7 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 283 + line: 7 + character: 11 + end_position: + bytes: 288 + line: 7 + character: 16 + token_type: + type: Identifier + identifier: ratio +- start_position: + bytes: 288 + line: 7 + character: 16 + end_position: + bytes: 289 + line: 7 + character: 17 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 289 + line: 7 + character: 17 + end_position: + bytes: 290 + line: 7 + character: 18 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 290 + line: 7 + character: 18 + end_position: + bytes: 291 + line: 7 + character: 19 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 291 + line: 7 + character: 19 + end_position: + bytes: 292 + line: 7 + character: 20 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 292 + line: 7 + character: 20 + end_position: + bytes: 299 + line: 7 + character: 27 + token_type: + type: Identifier + identifier: minAxis +- start_position: + bytes: 299 + line: 7 + character: 27 + end_position: + bytes: 300 + line: 7 + character: 28 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 300 + line: 7 + character: 28 + end_position: + bytes: 301 + line: 7 + character: 29 + token_type: + type: Symbol + symbol: "-" +- start_position: + bytes: 301 + line: 7 + character: 29 + end_position: + bytes: 302 + line: 7 + character: 30 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 302 + line: 7 + character: 30 + end_position: + bytes: 313 + line: 7 + character: 41 + token_type: + type: Identifier + identifier: minAxisSize +- start_position: + bytes: 313 + line: 7 + character: 41 + end_position: + bytes: 314 + line: 7 + character: 42 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 314 + line: 7 + character: 42 + end_position: + bytes: 315 + line: 7 + character: 43 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 315 + line: 7 + character: 43 + end_position: + bytes: 316 + line: 7 + character: 44 + token_type: + type: Symbol + symbol: / +- start_position: + bytes: 316 + line: 7 + character: 44 + end_position: + bytes: 317 + line: 7 + character: 45 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 317 + line: 7 + character: 45 + end_position: + bytes: 322 + line: 7 + character: 50 + token_type: + type: Identifier + identifier: delta +- start_position: + bytes: 322 + line: 7 + character: 50 + end_position: + bytes: 323 + line: 7 + character: 51 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 323 + line: 7 + character: 51 + end_position: + bytes: 324 + line: 7 + character: 52 + token_type: + type: Symbol + symbol: "*" +- start_position: + bytes: 324 + line: 7 + character: 52 + end_position: + bytes: 325 + line: 7 + character: 53 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 325 + line: 7 + character: 53 + end_position: + bytes: 326 + line: 7 + character: 54 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 326 + line: 7 + character: 54 + end_position: + bytes: 330 + line: 7 + character: 58 + token_type: + type: Identifier + identifier: self +- start_position: + bytes: 330 + line: 7 + character: 58 + end_position: + bytes: 331 + line: 7 + character: 59 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 331 + line: 7 + character: 59 + end_position: + bytes: 336 + line: 7 + character: 64 + token_type: + type: Identifier + identifier: props +- start_position: + bytes: 336 + line: 7 + character: 64 + end_position: + bytes: 337 + line: 7 + character: 65 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 337 + line: 7 + character: 65 + end_position: + bytes: 350 + line: 7 + character: 78 + token_type: + type: Identifier + identifier: maxScaleRatio +- start_position: + bytes: 350 + line: 7 + character: 78 + end_position: + bytes: 351 + line: 7 + character: 79 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 351 + line: 7 + character: 79 + end_position: + bytes: 352 + line: 7 + character: 80 + token_type: + type: Symbol + symbol: "-" +- start_position: + bytes: 352 + line: 7 + character: 80 + end_position: + bytes: 353 + line: 7 + character: 81 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 353 + line: 7 + character: 81 + end_position: + bytes: 357 + line: 7 + character: 85 + token_type: + type: Identifier + identifier: self +- start_position: + bytes: 357 + line: 7 + character: 85 + end_position: + bytes: 358 + line: 7 + character: 86 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 358 + line: 7 + character: 86 + end_position: + bytes: 363 + line: 7 + character: 91 + token_type: + type: Identifier + identifier: props +- start_position: + bytes: 363 + line: 7 + character: 91 + end_position: + bytes: 364 + line: 7 + character: 92 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 364 + line: 7 + character: 92 + end_position: + bytes: 377 + line: 7 + character: 105 + token_type: + type: Identifier + identifier: minScaleRatio +- start_position: + bytes: 377 + line: 7 + character: 105 + end_position: + bytes: 378 + line: 7 + character: 106 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 378 + line: 7 + character: 106 + end_position: + bytes: 379 + line: 7 + character: 107 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 379 + line: 7 + character: 107 + end_position: + bytes: 380 + line: 7 + character: 108 + token_type: + type: Symbol + symbol: + +- start_position: + bytes: 380 + line: 7 + character: 108 + end_position: + bytes: 381 + line: 7 + character: 109 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 381 + line: 7 + character: 109 + end_position: + bytes: 385 + line: 7 + character: 113 + token_type: + type: Identifier + identifier: self +- start_position: + bytes: 385 + line: 7 + character: 113 + end_position: + bytes: 386 + line: 7 + character: 114 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 386 + line: 7 + character: 114 + end_position: + bytes: 391 + line: 7 + character: 119 + token_type: + type: Identifier + identifier: props +- start_position: + bytes: 391 + line: 7 + character: 119 + end_position: + bytes: 392 + line: 7 + character: 120 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 392 + line: 7 + character: 120 + end_position: + bytes: 405 + line: 7 + character: 133 + token_type: + type: Identifier + identifier: minScaleRatio +- start_position: + bytes: 405 + line: 7 + character: 133 + end_position: + bytes: 406 + line: 7 + character: 133 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 406 + line: 8 + character: 1 + end_position: + bytes: 410 + line: 8 + character: 5 + token_type: + type: Whitespace + characters: "\t\t\t\t" +- start_position: + bytes: 410 + line: 8 + character: 5 + end_position: + bytes: 415 + line: 8 + character: 10 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 415 + line: 8 + character: 10 + end_position: + bytes: 416 + line: 8 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 416 + line: 8 + character: 11 + end_position: + bytes: 422 + line: 8 + character: 17 + token_type: + type: Identifier + identifier: ratio2 +- start_position: + bytes: 422 + line: 8 + character: 17 + end_position: + bytes: 423 + line: 8 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 423 + line: 8 + character: 18 + end_position: + bytes: 424 + line: 8 + character: 19 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 424 + line: 8 + character: 19 + end_position: + bytes: 425 + line: 8 + character: 20 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 425 + line: 8 + character: 20 + end_position: + bytes: 426 + line: 8 + character: 21 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 426 + line: 8 + character: 21 + end_position: + bytes: 433 + line: 8 + character: 28 + token_type: + type: Identifier + identifier: minAxis +- start_position: + bytes: 433 + line: 8 + character: 28 + end_position: + bytes: 434 + line: 8 + character: 29 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 434 + line: 8 + character: 29 + end_position: + bytes: 435 + line: 8 + character: 30 + token_type: + type: Symbol + symbol: "-" +- start_position: + bytes: 435 + line: 8 + character: 30 + end_position: + bytes: 436 + line: 8 + character: 31 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 436 + line: 8 + character: 31 + end_position: + bytes: 447 + line: 8 + character: 42 + token_type: + type: Identifier + identifier: minAxisSize +- start_position: + bytes: 447 + line: 8 + character: 42 + end_position: + bytes: 448 + line: 8 + character: 43 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 448 + line: 8 + character: 43 + end_position: + bytes: 449 + line: 8 + character: 44 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 449 + line: 8 + character: 44 + end_position: + bytes: 450 + line: 8 + character: 45 + token_type: + type: Symbol + symbol: / +- start_position: + bytes: 450 + line: 8 + character: 45 + end_position: + bytes: 451 + line: 8 + character: 46 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 451 + line: 8 + character: 46 + end_position: + bytes: 456 + line: 8 + character: 51 + token_type: + type: Identifier + identifier: delta +- start_position: + bytes: 456 + line: 8 + character: 51 + end_position: + bytes: 457 + line: 8 + character: 52 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 457 + line: 8 + character: 52 + end_position: + bytes: 458 + line: 8 + character: 53 + token_type: + type: Symbol + symbol: "*" +- start_position: + bytes: 458 + line: 8 + character: 53 + end_position: + bytes: 459 + line: 8 + character: 54 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 459 + line: 8 + character: 54 + end_position: + bytes: 460 + line: 8 + character: 55 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 460 + line: 8 + character: 55 + end_position: + bytes: 464 + line: 8 + character: 59 + token_type: + type: Identifier + identifier: self +- start_position: + bytes: 464 + line: 8 + character: 59 + end_position: + bytes: 465 + line: 8 + character: 60 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 465 + line: 8 + character: 60 + end_position: + bytes: 470 + line: 8 + character: 65 + token_type: + type: Identifier + identifier: props +- start_position: + bytes: 470 + line: 8 + character: 65 + end_position: + bytes: 471 + line: 8 + character: 66 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 471 + line: 8 + character: 66 + end_position: + bytes: 484 + line: 8 + character: 79 + token_type: + type: Identifier + identifier: maxScaleRatio +- start_position: + bytes: 484 + line: 8 + character: 79 + end_position: + bytes: 485 + line: 8 + character: 80 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 485 + line: 8 + character: 80 + end_position: + bytes: 486 + line: 8 + character: 81 + token_type: + type: Symbol + symbol: "-" +- start_position: + bytes: 486 + line: 8 + character: 81 + end_position: + bytes: 487 + line: 8 + character: 82 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 487 + line: 8 + character: 82 + end_position: + bytes: 491 + line: 8 + character: 86 + token_type: + type: Identifier + identifier: self +- start_position: + bytes: 491 + line: 8 + character: 86 + end_position: + bytes: 492 + line: 8 + character: 87 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 492 + line: 8 + character: 87 + end_position: + bytes: 497 + line: 8 + character: 92 + token_type: + type: Identifier + identifier: props +- start_position: + bytes: 497 + line: 8 + character: 92 + end_position: + bytes: 498 + line: 8 + character: 93 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 498 + line: 8 + character: 93 + end_position: + bytes: 511 + line: 8 + character: 106 + token_type: + type: Identifier + identifier: minScaleRatio +- start_position: + bytes: 511 + line: 8 + character: 106 + end_position: + bytes: 512 + line: 8 + character: 107 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 512 + line: 8 + character: 107 + end_position: + bytes: 513 + line: 8 + character: 108 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 513 + line: 8 + character: 108 + end_position: + bytes: 514 + line: 8 + character: 109 + token_type: + type: Symbol + symbol: "*" +- start_position: + bytes: 514 + line: 8 + character: 109 + end_position: + bytes: 515 + line: 8 + character: 110 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 515 + line: 8 + character: 110 + end_position: + bytes: 519 + line: 8 + character: 114 + token_type: + type: Identifier + identifier: self +- start_position: + bytes: 519 + line: 8 + character: 114 + end_position: + bytes: 520 + line: 8 + character: 115 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 520 + line: 8 + character: 115 + end_position: + bytes: 525 + line: 8 + character: 120 + token_type: + type: Identifier + identifier: props +- start_position: + bytes: 525 + line: 8 + character: 120 + end_position: + bytes: 526 + line: 8 + character: 121 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 526 + line: 8 + character: 121 + end_position: + bytes: 556 + line: 8 + character: 151 + token_type: + type: Identifier + identifier: aRandomVariableWhichIsVeryLong +- start_position: + bytes: 556 + line: 8 + character: 151 + end_position: + bytes: 557 + line: 8 + character: 152 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 557 + line: 8 + character: 152 + end_position: + bytes: 558 + line: 8 + character: 153 + token_type: + type: Symbol + symbol: + +- start_position: + bytes: 558 + line: 8 + character: 153 + end_position: + bytes: 559 + line: 8 + character: 154 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 559 + line: 8 + character: 154 + end_position: + bytes: 563 + line: 8 + character: 158 + token_type: + type: Identifier + identifier: self +- start_position: + bytes: 563 + line: 8 + character: 158 + end_position: + bytes: 564 + line: 8 + character: 159 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 564 + line: 8 + character: 159 + end_position: + bytes: 569 + line: 8 + character: 164 + token_type: + type: Identifier + identifier: props +- start_position: + bytes: 569 + line: 8 + character: 164 + end_position: + bytes: 570 + line: 8 + character: 165 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 570 + line: 8 + character: 165 + end_position: + bytes: 583 + line: 8 + character: 178 + token_type: + type: Identifier + identifier: minScaleRatio +- start_position: + bytes: 583 + line: 8 + character: 178 + end_position: + bytes: 584 + line: 8 + character: 178 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 584 + line: 9 + character: 1 + end_position: + bytes: 587 + line: 9 + character: 4 + token_type: + type: Whitespace + characters: "\t\t\t" +- start_position: + bytes: 587 + line: 9 + character: 4 + end_position: + bytes: 590 + line: 9 + character: 7 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 590 + line: 9 + character: 7 + end_position: + bytes: 591 + line: 9 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 591 + line: 10 + character: 1 + end_position: + bytes: 593 + line: 10 + character: 3 + token_type: + type: Whitespace + characters: "\t\t" +- start_position: + bytes: 593 + line: 10 + character: 3 + end_position: + bytes: 596 + line: 10 + character: 6 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 596 + line: 10 + character: 6 + end_position: + bytes: 597 + line: 10 + character: 6 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 597 + line: 11 + character: 1 + end_position: + bytes: 598 + line: 11 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 598 + line: 11 + character: 2 + end_position: + bytes: 601 + line: 11 + character: 5 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 601 + line: 11 + character: 5 + end_position: + bytes: 602 + line: 11 + character: 5 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 602 + line: 12 + character: 1 + end_position: + bytes: 605 + line: 12 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 605 + line: 12 + character: 4 + end_position: + bytes: 606 + line: 12 + character: 4 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 606 + line: 13 + character: 1 + end_position: + bytes: 606 + line: 13 + character: 1 + token_type: + type: Eof diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/named_function_arg_types/ast.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/named_function_arg_types/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..5113175fb9c61c226bfed43dd631614fc6e4c9da --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/named_function_arg_types/ast.snap @@ -0,0 +1,1983 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: ast.nodes() +input_file: vvs_parser/tests/roblox_cases/pass/named_function_arg_types +--- +stmts: + - - TypeDeclaration: + type_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: type + trailing_trivia: + - start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " + base: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Identifier + identifier: MyCallbackType + trailing_trivia: + - start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Whitespace + characters: " " + declare_as: + Callback: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 22 + line: 1 + character: 23 + end_position: + bytes: 23 + line: 1 + character: 24 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 49 + line: 1 + character: 50 + end_position: + bytes: 50 + line: 1 + character: 51 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 50 + line: 1 + character: 51 + end_position: + bytes: 51 + line: 1 + character: 52 + token_type: + type: Whitespace + characters: " " + arguments: + pairs: + - Punctuated: + - name: + - leading_trivia: [] + token: + start_position: + bytes: 23 + line: 1 + character: 24 + end_position: + bytes: 27 + line: 1 + character: 28 + token_type: + type: Identifier + identifier: cost + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 27 + line: 1 + character: 28 + end_position: + bytes: 28 + line: 1 + character: 29 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 28 + line: 1 + character: 29 + end_position: + bytes: 29 + line: 1 + character: 30 + token_type: + type: Whitespace + characters: " " + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 29 + line: 1 + character: 30 + end_position: + bytes: 35 + line: 1 + character: 36 + token_type: + type: Identifier + identifier: number + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 35 + line: 1 + character: 36 + end_position: + bytes: 36 + line: 1 + character: 37 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 36 + line: 1 + character: 37 + end_position: + bytes: 37 + line: 1 + character: 38 + token_type: + type: Whitespace + characters: " " + - End: + name: + - leading_trivia: [] + token: + start_position: + bytes: 37 + line: 1 + character: 38 + end_position: + bytes: 41 + line: 1 + character: 42 + token_type: + type: Identifier + identifier: name + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 41 + line: 1 + character: 42 + end_position: + bytes: 42 + line: 1 + character: 43 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 42 + line: 1 + character: 43 + end_position: + bytes: 43 + line: 1 + character: 44 + token_type: + type: Whitespace + characters: " " + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 43 + line: 1 + character: 44 + end_position: + bytes: 49 + line: 1 + character: 50 + token_type: + type: Identifier + identifier: string + trailing_trivia: [] + arrow: + leading_trivia: [] + token: + start_position: + bytes: 51 + line: 1 + character: 52 + end_position: + bytes: 53 + line: 1 + character: 54 + token_type: + type: Symbol + symbol: "->" + trailing_trivia: + - start_position: + bytes: 53 + line: 1 + character: 54 + end_position: + bytes: 54 + line: 1 + character: 55 + token_type: + type: Whitespace + characters: " " + return_type: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 54 + line: 1 + character: 55 + end_position: + bytes: 60 + line: 1 + character: 61 + token_type: + type: Identifier + identifier: string + trailing_trivia: + - start_position: + bytes: 60 + line: 1 + character: 61 + end_position: + bytes: 61 + line: 1 + character: 61 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: + - start_position: + bytes: 61 + line: 2 + character: 1 + end_position: + bytes: 62 + line: 2 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 62 + line: 3 + character: 1 + end_position: + bytes: 67 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 67 + line: 3 + character: 6 + end_position: + bytes: 68 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " + type_specifiers: + - punctuation: + leading_trivia: [] + token: + start_position: + bytes: 70 + line: 3 + character: 9 + end_position: + bytes: 71 + line: 3 + character: 10 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 71 + line: 3 + character: 10 + end_position: + bytes: 72 + line: 3 + character: 11 + token_type: + type: Whitespace + characters: " " + type_info: + Callback: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 72 + line: 3 + character: 11 + end_position: + bytes: 73 + line: 3 + character: 12 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 87 + line: 3 + character: 26 + end_position: + bytes: 88 + line: 3 + character: 27 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 88 + line: 3 + character: 27 + end_position: + bytes: 89 + line: 3 + character: 28 + token_type: + type: Whitespace + characters: " " + arguments: + pairs: + - End: + name: + - leading_trivia: [] + token: + start_position: + bytes: 73 + line: 3 + character: 12 + end_position: + bytes: 79 + line: 3 + character: 18 + token_type: + type: Identifier + identifier: amount + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 79 + line: 3 + character: 18 + end_position: + bytes: 80 + line: 3 + character: 19 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 80 + line: 3 + character: 19 + end_position: + bytes: 81 + line: 3 + character: 20 + token_type: + type: Whitespace + characters: " " + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 81 + line: 3 + character: 20 + end_position: + bytes: 87 + line: 3 + character: 26 + token_type: + type: Identifier + identifier: number + trailing_trivia: [] + arrow: + leading_trivia: [] + token: + start_position: + bytes: 89 + line: 3 + character: 28 + end_position: + bytes: 91 + line: 3 + character: 30 + token_type: + type: Symbol + symbol: "->" + trailing_trivia: + - start_position: + bytes: 91 + line: 3 + character: 30 + end_position: + bytes: 92 + line: 3 + character: 31 + token_type: + type: Whitespace + characters: " " + return_type: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 92 + line: 3 + character: 31 + end_position: + bytes: 98 + line: 3 + character: 37 + token_type: + type: Identifier + identifier: number + trailing_trivia: + - start_position: + bytes: 98 + line: 3 + character: 37 + end_position: + bytes: 99 + line: 3 + character: 37 + token_type: + type: Whitespace + characters: "\n" + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 68 + line: 3 + character: 7 + end_position: + bytes: 70 + line: 3 + character: 9 + token_type: + type: Identifier + identifier: cb + trailing_trivia: [] + equal_token: ~ + expr_list: + pairs: [] + - ~ + - - LocalFunction: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 99 + line: 4 + character: 1 + end_position: + bytes: 104 + line: 4 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 104 + line: 4 + character: 6 + end_position: + bytes: 105 + line: 4 + character: 7 + token_type: + type: Whitespace + characters: " " + function_token: + leading_trivia: [] + token: + start_position: + bytes: 105 + line: 4 + character: 7 + end_position: + bytes: 113 + line: 4 + character: 15 + token_type: + type: Symbol + symbol: function + trailing_trivia: + - start_position: + bytes: 113 + line: 4 + character: 15 + end_position: + bytes: 114 + line: 4 + character: 16 + token_type: + type: Whitespace + characters: " " + name: + leading_trivia: [] + token: + start_position: + bytes: 114 + line: 4 + character: 16 + end_position: + bytes: 117 + line: 4 + character: 19 + token_type: + type: Identifier + identifier: foo + trailing_trivia: [] + body: + parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 117 + line: 4 + character: 19 + end_position: + bytes: 118 + line: 4 + character: 20 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 144 + line: 4 + character: 46 + end_position: + bytes: 145 + line: 4 + character: 47 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 145 + line: 4 + character: 47 + end_position: + bytes: 146 + line: 4 + character: 47 + token_type: + type: Whitespace + characters: "\n" + parameters: + pairs: + - End: + name: + leading_trivia: [] + token: + start_position: + bytes: 118 + line: 4 + character: 20 + end_position: + bytes: 120 + line: 4 + character: 22 + token_type: + type: Identifier + identifier: cb + trailing_trivia: [] + type_specifiers: + - punctuation: + leading_trivia: [] + token: + start_position: + bytes: 120 + line: 4 + character: 22 + end_position: + bytes: 121 + line: 4 + character: 23 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 121 + line: 4 + character: 23 + end_position: + bytes: 122 + line: 4 + character: 24 + token_type: + type: Whitespace + characters: " " + type_info: + Callback: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 122 + line: 4 + character: 24 + end_position: + bytes: 123 + line: 4 + character: 25 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 135 + line: 4 + character: 37 + end_position: + bytes: 136 + line: 4 + character: 38 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 136 + line: 4 + character: 38 + end_position: + bytes: 137 + line: 4 + character: 39 + token_type: + type: Whitespace + characters: " " + arguments: + pairs: + - End: + name: + - leading_trivia: [] + token: + start_position: + bytes: 123 + line: 4 + character: 25 + end_position: + bytes: 127 + line: 4 + character: 29 + token_type: + type: Identifier + identifier: name + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 127 + line: 4 + character: 29 + end_position: + bytes: 128 + line: 4 + character: 30 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 128 + line: 4 + character: 30 + end_position: + bytes: 129 + line: 4 + character: 31 + token_type: + type: Whitespace + characters: " " + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 129 + line: 4 + character: 31 + end_position: + bytes: 135 + line: 4 + character: 37 + token_type: + type: Identifier + identifier: string + trailing_trivia: [] + arrow: + leading_trivia: [] + token: + start_position: + bytes: 137 + line: 4 + character: 39 + end_position: + bytes: 139 + line: 4 + character: 41 + token_type: + type: Symbol + symbol: "->" + trailing_trivia: + - start_position: + bytes: 139 + line: 4 + character: 41 + end_position: + bytes: 140 + line: 4 + character: 42 + token_type: + type: Whitespace + characters: " " + return_type: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 140 + line: 4 + character: 42 + end_position: + bytes: 144 + line: 4 + character: 46 + token_type: + type: Identifier + identifier: unit + trailing_trivia: [] + block: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 146 + line: 5 + character: 1 + end_position: + bytes: 149 + line: 5 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 149 + line: 5 + character: 4 + end_position: + bytes: 150 + line: 5 + character: 4 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalFunction: + local_token: + leading_trivia: + - start_position: + bytes: 150 + line: 6 + character: 1 + end_position: + bytes: 151 + line: 6 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 151 + line: 7 + character: 1 + end_position: + bytes: 156 + line: 7 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 156 + line: 7 + character: 6 + end_position: + bytes: 157 + line: 7 + character: 7 + token_type: + type: Whitespace + characters: " " + function_token: + leading_trivia: [] + token: + start_position: + bytes: 157 + line: 7 + character: 7 + end_position: + bytes: 165 + line: 7 + character: 15 + token_type: + type: Symbol + symbol: function + trailing_trivia: + - start_position: + bytes: 165 + line: 7 + character: 15 + end_position: + bytes: 166 + line: 7 + character: 16 + token_type: + type: Whitespace + characters: " " + name: + leading_trivia: [] + token: + start_position: + bytes: 166 + line: 7 + character: 16 + end_position: + bytes: 169 + line: 7 + character: 19 + token_type: + type: Identifier + identifier: bar + trailing_trivia: [] + body: + parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 169 + line: 7 + character: 19 + end_position: + bytes: 170 + line: 7 + character: 20 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 180 + line: 7 + character: 30 + end_position: + bytes: 181 + line: 7 + character: 31 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + parameters: + pairs: + - End: + name: + leading_trivia: [] + token: + start_position: + bytes: 170 + line: 7 + character: 20 + end_position: + bytes: 171 + line: 7 + character: 21 + token_type: + type: Identifier + identifier: x + trailing_trivia: [] + type_specifiers: + - punctuation: + leading_trivia: [] + token: + start_position: + bytes: 171 + line: 7 + character: 21 + end_position: + bytes: 172 + line: 7 + character: 22 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 172 + line: 7 + character: 22 + end_position: + bytes: 173 + line: 7 + character: 23 + token_type: + type: Whitespace + characters: " " + type_info: + Optional: + base: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 173 + line: 7 + character: 23 + end_position: + bytes: 179 + line: 7 + character: 29 + token_type: + type: Identifier + identifier: number + trailing_trivia: [] + question_mark: + leading_trivia: [] + token: + start_position: + bytes: 179 + line: 7 + character: 29 + end_position: + bytes: 180 + line: 7 + character: 30 + token_type: + type: Symbol + symbol: "?" + trailing_trivia: [] + return_type: + punctuation: + leading_trivia: [] + token: + start_position: + bytes: 181 + line: 7 + character: 31 + end_position: + bytes: 182 + line: 7 + character: 32 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 182 + line: 7 + character: 32 + end_position: + bytes: 183 + line: 7 + character: 33 + token_type: + type: Whitespace + characters: " " + type_info: + Callback: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 183 + line: 7 + character: 33 + end_position: + bytes: 184 + line: 7 + character: 34 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 195 + line: 7 + character: 45 + end_position: + bytes: 196 + line: 7 + character: 46 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 196 + line: 7 + character: 46 + end_position: + bytes: 197 + line: 7 + character: 47 + token_type: + type: Whitespace + characters: " " + arguments: + pairs: + - End: + name: + - leading_trivia: [] + token: + start_position: + bytes: 184 + line: 7 + character: 34 + end_position: + bytes: 187 + line: 7 + character: 37 + token_type: + type: Identifier + identifier: baz + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 187 + line: 7 + character: 37 + end_position: + bytes: 188 + line: 7 + character: 38 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 188 + line: 7 + character: 38 + end_position: + bytes: 189 + line: 7 + character: 39 + token_type: + type: Whitespace + characters: " " + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 189 + line: 7 + character: 39 + end_position: + bytes: 195 + line: 7 + character: 45 + token_type: + type: Identifier + identifier: string + trailing_trivia: [] + arrow: + leading_trivia: [] + token: + start_position: + bytes: 197 + line: 7 + character: 47 + end_position: + bytes: 199 + line: 7 + character: 49 + token_type: + type: Symbol + symbol: "->" + trailing_trivia: + - start_position: + bytes: 199 + line: 7 + character: 49 + end_position: + bytes: 200 + line: 7 + character: 50 + token_type: + type: Whitespace + characters: " " + return_type: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 200 + line: 7 + character: 50 + end_position: + bytes: 206 + line: 7 + character: 56 + token_type: + type: Identifier + identifier: string + trailing_trivia: + - start_position: + bytes: 206 + line: 7 + character: 56 + end_position: + bytes: 207 + line: 7 + character: 56 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 207 + line: 8 + character: 1 + end_position: + bytes: 210 + line: 8 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 210 + line: 8 + character: 4 + end_position: + bytes: 211 + line: 8 + character: 4 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalFunction: + local_token: + leading_trivia: + - start_position: + bytes: 211 + line: 9 + character: 1 + end_position: + bytes: 212 + line: 9 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 212 + line: 10 + character: 1 + end_position: + bytes: 217 + line: 10 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 217 + line: 10 + character: 6 + end_position: + bytes: 218 + line: 10 + character: 7 + token_type: + type: Whitespace + characters: " " + function_token: + leading_trivia: [] + token: + start_position: + bytes: 218 + line: 10 + character: 7 + end_position: + bytes: 226 + line: 10 + character: 15 + token_type: + type: Symbol + symbol: function + trailing_trivia: + - start_position: + bytes: 226 + line: 10 + character: 15 + end_position: + bytes: 227 + line: 10 + character: 16 + token_type: + type: Whitespace + characters: " " + name: + leading_trivia: [] + token: + start_position: + bytes: 227 + line: 10 + character: 16 + end_position: + bytes: 230 + line: 10 + character: 19 + token_type: + type: Identifier + identifier: bar + trailing_trivia: [] + body: + parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 230 + line: 10 + character: 19 + end_position: + bytes: 231 + line: 10 + character: 20 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 241 + line: 10 + character: 30 + end_position: + bytes: 242 + line: 10 + character: 31 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + parameters: + pairs: + - End: + name: + leading_trivia: [] + token: + start_position: + bytes: 231 + line: 10 + character: 20 + end_position: + bytes: 232 + line: 10 + character: 21 + token_type: + type: Identifier + identifier: x + trailing_trivia: [] + type_specifiers: + - punctuation: + leading_trivia: [] + token: + start_position: + bytes: 232 + line: 10 + character: 21 + end_position: + bytes: 233 + line: 10 + character: 22 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 233 + line: 10 + character: 22 + end_position: + bytes: 234 + line: 10 + character: 23 + token_type: + type: Whitespace + characters: " " + type_info: + Optional: + base: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 234 + line: 10 + character: 23 + end_position: + bytes: 240 + line: 10 + character: 29 + token_type: + type: Identifier + identifier: number + trailing_trivia: [] + question_mark: + leading_trivia: [] + token: + start_position: + bytes: 240 + line: 10 + character: 29 + end_position: + bytes: 241 + line: 10 + character: 30 + token_type: + type: Symbol + symbol: "?" + trailing_trivia: [] + return_type: + punctuation: + leading_trivia: [] + token: + start_position: + bytes: 242 + line: 10 + character: 31 + end_position: + bytes: 243 + line: 10 + character: 32 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 243 + line: 10 + character: 32 + end_position: + bytes: 244 + line: 10 + character: 33 + token_type: + type: Whitespace + characters: " " + type_info: + Callback: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 244 + line: 10 + character: 33 + end_position: + bytes: 245 + line: 10 + character: 34 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 256 + line: 10 + character: 45 + end_position: + bytes: 257 + line: 10 + character: 46 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 257 + line: 10 + character: 46 + end_position: + bytes: 258 + line: 10 + character: 47 + token_type: + type: Whitespace + characters: " " + arguments: + pairs: + - End: + name: + - leading_trivia: [] + token: + start_position: + bytes: 245 + line: 10 + character: 34 + end_position: + bytes: 248 + line: 10 + character: 37 + token_type: + type: Identifier + identifier: baz + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 248 + line: 10 + character: 37 + end_position: + bytes: 249 + line: 10 + character: 38 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 249 + line: 10 + character: 38 + end_position: + bytes: 250 + line: 10 + character: 39 + token_type: + type: Whitespace + characters: " " + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 250 + line: 10 + character: 39 + end_position: + bytes: 256 + line: 10 + character: 45 + token_type: + type: Identifier + identifier: string + trailing_trivia: [] + arrow: + leading_trivia: [] + token: + start_position: + bytes: 258 + line: 10 + character: 47 + end_position: + bytes: 260 + line: 10 + character: 49 + token_type: + type: Symbol + symbol: "->" + trailing_trivia: + - start_position: + bytes: 260 + line: 10 + character: 49 + end_position: + bytes: 261 + line: 10 + character: 50 + token_type: + type: Whitespace + characters: " " + return_type: + Tuple: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 261 + line: 10 + character: 50 + end_position: + bytes: 262 + line: 10 + character: 51 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 298 + line: 10 + character: 87 + end_position: + bytes: 299 + line: 10 + character: 88 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 299 + line: 10 + character: 88 + end_position: + bytes: 300 + line: 10 + character: 88 + token_type: + type: Whitespace + characters: "\n" + types: + pairs: + - End: + Callback: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 262 + line: 10 + character: 51 + end_position: + bytes: 263 + line: 10 + character: 52 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 290 + line: 10 + character: 79 + end_position: + bytes: 291 + line: 10 + character: 80 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 291 + line: 10 + character: 80 + end_position: + bytes: 292 + line: 10 + character: 81 + token_type: + type: Whitespace + characters: " " + arguments: + pairs: + - End: + name: + - leading_trivia: [] + token: + start_position: + bytes: 263 + line: 10 + character: 52 + end_position: + bytes: 268 + line: 10 + character: 57 + token_type: + type: Identifier + identifier: names + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 268 + line: 10 + character: 57 + end_position: + bytes: 269 + line: 10 + character: 58 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 269 + line: 10 + character: 58 + end_position: + bytes: 270 + line: 10 + character: 59 + token_type: + type: Whitespace + characters: " " + type_info: + Table: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 270 + line: 10 + character: 59 + end_position: + bytes: 271 + line: 10 + character: 60 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 271 + line: 10 + character: 60 + end_position: + bytes: 272 + line: 10 + character: 61 + token_type: + type: Whitespace + characters: " " + - leading_trivia: [] + token: + start_position: + bytes: 289 + line: 10 + character: 78 + end_position: + bytes: 290 + line: 10 + character: 79 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: [] + fields: + pairs: + - End: + key: + IndexSignature: + brackets: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 272 + line: 10 + character: 61 + end_position: + bytes: 273 + line: 10 + character: 62 + token_type: + type: Symbol + symbol: "[" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 279 + line: 10 + character: 68 + end_position: + bytes: 280 + line: 10 + character: 69 + token_type: + type: Symbol + symbol: "]" + trailing_trivia: [] + inner: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 273 + line: 10 + character: 62 + end_position: + bytes: 279 + line: 10 + character: 68 + token_type: + type: Identifier + identifier: number + trailing_trivia: [] + colon: + leading_trivia: [] + token: + start_position: + bytes: 280 + line: 10 + character: 69 + end_position: + bytes: 281 + line: 10 + character: 70 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 281 + line: 10 + character: 70 + end_position: + bytes: 282 + line: 10 + character: 71 + token_type: + type: Whitespace + characters: " " + value: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 282 + line: 10 + character: 71 + end_position: + bytes: 288 + line: 10 + character: 77 + token_type: + type: Identifier + identifier: string + trailing_trivia: + - start_position: + bytes: 288 + line: 10 + character: 77 + end_position: + bytes: 289 + line: 10 + character: 78 + token_type: + type: Whitespace + characters: " " + arrow: + leading_trivia: [] + token: + start_position: + bytes: 292 + line: 10 + character: 81 + end_position: + bytes: 294 + line: 10 + character: 83 + token_type: + type: Symbol + symbol: "->" + trailing_trivia: + - start_position: + bytes: 294 + line: 10 + character: 83 + end_position: + bytes: 295 + line: 10 + character: 84 + token_type: + type: Whitespace + characters: " " + return_type: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 295 + line: 10 + character: 84 + end_position: + bytes: 298 + line: 10 + character: 87 + token_type: + type: Identifier + identifier: any + trailing_trivia: [] + block: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 300 + line: 11 + character: 1 + end_position: + bytes: 303 + line: 11 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 303 + line: 11 + character: 4 + end_position: + bytes: 304 + line: 11 + character: 4 + token_type: + type: Whitespace + characters: "\n" + - ~ diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/named_function_arg_types/source.lua b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/named_function_arg_types/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..8b18eb9fee05aa1057f226f0d772e25d77575833 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/named_function_arg_types/source.lua @@ -0,0 +1,11 @@ +type MyCallbackType = (cost: number, name: string) -> string + +local cb: (amount: number) -> number +local function foo(cb: (name: string) -> unit) +end + +local function bar(x: number?): (baz: string) -> string +end + +local function bar(x: number?): (baz: string) -> ((names: { [number]: string }) -> any) +end diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/named_function_arg_types/tokens.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/named_function_arg_types/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..be7270ec714eb7f745eec7b53b9d22fe8c9cb969 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/named_function_arg_types/tokens.snap @@ -0,0 +1,1544 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: tokens +input_file: vvs_parser/tests/roblox_cases/pass/named_function_arg_types +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: type +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Identifier + identifier: MyCallbackType +- start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 22 + line: 1 + character: 23 + end_position: + bytes: 23 + line: 1 + character: 24 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 23 + line: 1 + character: 24 + end_position: + bytes: 27 + line: 1 + character: 28 + token_type: + type: Identifier + identifier: cost +- start_position: + bytes: 27 + line: 1 + character: 28 + end_position: + bytes: 28 + line: 1 + character: 29 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 28 + line: 1 + character: 29 + end_position: + bytes: 29 + line: 1 + character: 30 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 29 + line: 1 + character: 30 + end_position: + bytes: 35 + line: 1 + character: 36 + token_type: + type: Identifier + identifier: number +- start_position: + bytes: 35 + line: 1 + character: 36 + end_position: + bytes: 36 + line: 1 + character: 37 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 36 + line: 1 + character: 37 + end_position: + bytes: 37 + line: 1 + character: 38 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 37 + line: 1 + character: 38 + end_position: + bytes: 41 + line: 1 + character: 42 + token_type: + type: Identifier + identifier: name +- start_position: + bytes: 41 + line: 1 + character: 42 + end_position: + bytes: 42 + line: 1 + character: 43 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 42 + line: 1 + character: 43 + end_position: + bytes: 43 + line: 1 + character: 44 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 43 + line: 1 + character: 44 + end_position: + bytes: 49 + line: 1 + character: 50 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 49 + line: 1 + character: 50 + end_position: + bytes: 50 + line: 1 + character: 51 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 50 + line: 1 + character: 51 + end_position: + bytes: 51 + line: 1 + character: 52 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 51 + line: 1 + character: 52 + end_position: + bytes: 53 + line: 1 + character: 54 + token_type: + type: Symbol + symbol: "->" +- start_position: + bytes: 53 + line: 1 + character: 54 + end_position: + bytes: 54 + line: 1 + character: 55 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 54 + line: 1 + character: 55 + end_position: + bytes: 60 + line: 1 + character: 61 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 60 + line: 1 + character: 61 + end_position: + bytes: 61 + line: 1 + character: 61 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 61 + line: 2 + character: 1 + end_position: + bytes: 62 + line: 2 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 62 + line: 3 + character: 1 + end_position: + bytes: 67 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 67 + line: 3 + character: 6 + end_position: + bytes: 68 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 68 + line: 3 + character: 7 + end_position: + bytes: 70 + line: 3 + character: 9 + token_type: + type: Identifier + identifier: cb +- start_position: + bytes: 70 + line: 3 + character: 9 + end_position: + bytes: 71 + line: 3 + character: 10 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 71 + line: 3 + character: 10 + end_position: + bytes: 72 + line: 3 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 72 + line: 3 + character: 11 + end_position: + bytes: 73 + line: 3 + character: 12 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 73 + line: 3 + character: 12 + end_position: + bytes: 79 + line: 3 + character: 18 + token_type: + type: Identifier + identifier: amount +- start_position: + bytes: 79 + line: 3 + character: 18 + end_position: + bytes: 80 + line: 3 + character: 19 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 80 + line: 3 + character: 19 + end_position: + bytes: 81 + line: 3 + character: 20 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 81 + line: 3 + character: 20 + end_position: + bytes: 87 + line: 3 + character: 26 + token_type: + type: Identifier + identifier: number +- start_position: + bytes: 87 + line: 3 + character: 26 + end_position: + bytes: 88 + line: 3 + character: 27 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 88 + line: 3 + character: 27 + end_position: + bytes: 89 + line: 3 + character: 28 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 89 + line: 3 + character: 28 + end_position: + bytes: 91 + line: 3 + character: 30 + token_type: + type: Symbol + symbol: "->" +- start_position: + bytes: 91 + line: 3 + character: 30 + end_position: + bytes: 92 + line: 3 + character: 31 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 92 + line: 3 + character: 31 + end_position: + bytes: 98 + line: 3 + character: 37 + token_type: + type: Identifier + identifier: number +- start_position: + bytes: 98 + line: 3 + character: 37 + end_position: + bytes: 99 + line: 3 + character: 37 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 99 + line: 4 + character: 1 + end_position: + bytes: 104 + line: 4 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 104 + line: 4 + character: 6 + end_position: + bytes: 105 + line: 4 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 105 + line: 4 + character: 7 + end_position: + bytes: 113 + line: 4 + character: 15 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 113 + line: 4 + character: 15 + end_position: + bytes: 114 + line: 4 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 114 + line: 4 + character: 16 + end_position: + bytes: 117 + line: 4 + character: 19 + token_type: + type: Identifier + identifier: foo +- start_position: + bytes: 117 + line: 4 + character: 19 + end_position: + bytes: 118 + line: 4 + character: 20 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 118 + line: 4 + character: 20 + end_position: + bytes: 120 + line: 4 + character: 22 + token_type: + type: Identifier + identifier: cb +- start_position: + bytes: 120 + line: 4 + character: 22 + end_position: + bytes: 121 + line: 4 + character: 23 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 121 + line: 4 + character: 23 + end_position: + bytes: 122 + line: 4 + character: 24 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 122 + line: 4 + character: 24 + end_position: + bytes: 123 + line: 4 + character: 25 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 123 + line: 4 + character: 25 + end_position: + bytes: 127 + line: 4 + character: 29 + token_type: + type: Identifier + identifier: name +- start_position: + bytes: 127 + line: 4 + character: 29 + end_position: + bytes: 128 + line: 4 + character: 30 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 128 + line: 4 + character: 30 + end_position: + bytes: 129 + line: 4 + character: 31 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 129 + line: 4 + character: 31 + end_position: + bytes: 135 + line: 4 + character: 37 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 135 + line: 4 + character: 37 + end_position: + bytes: 136 + line: 4 + character: 38 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 136 + line: 4 + character: 38 + end_position: + bytes: 137 + line: 4 + character: 39 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 137 + line: 4 + character: 39 + end_position: + bytes: 139 + line: 4 + character: 41 + token_type: + type: Symbol + symbol: "->" +- start_position: + bytes: 139 + line: 4 + character: 41 + end_position: + bytes: 140 + line: 4 + character: 42 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 140 + line: 4 + character: 42 + end_position: + bytes: 144 + line: 4 + character: 46 + token_type: + type: Identifier + identifier: unit +- start_position: + bytes: 144 + line: 4 + character: 46 + end_position: + bytes: 145 + line: 4 + character: 47 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 145 + line: 4 + character: 47 + end_position: + bytes: 146 + line: 4 + character: 47 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 146 + line: 5 + character: 1 + end_position: + bytes: 149 + line: 5 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 149 + line: 5 + character: 4 + end_position: + bytes: 150 + line: 5 + character: 4 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 150 + line: 6 + character: 1 + end_position: + bytes: 151 + line: 6 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 151 + line: 7 + character: 1 + end_position: + bytes: 156 + line: 7 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 156 + line: 7 + character: 6 + end_position: + bytes: 157 + line: 7 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 157 + line: 7 + character: 7 + end_position: + bytes: 165 + line: 7 + character: 15 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 165 + line: 7 + character: 15 + end_position: + bytes: 166 + line: 7 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 166 + line: 7 + character: 16 + end_position: + bytes: 169 + line: 7 + character: 19 + token_type: + type: Identifier + identifier: bar +- start_position: + bytes: 169 + line: 7 + character: 19 + end_position: + bytes: 170 + line: 7 + character: 20 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 170 + line: 7 + character: 20 + end_position: + bytes: 171 + line: 7 + character: 21 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 171 + line: 7 + character: 21 + end_position: + bytes: 172 + line: 7 + character: 22 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 172 + line: 7 + character: 22 + end_position: + bytes: 173 + line: 7 + character: 23 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 173 + line: 7 + character: 23 + end_position: + bytes: 179 + line: 7 + character: 29 + token_type: + type: Identifier + identifier: number +- start_position: + bytes: 179 + line: 7 + character: 29 + end_position: + bytes: 180 + line: 7 + character: 30 + token_type: + type: Symbol + symbol: "?" +- start_position: + bytes: 180 + line: 7 + character: 30 + end_position: + bytes: 181 + line: 7 + character: 31 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 181 + line: 7 + character: 31 + end_position: + bytes: 182 + line: 7 + character: 32 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 182 + line: 7 + character: 32 + end_position: + bytes: 183 + line: 7 + character: 33 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 183 + line: 7 + character: 33 + end_position: + bytes: 184 + line: 7 + character: 34 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 184 + line: 7 + character: 34 + end_position: + bytes: 187 + line: 7 + character: 37 + token_type: + type: Identifier + identifier: baz +- start_position: + bytes: 187 + line: 7 + character: 37 + end_position: + bytes: 188 + line: 7 + character: 38 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 188 + line: 7 + character: 38 + end_position: + bytes: 189 + line: 7 + character: 39 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 189 + line: 7 + character: 39 + end_position: + bytes: 195 + line: 7 + character: 45 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 195 + line: 7 + character: 45 + end_position: + bytes: 196 + line: 7 + character: 46 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 196 + line: 7 + character: 46 + end_position: + bytes: 197 + line: 7 + character: 47 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 197 + line: 7 + character: 47 + end_position: + bytes: 199 + line: 7 + character: 49 + token_type: + type: Symbol + symbol: "->" +- start_position: + bytes: 199 + line: 7 + character: 49 + end_position: + bytes: 200 + line: 7 + character: 50 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 200 + line: 7 + character: 50 + end_position: + bytes: 206 + line: 7 + character: 56 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 206 + line: 7 + character: 56 + end_position: + bytes: 207 + line: 7 + character: 56 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 207 + line: 8 + character: 1 + end_position: + bytes: 210 + line: 8 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 210 + line: 8 + character: 4 + end_position: + bytes: 211 + line: 8 + character: 4 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 211 + line: 9 + character: 1 + end_position: + bytes: 212 + line: 9 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 212 + line: 10 + character: 1 + end_position: + bytes: 217 + line: 10 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 217 + line: 10 + character: 6 + end_position: + bytes: 218 + line: 10 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 218 + line: 10 + character: 7 + end_position: + bytes: 226 + line: 10 + character: 15 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 226 + line: 10 + character: 15 + end_position: + bytes: 227 + line: 10 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 227 + line: 10 + character: 16 + end_position: + bytes: 230 + line: 10 + character: 19 + token_type: + type: Identifier + identifier: bar +- start_position: + bytes: 230 + line: 10 + character: 19 + end_position: + bytes: 231 + line: 10 + character: 20 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 231 + line: 10 + character: 20 + end_position: + bytes: 232 + line: 10 + character: 21 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 232 + line: 10 + character: 21 + end_position: + bytes: 233 + line: 10 + character: 22 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 233 + line: 10 + character: 22 + end_position: + bytes: 234 + line: 10 + character: 23 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 234 + line: 10 + character: 23 + end_position: + bytes: 240 + line: 10 + character: 29 + token_type: + type: Identifier + identifier: number +- start_position: + bytes: 240 + line: 10 + character: 29 + end_position: + bytes: 241 + line: 10 + character: 30 + token_type: + type: Symbol + symbol: "?" +- start_position: + bytes: 241 + line: 10 + character: 30 + end_position: + bytes: 242 + line: 10 + character: 31 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 242 + line: 10 + character: 31 + end_position: + bytes: 243 + line: 10 + character: 32 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 243 + line: 10 + character: 32 + end_position: + bytes: 244 + line: 10 + character: 33 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 244 + line: 10 + character: 33 + end_position: + bytes: 245 + line: 10 + character: 34 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 245 + line: 10 + character: 34 + end_position: + bytes: 248 + line: 10 + character: 37 + token_type: + type: Identifier + identifier: baz +- start_position: + bytes: 248 + line: 10 + character: 37 + end_position: + bytes: 249 + line: 10 + character: 38 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 249 + line: 10 + character: 38 + end_position: + bytes: 250 + line: 10 + character: 39 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 250 + line: 10 + character: 39 + end_position: + bytes: 256 + line: 10 + character: 45 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 256 + line: 10 + character: 45 + end_position: + bytes: 257 + line: 10 + character: 46 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 257 + line: 10 + character: 46 + end_position: + bytes: 258 + line: 10 + character: 47 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 258 + line: 10 + character: 47 + end_position: + bytes: 260 + line: 10 + character: 49 + token_type: + type: Symbol + symbol: "->" +- start_position: + bytes: 260 + line: 10 + character: 49 + end_position: + bytes: 261 + line: 10 + character: 50 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 261 + line: 10 + character: 50 + end_position: + bytes: 262 + line: 10 + character: 51 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 262 + line: 10 + character: 51 + end_position: + bytes: 263 + line: 10 + character: 52 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 263 + line: 10 + character: 52 + end_position: + bytes: 268 + line: 10 + character: 57 + token_type: + type: Identifier + identifier: names +- start_position: + bytes: 268 + line: 10 + character: 57 + end_position: + bytes: 269 + line: 10 + character: 58 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 269 + line: 10 + character: 58 + end_position: + bytes: 270 + line: 10 + character: 59 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 270 + line: 10 + character: 59 + end_position: + bytes: 271 + line: 10 + character: 60 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 271 + line: 10 + character: 60 + end_position: + bytes: 272 + line: 10 + character: 61 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 272 + line: 10 + character: 61 + end_position: + bytes: 273 + line: 10 + character: 62 + token_type: + type: Symbol + symbol: "[" +- start_position: + bytes: 273 + line: 10 + character: 62 + end_position: + bytes: 279 + line: 10 + character: 68 + token_type: + type: Identifier + identifier: number +- start_position: + bytes: 279 + line: 10 + character: 68 + end_position: + bytes: 280 + line: 10 + character: 69 + token_type: + type: Symbol + symbol: "]" +- start_position: + bytes: 280 + line: 10 + character: 69 + end_position: + bytes: 281 + line: 10 + character: 70 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 281 + line: 10 + character: 70 + end_position: + bytes: 282 + line: 10 + character: 71 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 282 + line: 10 + character: 71 + end_position: + bytes: 288 + line: 10 + character: 77 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 288 + line: 10 + character: 77 + end_position: + bytes: 289 + line: 10 + character: 78 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 289 + line: 10 + character: 78 + end_position: + bytes: 290 + line: 10 + character: 79 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 290 + line: 10 + character: 79 + end_position: + bytes: 291 + line: 10 + character: 80 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 291 + line: 10 + character: 80 + end_position: + bytes: 292 + line: 10 + character: 81 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 292 + line: 10 + character: 81 + end_position: + bytes: 294 + line: 10 + character: 83 + token_type: + type: Symbol + symbol: "->" +- start_position: + bytes: 294 + line: 10 + character: 83 + end_position: + bytes: 295 + line: 10 + character: 84 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 295 + line: 10 + character: 84 + end_position: + bytes: 298 + line: 10 + character: 87 + token_type: + type: Identifier + identifier: any +- start_position: + bytes: 298 + line: 10 + character: 87 + end_position: + bytes: 299 + line: 10 + character: 88 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 299 + line: 10 + character: 88 + end_position: + bytes: 300 + line: 10 + character: 88 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 300 + line: 11 + character: 1 + end_position: + bytes: 303 + line: 11 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 303 + line: 11 + character: 4 + end_position: + bytes: 304 + line: 11 + character: 4 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 304 + line: 12 + character: 1 + end_position: + bytes: 304 + line: 12 + character: 1 + token_type: + type: Eof diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/no_roblox_syntax/ast.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/no_roblox_syntax/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..d8d3dfb58b4b5073f1d886a3a657f0d7050a5642 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/no_roblox_syntax/ast.snap @@ -0,0 +1,5623 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: ast.nodes() +input_file: vvs_parser/tests/roblox_cases/pass/no_roblox_syntax +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: + - start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 97 + line: 1 + character: 98 + token_type: + type: SingleLineComment + comment: " Taken from https://raw.githubusercontent.com/Kampfkarren/Roblox/master/Modules/LineOfSight.lua" + - start_position: + bytes: 97 + line: 1 + character: 98 + end_position: + bytes: 98 + line: 1 + character: 98 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 98 + line: 2 + character: 1 + end_position: + bytes: 103 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 103 + line: 2 + character: 6 + end_position: + bytes: 104 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 104 + line: 2 + character: 7 + end_position: + bytes: 121 + line: 2 + character: 24 + token_type: + type: Identifier + identifier: ReplicatedStorage + trailing_trivia: + - start_position: + bytes: 121 + line: 2 + character: 24 + end_position: + bytes: 122 + line: 2 + character: 25 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 122 + line: 2 + character: 25 + end_position: + bytes: 123 + line: 2 + character: 26 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 123 + line: 2 + character: 26 + end_position: + bytes: 124 + line: 2 + character: 27 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 124 + line: 2 + character: 27 + end_position: + bytes: 128 + line: 2 + character: 31 + token_type: + type: Identifier + identifier: game + trailing_trivia: [] + suffixes: + - Call: + MethodCall: + colon_token: + leading_trivia: [] + token: + start_position: + bytes: 128 + line: 2 + character: 31 + end_position: + bytes: 129 + line: 2 + character: 32 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 129 + line: 2 + character: 32 + end_position: + bytes: 139 + line: 2 + character: 42 + token_type: + type: Identifier + identifier: GetService + trailing_trivia: [] + args: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 139 + line: 2 + character: 42 + end_position: + bytes: 140 + line: 2 + character: 43 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 159 + line: 2 + character: 62 + end_position: + bytes: 160 + line: 2 + character: 63 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 160 + line: 2 + character: 63 + end_position: + bytes: 161 + line: 2 + character: 63 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 140 + line: 2 + character: 43 + end_position: + bytes: 159 + line: 2 + character: 62 + token_type: + type: StringLiteral + literal: ReplicatedStorage + quote_type: Double + trailing_trivia: [] + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 161 + line: 3 + character: 1 + end_position: + bytes: 166 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 166 + line: 3 + character: 6 + end_position: + bytes: 167 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 167 + line: 3 + character: 7 + end_position: + bytes: 177 + line: 3 + character: 17 + token_type: + type: Identifier + identifier: RunService + trailing_trivia: + - start_position: + bytes: 177 + line: 3 + character: 17 + end_position: + bytes: 178 + line: 3 + character: 18 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 178 + line: 3 + character: 18 + end_position: + bytes: 179 + line: 3 + character: 19 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 179 + line: 3 + character: 19 + end_position: + bytes: 180 + line: 3 + character: 20 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 180 + line: 3 + character: 20 + end_position: + bytes: 184 + line: 3 + character: 24 + token_type: + type: Identifier + identifier: game + trailing_trivia: [] + suffixes: + - Call: + MethodCall: + colon_token: + leading_trivia: [] + token: + start_position: + bytes: 184 + line: 3 + character: 24 + end_position: + bytes: 185 + line: 3 + character: 25 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 185 + line: 3 + character: 25 + end_position: + bytes: 195 + line: 3 + character: 35 + token_type: + type: Identifier + identifier: GetService + trailing_trivia: [] + args: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 195 + line: 3 + character: 35 + end_position: + bytes: 196 + line: 3 + character: 36 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 208 + line: 3 + character: 48 + end_position: + bytes: 209 + line: 3 + character: 49 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 209 + line: 3 + character: 49 + end_position: + bytes: 210 + line: 3 + character: 49 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 196 + line: 3 + character: 36 + end_position: + bytes: 208 + line: 3 + character: 48 + token_type: + type: StringLiteral + literal: RunService + quote_type: Double + trailing_trivia: [] + - ~ + - - LocalAssignment: + local_token: + leading_trivia: + - start_position: + bytes: 210 + line: 4 + character: 1 + end_position: + bytes: 211 + line: 4 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 211 + line: 5 + character: 1 + end_position: + bytes: 216 + line: 5 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 216 + line: 5 + character: 6 + end_position: + bytes: 217 + line: 5 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 217 + line: 5 + character: 7 + end_position: + bytes: 224 + line: 5 + character: 14 + token_type: + type: Identifier + identifier: Raycast + trailing_trivia: + - start_position: + bytes: 224 + line: 5 + character: 14 + end_position: + bytes: 225 + line: 5 + character: 15 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 225 + line: 5 + character: 15 + end_position: + bytes: 226 + line: 5 + character: 16 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 226 + line: 5 + character: 16 + end_position: + bytes: 227 + line: 5 + character: 17 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 227 + line: 5 + character: 17 + end_position: + bytes: 234 + line: 5 + character: 24 + token_type: + type: Identifier + identifier: require + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 234 + line: 5 + character: 24 + end_position: + bytes: 235 + line: 5 + character: 25 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 268 + line: 5 + character: 58 + end_position: + bytes: 269 + line: 5 + character: 59 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 269 + line: 5 + character: 59 + end_position: + bytes: 270 + line: 5 + character: 59 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - End: + Var: + Expression: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 235 + line: 5 + character: 25 + end_position: + bytes: 252 + line: 5 + character: 42 + token_type: + type: Identifier + identifier: ReplicatedStorage + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 252 + line: 5 + character: 42 + end_position: + bytes: 253 + line: 5 + character: 43 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 253 + line: 5 + character: 43 + end_position: + bytes: 260 + line: 5 + character: 50 + token_type: + type: Identifier + identifier: Modules + trailing_trivia: [] + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 260 + line: 5 + character: 50 + end_position: + bytes: 261 + line: 5 + character: 51 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 261 + line: 5 + character: 51 + end_position: + bytes: 268 + line: 5 + character: 58 + token_type: + type: Identifier + identifier: Raycast + trailing_trivia: [] + - ~ + - - LocalAssignment: + local_token: + leading_trivia: + - start_position: + bytes: 270 + line: 6 + character: 1 + end_position: + bytes: 271 + line: 6 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 271 + line: 7 + character: 1 + end_position: + bytes: 276 + line: 7 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 276 + line: 7 + character: 6 + end_position: + bytes: 277 + line: 7 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 277 + line: 7 + character: 7 + end_position: + bytes: 282 + line: 7 + character: 12 + token_type: + type: Identifier + identifier: DEBUG + trailing_trivia: + - start_position: + bytes: 282 + line: 7 + character: 12 + end_position: + bytes: 283 + line: 7 + character: 13 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 283 + line: 7 + character: 13 + end_position: + bytes: 284 + line: 7 + character: 14 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 284 + line: 7 + character: 14 + end_position: + bytes: 285 + line: 7 + character: 15 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Symbol: + leading_trivia: [] + token: + start_position: + bytes: 285 + line: 7 + character: 15 + end_position: + bytes: 289 + line: 7 + character: 19 + token_type: + type: Symbol + symbol: "true" + trailing_trivia: + - start_position: + bytes: 289 + line: 7 + character: 19 + end_position: + bytes: 290 + line: 7 + character: 19 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - Assignment: + var_list: + pairs: + - End: + Name: + leading_trivia: [] + token: + start_position: + bytes: 290 + line: 8 + character: 1 + end_position: + bytes: 295 + line: 8 + character: 6 + token_type: + type: Identifier + identifier: DEBUG + trailing_trivia: + - start_position: + bytes: 295 + line: 8 + character: 6 + end_position: + bytes: 296 + line: 8 + character: 7 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 296 + line: 8 + character: 7 + end_position: + bytes: 297 + line: 8 + character: 8 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 297 + line: 8 + character: 8 + end_position: + bytes: 298 + line: 8 + character: 9 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + BinaryOperator: + lhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 298 + line: 8 + character: 9 + end_position: + bytes: 303 + line: 8 + character: 14 + token_type: + type: Identifier + identifier: DEBUG + trailing_trivia: + - start_position: + bytes: 303 + line: 8 + character: 14 + end_position: + bytes: 304 + line: 8 + character: 15 + token_type: + type: Whitespace + characters: " " + binop: + And: + leading_trivia: [] + token: + start_position: + bytes: 304 + line: 8 + character: 15 + end_position: + bytes: 307 + line: 8 + character: 18 + token_type: + type: Symbol + symbol: and + trailing_trivia: + - start_position: + bytes: 307 + line: 8 + character: 18 + end_position: + bytes: 308 + line: 8 + character: 19 + token_type: + type: Whitespace + characters: " " + rhs: + FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 308 + line: 8 + character: 19 + end_position: + bytes: 318 + line: 8 + character: 29 + token_type: + type: Identifier + identifier: RunService + trailing_trivia: [] + suffixes: + - Call: + MethodCall: + colon_token: + leading_trivia: [] + token: + start_position: + bytes: 318 + line: 8 + character: 29 + end_position: + bytes: 319 + line: 8 + character: 30 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 319 + line: 8 + character: 30 + end_position: + bytes: 327 + line: 8 + character: 38 + token_type: + type: Identifier + identifier: IsStudio + trailing_trivia: [] + args: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 327 + line: 8 + character: 38 + end_position: + bytes: 328 + line: 8 + character: 39 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 328 + line: 8 + character: 39 + end_position: + bytes: 329 + line: 8 + character: 40 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 329 + line: 8 + character: 40 + end_position: + bytes: 330 + line: 8 + character: 40 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: [] + - ~ + - - LocalAssignment: + local_token: + leading_trivia: + - start_position: + bytes: 330 + line: 9 + character: 1 + end_position: + bytes: 331 + line: 9 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 331 + line: 10 + character: 1 + end_position: + bytes: 336 + line: 10 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 336 + line: 10 + character: 6 + end_position: + bytes: 337 + line: 10 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 337 + line: 10 + character: 7 + end_position: + bytes: 342 + line: 10 + character: 12 + token_type: + type: Identifier + identifier: debug + trailing_trivia: + - start_position: + bytes: 342 + line: 10 + character: 12 + end_position: + bytes: 343 + line: 10 + character: 12 + token_type: + type: Whitespace + characters: "\n" + equal_token: ~ + expr_list: + pairs: [] + - ~ + - - If: + if_token: + leading_trivia: + - start_position: + bytes: 343 + line: 11 + character: 1 + end_position: + bytes: 344 + line: 11 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 344 + line: 12 + character: 1 + end_position: + bytes: 346 + line: 12 + character: 3 + token_type: + type: Symbol + symbol: if + trailing_trivia: + - start_position: + bytes: 346 + line: 12 + character: 3 + end_position: + bytes: 347 + line: 12 + character: 4 + token_type: + type: Whitespace + characters: " " + condition: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 347 + line: 12 + character: 4 + end_position: + bytes: 352 + line: 12 + character: 9 + token_type: + type: Identifier + identifier: DEBUG + trailing_trivia: + - start_position: + bytes: 352 + line: 12 + character: 9 + end_position: + bytes: 353 + line: 12 + character: 10 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 353 + line: 12 + character: 10 + end_position: + bytes: 357 + line: 12 + character: 14 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 357 + line: 12 + character: 14 + end_position: + bytes: 358 + line: 12 + character: 14 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - FunctionDeclaration: + function_token: + leading_trivia: + - start_position: + bytes: 358 + line: 13 + character: 1 + end_position: + bytes: 359 + line: 13 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 359 + line: 13 + character: 2 + end_position: + bytes: 367 + line: 13 + character: 10 + token_type: + type: Symbol + symbol: function + trailing_trivia: + - start_position: + bytes: 367 + line: 13 + character: 10 + end_position: + bytes: 368 + line: 13 + character: 11 + token_type: + type: Whitespace + characters: " " + name: + names: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 368 + line: 13 + character: 11 + end_position: + bytes: 373 + line: 13 + character: 16 + token_type: + type: Identifier + identifier: debug + trailing_trivia: [] + colon_name: ~ + body: + parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 373 + line: 13 + character: 16 + end_position: + bytes: 374 + line: 13 + character: 17 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 379 + line: 13 + character: 22 + end_position: + bytes: 380 + line: 13 + character: 23 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 380 + line: 13 + character: 23 + end_position: + bytes: 381 + line: 13 + character: 23 + token_type: + type: Whitespace + characters: "\n" + parameters: + pairs: + - End: + name: + leading_trivia: [] + token: + start_position: + bytes: 374 + line: 13 + character: 17 + end_position: + bytes: 379 + line: 13 + character: 22 + token_type: + type: Identifier + identifier: table + trailing_trivia: [] + type_specifiers: + - ~ + block: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 381 + line: 14 + character: 1 + end_position: + bytes: 383 + line: 14 + character: 3 + token_type: + type: Whitespace + characters: "\t\t" + token: + start_position: + bytes: 383 + line: 14 + character: 3 + end_position: + bytes: 388 + line: 14 + character: 8 + token_type: + type: Identifier + identifier: print + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 388 + line: 14 + character: 8 + end_position: + bytes: 389 + line: 14 + character: 9 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 411 + line: 14 + character: 31 + end_position: + bytes: 412 + line: 14 + character: 32 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 412 + line: 14 + character: 32 + end_position: + bytes: 413 + line: 14 + character: 32 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - Punctuated: + - String: + leading_trivia: [] + token: + start_position: + bytes: 389 + line: 14 + character: 9 + end_position: + bytes: 404 + line: 14 + character: 24 + token_type: + type: StringLiteral + literal: "[LineOfSight]" + quote_type: Double + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 404 + line: 14 + character: 24 + end_position: + bytes: 405 + line: 14 + character: 25 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 405 + line: 14 + character: 25 + end_position: + bytes: 406 + line: 14 + character: 26 + token_type: + type: Whitespace + characters: " " + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 406 + line: 14 + character: 26 + end_position: + bytes: 411 + line: 14 + character: 31 + token_type: + type: Identifier + identifier: table + trailing_trivia: [] + - ~ + end_token: + leading_trivia: + - start_position: + bytes: 413 + line: 15 + character: 1 + end_position: + bytes: 414 + line: 15 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 414 + line: 15 + character: 2 + end_position: + bytes: 417 + line: 15 + character: 5 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 417 + line: 15 + character: 5 + end_position: + bytes: 418 + line: 15 + character: 5 + token_type: + type: Whitespace + characters: "\n" + - ~ + else_if: ~ + else_token: + leading_trivia: [] + token: + start_position: + bytes: 418 + line: 16 + character: 1 + end_position: + bytes: 422 + line: 16 + character: 5 + token_type: + type: Symbol + symbol: else + trailing_trivia: + - start_position: + bytes: 422 + line: 16 + character: 5 + end_position: + bytes: 423 + line: 16 + character: 5 + token_type: + type: Whitespace + characters: "\n" + else: + stmts: + - - FunctionDeclaration: + function_token: + leading_trivia: + - start_position: + bytes: 423 + line: 17 + character: 1 + end_position: + bytes: 424 + line: 17 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 424 + line: 17 + character: 2 + end_position: + bytes: 432 + line: 17 + character: 10 + token_type: + type: Symbol + symbol: function + trailing_trivia: + - start_position: + bytes: 432 + line: 17 + character: 10 + end_position: + bytes: 433 + line: 17 + character: 11 + token_type: + type: Whitespace + characters: " " + name: + names: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 433 + line: 17 + character: 11 + end_position: + bytes: 438 + line: 17 + character: 16 + token_type: + type: Identifier + identifier: debug + trailing_trivia: [] + colon_name: ~ + body: + parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 438 + line: 17 + character: 16 + end_position: + bytes: 439 + line: 17 + character: 17 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 439 + line: 17 + character: 17 + end_position: + bytes: 440 + line: 17 + character: 18 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 440 + line: 17 + character: 18 + end_position: + bytes: 441 + line: 17 + character: 18 + token_type: + type: Whitespace + characters: "\n" + parameters: + pairs: [] + type_specifiers: [] + block: + stmts: [] + end_token: + leading_trivia: + - start_position: + bytes: 441 + line: 18 + character: 1 + end_position: + bytes: 442 + line: 18 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 442 + line: 18 + character: 2 + end_position: + bytes: 445 + line: 18 + character: 5 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 445 + line: 18 + character: 5 + end_position: + bytes: 446 + line: 18 + character: 5 + token_type: + type: Whitespace + characters: "\n" + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 446 + line: 19 + character: 1 + end_position: + bytes: 449 + line: 19 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 449 + line: 19 + character: 4 + end_position: + bytes: 450 + line: 19 + character: 4 + token_type: + type: Whitespace + characters: "\n" + - ~ +last_stmt: + - Return: + token: + leading_trivia: + - start_position: + bytes: 450 + line: 20 + character: 1 + end_position: + bytes: 451 + line: 20 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 451 + line: 21 + character: 1 + end_position: + bytes: 457 + line: 21 + character: 7 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 457 + line: 21 + character: 7 + end_position: + bytes: 458 + line: 21 + character: 8 + token_type: + type: Whitespace + characters: " " + returns: + pairs: + - End: + Function: + - leading_trivia: [] + token: + start_position: + bytes: 458 + line: 21 + character: 8 + end_position: + bytes: 466 + line: 21 + character: 16 + token_type: + type: Symbol + symbol: function + trailing_trivia: [] + - parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 466 + line: 21 + character: 16 + end_position: + bytes: 467 + line: 21 + character: 17 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 512 + line: 21 + character: 62 + end_position: + bytes: 513 + line: 21 + character: 63 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 513 + line: 21 + character: 63 + end_position: + bytes: 514 + line: 21 + character: 63 + token_type: + type: Whitespace + characters: "\n" + parameters: + pairs: + - Punctuated: + - name: + leading_trivia: [] + token: + start_position: + bytes: 467 + line: 21 + character: 17 + end_position: + bytes: 473 + line: 21 + character: 23 + token_type: + type: Identifier + identifier: origin + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 473 + line: 21 + character: 23 + end_position: + bytes: 474 + line: 21 + character: 24 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 474 + line: 21 + character: 24 + end_position: + bytes: 475 + line: 21 + character: 25 + token_type: + type: Whitespace + characters: " " + - Punctuated: + - name: + leading_trivia: [] + token: + start_position: + bytes: 475 + line: 21 + character: 25 + end_position: + bytes: 484 + line: 21 + character: 34 + token_type: + type: Identifier + identifier: character + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 484 + line: 21 + character: 34 + end_position: + bytes: 485 + line: 21 + character: 35 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 485 + line: 21 + character: 35 + end_position: + bytes: 486 + line: 21 + character: 36 + token_type: + type: Whitespace + characters: " " + - Punctuated: + - name: + leading_trivia: [] + token: + start_position: + bytes: 486 + line: 21 + character: 36 + end_position: + bytes: 491 + line: 21 + character: 41 + token_type: + type: Identifier + identifier: range + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 491 + line: 21 + character: 41 + end_position: + bytes: 492 + line: 21 + character: 42 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 492 + line: 21 + character: 42 + end_position: + bytes: 493 + line: 21 + character: 43 + token_type: + type: Whitespace + characters: " " + - Punctuated: + - name: + leading_trivia: [] + token: + start_position: + bytes: 493 + line: 21 + character: 43 + end_position: + bytes: 501 + line: 21 + character: 51 + token_type: + type: Identifier + identifier: ignoreIf + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 501 + line: 21 + character: 51 + end_position: + bytes: 502 + line: 21 + character: 52 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 502 + line: 21 + character: 52 + end_position: + bytes: 503 + line: 21 + character: 53 + token_type: + type: Whitespace + characters: " " + - End: + name: + leading_trivia: [] + token: + start_position: + bytes: 503 + line: 21 + character: 53 + end_position: + bytes: 512 + line: 21 + character: 62 + token_type: + type: Identifier + identifier: blacklist + trailing_trivia: [] + type_specifiers: + - ~ + - ~ + - ~ + - ~ + - ~ + block: + stmts: + - - If: + if_token: + leading_trivia: + - start_position: + bytes: 514 + line: 22 + character: 1 + end_position: + bytes: 515 + line: 22 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 515 + line: 22 + character: 2 + end_position: + bytes: 517 + line: 22 + character: 4 + token_type: + type: Symbol + symbol: if + trailing_trivia: + - start_position: + bytes: 517 + line: 22 + character: 4 + end_position: + bytes: 518 + line: 22 + character: 5 + token_type: + type: Whitespace + characters: " " + condition: + BinaryOperator: + lhs: + FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 518 + line: 22 + character: 5 + end_position: + bytes: 524 + line: 22 + character: 11 + token_type: + type: Identifier + identifier: typeof + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 524 + line: 22 + character: 11 + end_position: + bytes: 525 + line: 22 + character: 12 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 531 + line: 22 + character: 18 + end_position: + bytes: 532 + line: 22 + character: 19 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 532 + line: 22 + character: 19 + end_position: + bytes: 533 + line: 22 + character: 20 + token_type: + type: Whitespace + characters: " " + arguments: + pairs: + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 525 + line: 22 + character: 12 + end_position: + bytes: 531 + line: 22 + character: 18 + token_type: + type: Identifier + identifier: origin + trailing_trivia: [] + binop: + TwoEqual: + leading_trivia: [] + token: + start_position: + bytes: 533 + line: 22 + character: 20 + end_position: + bytes: 535 + line: 22 + character: 22 + token_type: + type: Symbol + symbol: "==" + trailing_trivia: + - start_position: + bytes: 535 + line: 22 + character: 22 + end_position: + bytes: 536 + line: 22 + character: 23 + token_type: + type: Whitespace + characters: " " + rhs: + String: + leading_trivia: [] + token: + start_position: + bytes: 536 + line: 22 + character: 23 + end_position: + bytes: 546 + line: 22 + character: 33 + token_type: + type: StringLiteral + literal: Instance + quote_type: Double + trailing_trivia: + - start_position: + bytes: 546 + line: 22 + character: 33 + end_position: + bytes: 547 + line: 22 + character: 34 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 547 + line: 22 + character: 34 + end_position: + bytes: 551 + line: 22 + character: 38 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 551 + line: 22 + character: 38 + end_position: + bytes: 552 + line: 22 + character: 38 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - If: + if_token: + leading_trivia: + - start_position: + bytes: 552 + line: 23 + character: 1 + end_position: + bytes: 554 + line: 23 + character: 3 + token_type: + type: Whitespace + characters: "\t\t" + token: + start_position: + bytes: 554 + line: 23 + character: 3 + end_position: + bytes: 556 + line: 23 + character: 5 + token_type: + type: Symbol + symbol: if + trailing_trivia: + - start_position: + bytes: 556 + line: 23 + character: 5 + end_position: + bytes: 557 + line: 23 + character: 6 + token_type: + type: Whitespace + characters: " " + condition: + FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 557 + line: 23 + character: 6 + end_position: + bytes: 563 + line: 23 + character: 12 + token_type: + type: Identifier + identifier: origin + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 563 + line: 23 + character: 12 + end_position: + bytes: 564 + line: 23 + character: 13 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 564 + line: 23 + character: 13 + end_position: + bytes: 572 + line: 23 + character: 21 + token_type: + type: Identifier + identifier: Position + trailing_trivia: [] + - Call: + MethodCall: + colon_token: + leading_trivia: [] + token: + start_position: + bytes: 572 + line: 23 + character: 21 + end_position: + bytes: 573 + line: 23 + character: 22 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 573 + line: 23 + character: 22 + end_position: + bytes: 580 + line: 23 + character: 29 + token_type: + type: Identifier + identifier: FuzzyEq + trailing_trivia: [] + args: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 580 + line: 23 + character: 29 + end_position: + bytes: 581 + line: 23 + character: 30 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 611 + line: 23 + character: 60 + end_position: + bytes: 612 + line: 23 + character: 61 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 612 + line: 23 + character: 61 + end_position: + bytes: 613 + line: 23 + character: 62 + token_type: + type: Whitespace + characters: " " + arguments: + pairs: + - End: + Var: + Expression: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 581 + line: 23 + character: 30 + end_position: + bytes: 590 + line: 23 + character: 39 + token_type: + type: Identifier + identifier: character + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 590 + line: 23 + character: 39 + end_position: + bytes: 591 + line: 23 + character: 40 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 591 + line: 23 + character: 40 + end_position: + bytes: 602 + line: 23 + character: 51 + token_type: + type: Identifier + identifier: PrimaryPart + trailing_trivia: [] + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 602 + line: 23 + character: 51 + end_position: + bytes: 603 + line: 23 + character: 52 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 603 + line: 23 + character: 52 + end_position: + bytes: 611 + line: 23 + character: 60 + token_type: + type: Identifier + identifier: Position + trailing_trivia: [] + then_token: + leading_trivia: [] + token: + start_position: + bytes: 613 + line: 23 + character: 62 + end_position: + bytes: 617 + line: 23 + character: 66 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 617 + line: 23 + character: 66 + end_position: + bytes: 618 + line: 23 + character: 66 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 618 + line: 24 + character: 1 + end_position: + bytes: 621 + line: 24 + character: 4 + token_type: + type: Whitespace + characters: "\t\t\t" + token: + start_position: + bytes: 621 + line: 24 + character: 4 + end_position: + bytes: 626 + line: 24 + character: 9 + token_type: + type: Identifier + identifier: debug + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 626 + line: 24 + character: 9 + end_position: + bytes: 627 + line: 24 + character: 10 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 649 + line: 24 + character: 32 + end_position: + bytes: 650 + line: 24 + character: 33 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 650 + line: 24 + character: 33 + end_position: + bytes: 651 + line: 24 + character: 33 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 627 + line: 24 + character: 10 + end_position: + bytes: 649 + line: 24 + character: 32 + token_type: + type: StringLiteral + literal: ORIGIN WAS CHARACTER + quote_type: Double + trailing_trivia: [] + - ~ + last_stmt: + - Return: + token: + leading_trivia: + - start_position: + bytes: 651 + line: 25 + character: 1 + end_position: + bytes: 654 + line: 25 + character: 4 + token_type: + type: Whitespace + characters: "\t\t\t" + token: + start_position: + bytes: 654 + line: 25 + character: 4 + end_position: + bytes: 660 + line: 25 + character: 10 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 660 + line: 25 + character: 10 + end_position: + bytes: 661 + line: 25 + character: 11 + token_type: + type: Whitespace + characters: " " + returns: + pairs: + - Punctuated: + - Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 661 + line: 25 + character: 11 + end_position: + bytes: 667 + line: 25 + character: 17 + token_type: + type: Identifier + identifier: origin + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 667 + line: 25 + character: 17 + end_position: + bytes: 668 + line: 25 + character: 18 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 668 + line: 25 + character: 18 + end_position: + bytes: 669 + line: 25 + character: 19 + token_type: + type: Whitespace + characters: " " + - End: + Var: + Expression: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 669 + line: 25 + character: 19 + end_position: + bytes: 675 + line: 25 + character: 25 + token_type: + type: Identifier + identifier: origin + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 675 + line: 25 + character: 25 + end_position: + bytes: 676 + line: 25 + character: 26 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 676 + line: 25 + character: 26 + end_position: + bytes: 684 + line: 25 + character: 34 + token_type: + type: Identifier + identifier: Position + trailing_trivia: + - start_position: + bytes: 684 + line: 25 + character: 34 + end_position: + bytes: 685 + line: 25 + character: 34 + token_type: + type: Whitespace + characters: "\n" + - ~ + else_if: ~ + else_token: ~ + else: ~ + end_token: + leading_trivia: + - start_position: + bytes: 685 + line: 26 + character: 1 + end_position: + bytes: 687 + line: 26 + character: 3 + token_type: + type: Whitespace + characters: "\t\t" + token: + start_position: + bytes: 687 + line: 26 + character: 3 + end_position: + bytes: 690 + line: 26 + character: 6 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 690 + line: 26 + character: 6 + end_position: + bytes: 691 + line: 26 + character: 6 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - Assignment: + var_list: + pairs: + - End: + Name: + leading_trivia: + - start_position: + bytes: 691 + line: 27 + character: 1 + end_position: + bytes: 692 + line: 27 + character: 1 + token_type: + type: Whitespace + characters: "\n" + - start_position: + bytes: 692 + line: 28 + character: 1 + end_position: + bytes: 694 + line: 28 + character: 3 + token_type: + type: Whitespace + characters: "\t\t" + token: + start_position: + bytes: 694 + line: 28 + character: 3 + end_position: + bytes: 700 + line: 28 + character: 9 + token_type: + type: Identifier + identifier: origin + trailing_trivia: + - start_position: + bytes: 700 + line: 28 + character: 9 + end_position: + bytes: 701 + line: 28 + character: 10 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 701 + line: 28 + character: 10 + end_position: + bytes: 702 + line: 28 + character: 11 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 702 + line: 28 + character: 11 + end_position: + bytes: 703 + line: 28 + character: 12 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Var: + Expression: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 703 + line: 28 + character: 12 + end_position: + bytes: 709 + line: 28 + character: 18 + token_type: + type: Identifier + identifier: origin + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 709 + line: 28 + character: 18 + end_position: + bytes: 710 + line: 28 + character: 19 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 710 + line: 28 + character: 19 + end_position: + bytes: 718 + line: 28 + character: 27 + token_type: + type: Identifier + identifier: Position + trailing_trivia: + - start_position: + bytes: 718 + line: 28 + character: 27 + end_position: + bytes: 719 + line: 28 + character: 27 + token_type: + type: Whitespace + characters: "\n" + - ~ + else_if: ~ + else_token: ~ + else: ~ + end_token: + leading_trivia: + - start_position: + bytes: 719 + line: 29 + character: 1 + end_position: + bytes: 720 + line: 29 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 720 + line: 29 + character: 2 + end_position: + bytes: 723 + line: 29 + character: 5 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 723 + line: 29 + character: 5 + end_position: + bytes: 724 + line: 29 + character: 5 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - Assignment: + var_list: + pairs: + - End: + Name: + leading_trivia: + - start_position: + bytes: 724 + line: 30 + character: 1 + end_position: + bytes: 725 + line: 30 + character: 1 + token_type: + type: Whitespace + characters: "\n" + - start_position: + bytes: 725 + line: 31 + character: 1 + end_position: + bytes: 726 + line: 31 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 726 + line: 31 + character: 2 + end_position: + bytes: 735 + line: 31 + character: 11 + token_type: + type: Identifier + identifier: blacklist + trailing_trivia: + - start_position: + bytes: 735 + line: 31 + character: 11 + end_position: + bytes: 736 + line: 31 + character: 12 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 736 + line: 31 + character: 12 + end_position: + bytes: 737 + line: 31 + character: 13 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 737 + line: 31 + character: 13 + end_position: + bytes: 738 + line: 31 + character: 14 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + BinaryOperator: + lhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 738 + line: 31 + character: 14 + end_position: + bytes: 747 + line: 31 + character: 23 + token_type: + type: Identifier + identifier: blacklist + trailing_trivia: + - start_position: + bytes: 747 + line: 31 + character: 23 + end_position: + bytes: 748 + line: 31 + character: 24 + token_type: + type: Whitespace + characters: " " + binop: + Or: + leading_trivia: [] + token: + start_position: + bytes: 748 + line: 31 + character: 24 + end_position: + bytes: 750 + line: 31 + character: 26 + token_type: + type: Symbol + symbol: or + trailing_trivia: + - start_position: + bytes: 750 + line: 31 + character: 26 + end_position: + bytes: 751 + line: 31 + character: 27 + token_type: + type: Whitespace + characters: " " + rhs: + TableConstructor: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 751 + line: 31 + character: 27 + end_position: + bytes: 752 + line: 31 + character: 28 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 752 + line: 31 + character: 28 + end_position: + bytes: 753 + line: 31 + character: 29 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: + - start_position: + bytes: 753 + line: 31 + character: 29 + end_position: + bytes: 754 + line: 31 + character: 29 + token_type: + type: Whitespace + characters: "\n" + fields: + pairs: [] + - ~ + - - LocalAssignment: + local_token: + leading_trivia: + - start_position: + bytes: 754 + line: 32 + character: 1 + end_position: + bytes: 755 + line: 32 + character: 1 + token_type: + type: Whitespace + characters: "\n" + - start_position: + bytes: 755 + line: 33 + character: 1 + end_position: + bytes: 756 + line: 33 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 756 + line: 33 + character: 2 + end_position: + bytes: 761 + line: 33 + character: 7 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 761 + line: 33 + character: 7 + end_position: + bytes: 762 + line: 33 + character: 8 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - Punctuated: + - leading_trivia: [] + token: + start_position: + bytes: 762 + line: 33 + character: 8 + end_position: + bytes: 765 + line: 33 + character: 11 + token_type: + type: Identifier + identifier: hit + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 765 + line: 33 + character: 11 + end_position: + bytes: 766 + line: 33 + character: 12 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 766 + line: 33 + character: 12 + end_position: + bytes: 767 + line: 33 + character: 13 + token_type: + type: Whitespace + characters: " " + - End: + leading_trivia: [] + token: + start_position: + bytes: 767 + line: 33 + character: 13 + end_position: + bytes: 772 + line: 33 + character: 18 + token_type: + type: Identifier + identifier: point + trailing_trivia: + - start_position: + bytes: 772 + line: 33 + character: 18 + end_position: + bytes: 773 + line: 33 + character: 19 + token_type: + type: Whitespace + characters: " " + equal_token: ~ + expr_list: + pairs: [] + - ~ + - - Do: + do_token: + leading_trivia: [] + token: + start_position: + bytes: 773 + line: 33 + character: 19 + end_position: + bytes: 775 + line: 33 + character: 21 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 775 + line: 33 + character: 21 + end_position: + bytes: 776 + line: 33 + character: 21 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - While: + while_token: + leading_trivia: + - start_position: + bytes: 776 + line: 34 + character: 1 + end_position: + bytes: 778 + line: 34 + character: 3 + token_type: + type: Whitespace + characters: "\t\t" + token: + start_position: + bytes: 778 + line: 34 + character: 3 + end_position: + bytes: 783 + line: 34 + character: 8 + token_type: + type: Symbol + symbol: while + trailing_trivia: + - start_position: + bytes: 783 + line: 34 + character: 8 + end_position: + bytes: 784 + line: 34 + character: 9 + token_type: + type: Whitespace + characters: " " + condition: + Symbol: + leading_trivia: [] + token: + start_position: + bytes: 784 + line: 34 + character: 9 + end_position: + bytes: 788 + line: 34 + character: 13 + token_type: + type: Symbol + symbol: "true" + trailing_trivia: + - start_position: + bytes: 788 + line: 34 + character: 13 + end_position: + bytes: 789 + line: 34 + character: 14 + token_type: + type: Whitespace + characters: " " + do_token: + leading_trivia: [] + token: + start_position: + bytes: 789 + line: 34 + character: 14 + end_position: + bytes: 791 + line: 34 + character: 16 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 791 + line: 34 + character: 16 + end_position: + bytes: 792 + line: 34 + character: 16 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - Assignment: + var_list: + pairs: + - Punctuated: + - Name: + leading_trivia: + - start_position: + bytes: 792 + line: 35 + character: 1 + end_position: + bytes: 795 + line: 35 + character: 4 + token_type: + type: Whitespace + characters: "\t\t\t" + token: + start_position: + bytes: 795 + line: 35 + character: 4 + end_position: + bytes: 798 + line: 35 + character: 7 + token_type: + type: Identifier + identifier: hit + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 798 + line: 35 + character: 7 + end_position: + bytes: 799 + line: 35 + character: 8 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 799 + line: 35 + character: 8 + end_position: + bytes: 800 + line: 35 + character: 9 + token_type: + type: Whitespace + characters: " " + - End: + Name: + leading_trivia: [] + token: + start_position: + bytes: 800 + line: 35 + character: 9 + end_position: + bytes: 805 + line: 35 + character: 14 + token_type: + type: Identifier + identifier: point + trailing_trivia: + - start_position: + bytes: 805 + line: 35 + character: 14 + end_position: + bytes: 806 + line: 35 + character: 15 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 806 + line: 35 + character: 15 + end_position: + bytes: 807 + line: 35 + character: 16 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 807 + line: 35 + character: 16 + end_position: + bytes: 808 + line: 35 + character: 17 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 808 + line: 35 + character: 17 + end_position: + bytes: 815 + line: 35 + character: 24 + token_type: + type: Identifier + identifier: Raycast + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 815 + line: 35 + character: 24 + end_position: + bytes: 816 + line: 35 + character: 25 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 899 + line: 35 + character: 108 + end_position: + bytes: 900 + line: 35 + character: 109 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 900 + line: 35 + character: 109 + end_position: + bytes: 901 + line: 35 + character: 109 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - Punctuated: + - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 816 + line: 35 + character: 25 + end_position: + bytes: 819 + line: 35 + character: 28 + token_type: + type: Identifier + identifier: Ray + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 819 + line: 35 + character: 28 + end_position: + bytes: 820 + line: 35 + character: 29 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 820 + line: 35 + character: 29 + end_position: + bytes: 823 + line: 35 + character: 32 + token_type: + type: Identifier + identifier: new + trailing_trivia: [] + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 823 + line: 35 + character: 32 + end_position: + bytes: 824 + line: 35 + character: 33 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 887 + line: 35 + character: 96 + end_position: + bytes: 888 + line: 35 + character: 97 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: + - Punctuated: + - Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 824 + line: 35 + character: 33 + end_position: + bytes: 830 + line: 35 + character: 39 + token_type: + type: Identifier + identifier: origin + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 830 + line: 35 + character: 39 + end_position: + bytes: 831 + line: 35 + character: 40 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 831 + line: 35 + character: 40 + end_position: + bytes: 832 + line: 35 + character: 41 + token_type: + type: Whitespace + characters: " " + - End: + BinaryOperator: + lhs: + Var: + Expression: + prefix: + Expression: + Parentheses: + contained: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 832 + line: 35 + character: 41 + end_position: + bytes: 833 + line: 35 + character: 42 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 872 + line: 35 + character: 81 + end_position: + bytes: 873 + line: 35 + character: 82 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + expression: + BinaryOperator: + lhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 833 + line: 35 + character: 42 + end_position: + bytes: 839 + line: 35 + character: 48 + token_type: + type: Identifier + identifier: origin + trailing_trivia: + - start_position: + bytes: 839 + line: 35 + character: 48 + end_position: + bytes: 840 + line: 35 + character: 49 + token_type: + type: Whitespace + characters: " " + binop: + Minus: + leading_trivia: [] + token: + start_position: + bytes: 840 + line: 35 + character: 49 + end_position: + bytes: 841 + line: 35 + character: 50 + token_type: + type: Symbol + symbol: "-" + trailing_trivia: + - start_position: + bytes: 841 + line: 35 + character: 50 + end_position: + bytes: 842 + line: 35 + character: 51 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Expression: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 842 + line: 35 + character: 51 + end_position: + bytes: 851 + line: 35 + character: 60 + token_type: + type: Identifier + identifier: character + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 851 + line: 35 + character: 60 + end_position: + bytes: 852 + line: 35 + character: 61 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 852 + line: 35 + character: 61 + end_position: + bytes: 863 + line: 35 + character: 72 + token_type: + type: Identifier + identifier: PrimaryPart + trailing_trivia: [] + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 863 + line: 35 + character: 72 + end_position: + bytes: 864 + line: 35 + character: 73 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 864 + line: 35 + character: 73 + end_position: + bytes: 872 + line: 35 + character: 81 + token_type: + type: Identifier + identifier: Position + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 873 + line: 35 + character: 82 + end_position: + bytes: 874 + line: 35 + character: 83 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 874 + line: 35 + character: 83 + end_position: + bytes: 878 + line: 35 + character: 87 + token_type: + type: Identifier + identifier: Unit + trailing_trivia: + - start_position: + bytes: 878 + line: 35 + character: 87 + end_position: + bytes: 879 + line: 35 + character: 88 + token_type: + type: Whitespace + characters: " " + binop: + Star: + leading_trivia: [] + token: + start_position: + bytes: 879 + line: 35 + character: 88 + end_position: + bytes: 880 + line: 35 + character: 89 + token_type: + type: Symbol + symbol: "*" + trailing_trivia: + - start_position: + bytes: 880 + line: 35 + character: 89 + end_position: + bytes: 881 + line: 35 + character: 90 + token_type: + type: Whitespace + characters: " " + rhs: + UnaryOperator: + unop: + Minus: + leading_trivia: [] + token: + start_position: + bytes: 881 + line: 35 + character: 90 + end_position: + bytes: 882 + line: 35 + character: 91 + token_type: + type: Symbol + symbol: "-" + trailing_trivia: [] + expression: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 882 + line: 35 + character: 91 + end_position: + bytes: 887 + line: 35 + character: 96 + token_type: + type: Identifier + identifier: range + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 888 + line: 35 + character: 97 + end_position: + bytes: 889 + line: 35 + character: 98 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 889 + line: 35 + character: 98 + end_position: + bytes: 890 + line: 35 + character: 99 + token_type: + type: Whitespace + characters: " " + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 890 + line: 35 + character: 99 + end_position: + bytes: 899 + line: 35 + character: 108 + token_type: + type: Identifier + identifier: blacklist + trailing_trivia: [] + - ~ + - - If: + if_token: + leading_trivia: + - start_position: + bytes: 901 + line: 36 + character: 1 + end_position: + bytes: 902 + line: 36 + character: 1 + token_type: + type: Whitespace + characters: "\n" + - start_position: + bytes: 902 + line: 37 + character: 1 + end_position: + bytes: 905 + line: 37 + character: 4 + token_type: + type: Whitespace + characters: "\t\t\t" + token: + start_position: + bytes: 905 + line: 37 + character: 4 + end_position: + bytes: 907 + line: 37 + character: 6 + token_type: + type: Symbol + symbol: if + trailing_trivia: + - start_position: + bytes: 907 + line: 37 + character: 6 + end_position: + bytes: 908 + line: 37 + character: 7 + token_type: + type: Whitespace + characters: " " + condition: + BinaryOperator: + lhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 908 + line: 37 + character: 7 + end_position: + bytes: 911 + line: 37 + character: 10 + token_type: + type: Identifier + identifier: hit + trailing_trivia: + - start_position: + bytes: 911 + line: 37 + character: 10 + end_position: + bytes: 912 + line: 37 + character: 11 + token_type: + type: Whitespace + characters: " " + binop: + And: + leading_trivia: [] + token: + start_position: + bytes: 912 + line: 37 + character: 11 + end_position: + bytes: 915 + line: 37 + character: 14 + token_type: + type: Symbol + symbol: and + trailing_trivia: + - start_position: + bytes: 915 + line: 37 + character: 14 + end_position: + bytes: 916 + line: 37 + character: 15 + token_type: + type: Whitespace + characters: " " + rhs: + FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 916 + line: 37 + character: 15 + end_position: + bytes: 919 + line: 37 + character: 18 + token_type: + type: Identifier + identifier: hit + trailing_trivia: [] + suffixes: + - Call: + MethodCall: + colon_token: + leading_trivia: [] + token: + start_position: + bytes: 919 + line: 37 + character: 18 + end_position: + bytes: 920 + line: 37 + character: 19 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 920 + line: 37 + character: 19 + end_position: + bytes: 934 + line: 37 + character: 33 + token_type: + type: Identifier + identifier: IsDescendantOf + trailing_trivia: [] + args: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 934 + line: 37 + character: 33 + end_position: + bytes: 935 + line: 37 + character: 34 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 944 + line: 37 + character: 43 + end_position: + bytes: 945 + line: 37 + character: 44 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 945 + line: 37 + character: 44 + end_position: + bytes: 946 + line: 37 + character: 45 + token_type: + type: Whitespace + characters: " " + arguments: + pairs: + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 935 + line: 37 + character: 34 + end_position: + bytes: 944 + line: 37 + character: 43 + token_type: + type: Identifier + identifier: character + trailing_trivia: [] + then_token: + leading_trivia: [] + token: + start_position: + bytes: 946 + line: 37 + character: 45 + end_position: + bytes: 950 + line: 37 + character: 49 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 950 + line: 37 + character: 49 + end_position: + bytes: 951 + line: 37 + character: 49 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: [] + last_stmt: + - Break: + leading_trivia: + - start_position: + bytes: 951 + line: 38 + character: 1 + end_position: + bytes: 955 + line: 38 + character: 5 + token_type: + type: Whitespace + characters: "\t\t\t\t" + token: + start_position: + bytes: 955 + line: 38 + character: 5 + end_position: + bytes: 960 + line: 38 + character: 10 + token_type: + type: Symbol + symbol: break + trailing_trivia: + - start_position: + bytes: 960 + line: 38 + character: 10 + end_position: + bytes: 961 + line: 38 + character: 10 + token_type: + type: Whitespace + characters: "\n" + - ~ + else_if: + - else_if_token: + leading_trivia: + - start_position: + bytes: 961 + line: 39 + character: 1 + end_position: + bytes: 964 + line: 39 + character: 4 + token_type: + type: Whitespace + characters: "\t\t\t" + token: + start_position: + bytes: 964 + line: 39 + character: 4 + end_position: + bytes: 970 + line: 39 + character: 10 + token_type: + type: Symbol + symbol: elseif + trailing_trivia: + - start_position: + bytes: 970 + line: 39 + character: 10 + end_position: + bytes: 971 + line: 39 + character: 11 + token_type: + type: Whitespace + characters: " " + condition: + BinaryOperator: + lhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 971 + line: 39 + character: 11 + end_position: + bytes: 974 + line: 39 + character: 14 + token_type: + type: Identifier + identifier: hit + trailing_trivia: + - start_position: + bytes: 974 + line: 39 + character: 14 + end_position: + bytes: 975 + line: 39 + character: 15 + token_type: + type: Whitespace + characters: " " + binop: + And: + leading_trivia: [] + token: + start_position: + bytes: 975 + line: 39 + character: 15 + end_position: + bytes: 978 + line: 39 + character: 18 + token_type: + type: Symbol + symbol: and + trailing_trivia: + - start_position: + bytes: 978 + line: 39 + character: 18 + end_position: + bytes: 979 + line: 39 + character: 19 + token_type: + type: Whitespace + characters: " " + rhs: + FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 979 + line: 39 + character: 19 + end_position: + bytes: 987 + line: 39 + character: 27 + token_type: + type: Identifier + identifier: ignoreIf + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 987 + line: 39 + character: 27 + end_position: + bytes: 988 + line: 39 + character: 28 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 991 + line: 39 + character: 31 + end_position: + bytes: 992 + line: 39 + character: 32 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 992 + line: 39 + character: 32 + end_position: + bytes: 993 + line: 39 + character: 33 + token_type: + type: Whitespace + characters: " " + arguments: + pairs: + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 988 + line: 39 + character: 28 + end_position: + bytes: 991 + line: 39 + character: 31 + token_type: + type: Identifier + identifier: hit + trailing_trivia: [] + then_token: + leading_trivia: [] + token: + start_position: + bytes: 993 + line: 39 + character: 33 + end_position: + bytes: 997 + line: 39 + character: 37 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 997 + line: 39 + character: 37 + end_position: + bytes: 998 + line: 39 + character: 37 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 998 + line: 40 + character: 1 + end_position: + bytes: 1002 + line: 40 + character: 5 + token_type: + type: Whitespace + characters: "\t\t\t\t" + token: + start_position: + bytes: 1002 + line: 40 + character: 5 + end_position: + bytes: 1007 + line: 40 + character: 10 + token_type: + type: Identifier + identifier: debug + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 1007 + line: 40 + character: 10 + end_position: + bytes: 1008 + line: 40 + character: 11 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 1044 + line: 40 + character: 47 + end_position: + bytes: 1045 + line: 40 + character: 48 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 1045 + line: 40 + character: 48 + end_position: + bytes: 1046 + line: 40 + character: 48 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - Punctuated: + - String: + leading_trivia: [] + token: + start_position: + bytes: 1008 + line: 40 + character: 11 + end_position: + bytes: 1025 + line: 40 + character: 28 + token_type: + type: StringLiteral + literal: IGNORING OFF IF + quote_type: Double + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 1025 + line: 40 + character: 28 + end_position: + bytes: 1026 + line: 40 + character: 29 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 1026 + line: 40 + character: 29 + end_position: + bytes: 1027 + line: 40 + character: 30 + token_type: + type: Whitespace + characters: " " + - End: + FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 1027 + line: 40 + character: 30 + end_position: + bytes: 1030 + line: 40 + character: 33 + token_type: + type: Identifier + identifier: hit + trailing_trivia: [] + suffixes: + - Call: + MethodCall: + colon_token: + leading_trivia: [] + token: + start_position: + bytes: 1030 + line: 40 + character: 33 + end_position: + bytes: 1031 + line: 40 + character: 34 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 1031 + line: 40 + character: 34 + end_position: + bytes: 1042 + line: 40 + character: 45 + token_type: + type: Identifier + identifier: GetFullName + trailing_trivia: [] + args: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 1042 + line: 40 + character: 45 + end_position: + bytes: 1043 + line: 40 + character: 46 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 1043 + line: 40 + character: 46 + end_position: + bytes: 1044 + line: 40 + character: 47 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: [] + - ~ + - - Assignment: + var_list: + pairs: + - End: + Expression: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 1046 + line: 41 + character: 1 + end_position: + bytes: 1050 + line: 41 + character: 5 + token_type: + type: Whitespace + characters: "\t\t\t\t" + token: + start_position: + bytes: 1050 + line: 41 + character: 5 + end_position: + bytes: 1059 + line: 41 + character: 14 + token_type: + type: Identifier + identifier: blacklist + trailing_trivia: [] + suffixes: + - Index: + Brackets: + brackets: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 1059 + line: 41 + character: 14 + end_position: + bytes: 1060 + line: 41 + character: 15 + token_type: + type: Symbol + symbol: "[" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 1074 + line: 41 + character: 29 + end_position: + bytes: 1075 + line: 41 + character: 30 + token_type: + type: Symbol + symbol: "]" + trailing_trivia: + - start_position: + bytes: 1075 + line: 41 + character: 30 + end_position: + bytes: 1076 + line: 41 + character: 31 + token_type: + type: Whitespace + characters: " " + expression: + BinaryOperator: + lhs: + UnaryOperator: + unop: + Hash: + leading_trivia: [] + token: + start_position: + bytes: 1060 + line: 41 + character: 15 + end_position: + bytes: 1061 + line: 41 + character: 16 + token_type: + type: Symbol + symbol: "#" + trailing_trivia: [] + expression: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 1061 + line: 41 + character: 16 + end_position: + bytes: 1070 + line: 41 + character: 25 + token_type: + type: Identifier + identifier: blacklist + trailing_trivia: + - start_position: + bytes: 1070 + line: 41 + character: 25 + end_position: + bytes: 1071 + line: 41 + character: 26 + token_type: + type: Whitespace + characters: " " + binop: + Plus: + leading_trivia: [] + token: + start_position: + bytes: 1071 + line: 41 + character: 26 + end_position: + bytes: 1072 + line: 41 + character: 27 + token_type: + type: Symbol + symbol: + + trailing_trivia: + - start_position: + bytes: 1072 + line: 41 + character: 27 + end_position: + bytes: 1073 + line: 41 + character: 28 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 1073 + line: 41 + character: 28 + end_position: + bytes: 1074 + line: 41 + character: 29 + token_type: + type: Number + text: "1" + trailing_trivia: [] + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 1076 + line: 41 + character: 31 + end_position: + bytes: 1077 + line: 41 + character: 32 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 1077 + line: 41 + character: 32 + end_position: + bytes: 1078 + line: 41 + character: 33 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 1078 + line: 41 + character: 33 + end_position: + bytes: 1081 + line: 41 + character: 36 + token_type: + type: Identifier + identifier: hit + trailing_trivia: + - start_position: + bytes: 1081 + line: 41 + character: 36 + end_position: + bytes: 1082 + line: 41 + character: 36 + token_type: + type: Whitespace + characters: "\n" + - ~ + else_token: + leading_trivia: + - start_position: + bytes: 1082 + line: 42 + character: 1 + end_position: + bytes: 1085 + line: 42 + character: 4 + token_type: + type: Whitespace + characters: "\t\t\t" + token: + start_position: + bytes: 1085 + line: 42 + character: 4 + end_position: + bytes: 1089 + line: 42 + character: 8 + token_type: + type: Symbol + symbol: else + trailing_trivia: + - start_position: + bytes: 1089 + line: 42 + character: 8 + end_position: + bytes: 1090 + line: 42 + character: 8 + token_type: + type: Whitespace + characters: "\n" + else: + stmts: [] + last_stmt: + - Break: + leading_trivia: + - start_position: + bytes: 1090 + line: 43 + character: 1 + end_position: + bytes: 1094 + line: 43 + character: 5 + token_type: + type: Whitespace + characters: "\t\t\t\t" + token: + start_position: + bytes: 1094 + line: 43 + character: 5 + end_position: + bytes: 1099 + line: 43 + character: 10 + token_type: + type: Symbol + symbol: break + trailing_trivia: + - start_position: + bytes: 1099 + line: 43 + character: 10 + end_position: + bytes: 1100 + line: 43 + character: 10 + token_type: + type: Whitespace + characters: "\n" + - ~ + end_token: + leading_trivia: + - start_position: + bytes: 1100 + line: 44 + character: 1 + end_position: + bytes: 1103 + line: 44 + character: 4 + token_type: + type: Whitespace + characters: "\t\t\t" + token: + start_position: + bytes: 1103 + line: 44 + character: 4 + end_position: + bytes: 1106 + line: 44 + character: 7 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 1106 + line: 44 + character: 7 + end_position: + bytes: 1107 + line: 44 + character: 7 + token_type: + type: Whitespace + characters: "\n" + - ~ + end_token: + leading_trivia: + - start_position: + bytes: 1107 + line: 45 + character: 1 + end_position: + bytes: 1109 + line: 45 + character: 3 + token_type: + type: Whitespace + characters: "\t\t" + token: + start_position: + bytes: 1109 + line: 45 + character: 3 + end_position: + bytes: 1112 + line: 45 + character: 6 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 1112 + line: 45 + character: 6 + end_position: + bytes: 1113 + line: 45 + character: 6 + token_type: + type: Whitespace + characters: "\n" + - ~ + end_token: + leading_trivia: + - start_position: + bytes: 1113 + line: 46 + character: 1 + end_position: + bytes: 1114 + line: 46 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 1114 + line: 46 + character: 2 + end_position: + bytes: 1117 + line: 46 + character: 5 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 1117 + line: 46 + character: 5 + end_position: + bytes: 1118 + line: 46 + character: 5 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 1118 + line: 47 + character: 1 + end_position: + bytes: 1119 + line: 47 + character: 1 + token_type: + type: Whitespace + characters: "\n" + - start_position: + bytes: 1119 + line: 48 + character: 1 + end_position: + bytes: 1120 + line: 48 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 1120 + line: 48 + character: 2 + end_position: + bytes: 1125 + line: 48 + character: 7 + token_type: + type: Identifier + identifier: debug + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 1125 + line: 48 + character: 7 + end_position: + bytes: 1126 + line: 48 + character: 8 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 1165 + line: 48 + character: 47 + end_position: + bytes: 1166 + line: 48 + character: 48 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 1166 + line: 48 + character: 48 + end_position: + bytes: 1167 + line: 48 + character: 48 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - Punctuated: + - String: + leading_trivia: [] + token: + start_position: + bytes: 1126 + line: 48 + character: 8 + end_position: + bytes: 1138 + line: 48 + character: 20 + token_type: + type: StringLiteral + literal: LOS RESULT + quote_type: Double + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 1138 + line: 48 + character: 20 + end_position: + bytes: 1139 + line: 48 + character: 21 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 1139 + line: 48 + character: 21 + end_position: + bytes: 1140 + line: 48 + character: 22 + token_type: + type: Whitespace + characters: " " + - End: + BinaryOperator: + lhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 1140 + line: 48 + character: 22 + end_position: + bytes: 1143 + line: 48 + character: 25 + token_type: + type: Identifier + identifier: hit + trailing_trivia: + - start_position: + bytes: 1143 + line: 48 + character: 25 + end_position: + bytes: 1144 + line: 48 + character: 26 + token_type: + type: Whitespace + characters: " " + binop: + And: + leading_trivia: [] + token: + start_position: + bytes: 1144 + line: 48 + character: 26 + end_position: + bytes: 1147 + line: 48 + character: 29 + token_type: + type: Symbol + symbol: and + trailing_trivia: + - start_position: + bytes: 1147 + line: 48 + character: 29 + end_position: + bytes: 1148 + line: 48 + character: 30 + token_type: + type: Whitespace + characters: " " + rhs: + FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 1148 + line: 48 + character: 30 + end_position: + bytes: 1151 + line: 48 + character: 33 + token_type: + type: Identifier + identifier: hit + trailing_trivia: [] + suffixes: + - Call: + MethodCall: + colon_token: + leading_trivia: [] + token: + start_position: + bytes: 1151 + line: 48 + character: 33 + end_position: + bytes: 1152 + line: 48 + character: 34 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 1152 + line: 48 + character: 34 + end_position: + bytes: 1163 + line: 48 + character: 45 + token_type: + type: Identifier + identifier: GetFullName + trailing_trivia: [] + args: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 1163 + line: 48 + character: 45 + end_position: + bytes: 1164 + line: 48 + character: 46 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 1164 + line: 48 + character: 46 + end_position: + bytes: 1165 + line: 48 + character: 47 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: [] + - ~ + last_stmt: + - Return: + token: + leading_trivia: + - start_position: + bytes: 1167 + line: 49 + character: 1 + end_position: + bytes: 1168 + line: 49 + character: 1 + token_type: + type: Whitespace + characters: "\n" + - start_position: + bytes: 1168 + line: 50 + character: 1 + end_position: + bytes: 1169 + line: 50 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 1169 + line: 50 + character: 2 + end_position: + bytes: 1175 + line: 50 + character: 8 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 1175 + line: 50 + character: 8 + end_position: + bytes: 1176 + line: 50 + character: 9 + token_type: + type: Whitespace + characters: " " + returns: + pairs: + - Punctuated: + - BinaryOperator: + lhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 1176 + line: 50 + character: 9 + end_position: + bytes: 1179 + line: 50 + character: 12 + token_type: + type: Identifier + identifier: hit + trailing_trivia: + - start_position: + bytes: 1179 + line: 50 + character: 12 + end_position: + bytes: 1180 + line: 50 + character: 13 + token_type: + type: Whitespace + characters: " " + binop: + And: + leading_trivia: [] + token: + start_position: + bytes: 1180 + line: 50 + character: 13 + end_position: + bytes: 1183 + line: 50 + character: 16 + token_type: + type: Symbol + symbol: and + trailing_trivia: + - start_position: + bytes: 1183 + line: 50 + character: 16 + end_position: + bytes: 1184 + line: 50 + character: 17 + token_type: + type: Whitespace + characters: " " + rhs: + FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 1184 + line: 50 + character: 17 + end_position: + bytes: 1187 + line: 50 + character: 20 + token_type: + type: Identifier + identifier: hit + trailing_trivia: [] + suffixes: + - Call: + MethodCall: + colon_token: + leading_trivia: [] + token: + start_position: + bytes: 1187 + line: 50 + character: 20 + end_position: + bytes: 1188 + line: 50 + character: 21 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 1188 + line: 50 + character: 21 + end_position: + bytes: 1202 + line: 50 + character: 35 + token_type: + type: Identifier + identifier: IsDescendantOf + trailing_trivia: [] + args: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 1202 + line: 50 + character: 35 + end_position: + bytes: 1203 + line: 50 + character: 36 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 1212 + line: 50 + character: 45 + end_position: + bytes: 1213 + line: 50 + character: 46 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 1203 + line: 50 + character: 36 + end_position: + bytes: 1212 + line: 50 + character: 45 + token_type: + type: Identifier + identifier: character + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 1213 + line: 50 + character: 46 + end_position: + bytes: 1214 + line: 50 + character: 47 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 1214 + line: 50 + character: 47 + end_position: + bytes: 1215 + line: 50 + character: 48 + token_type: + type: Whitespace + characters: " " + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 1215 + line: 50 + character: 48 + end_position: + bytes: 1220 + line: 50 + character: 53 + token_type: + type: Identifier + identifier: point + trailing_trivia: + - start_position: + bytes: 1220 + line: 50 + character: 53 + end_position: + bytes: 1221 + line: 50 + character: 53 + token_type: + type: Whitespace + characters: "\n" + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 1221 + line: 51 + character: 1 + end_position: + bytes: 1224 + line: 51 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 1224 + line: 51 + character: 4 + end_position: + bytes: 1225 + line: 51 + character: 4 + token_type: + type: Whitespace + characters: "\n" + - ~ diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/no_roblox_syntax/source.lua b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/no_roblox_syntax/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..e86cb5822206891b034e255015f9c2a094566b50 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/no_roblox_syntax/source.lua @@ -0,0 +1,51 @@ +-- Taken from https://raw.githubusercontent.com/Kampfkarren/Roblox/master/Modules/LineOfSight.lua +local ReplicatedStorage = game:GetService("ReplicatedStorage") +local RunService = game:GetService("RunService") + +local Raycast = require(ReplicatedStorage.Modules.Raycast) + +local DEBUG = true +DEBUG = DEBUG and RunService:IsStudio() + +local debug + +if DEBUG then + function debug(table) + print("[LineOfSight]", table) + end +else + function debug() + end +end + +return function(origin, character, range, ignoreIf, blacklist) + if typeof(origin) == "Instance" then + if origin.Position:FuzzyEq(character.PrimaryPart.Position) then + debug("ORIGIN WAS CHARACTER") + return origin, origin.Position + end + + origin = origin.Position + end + + blacklist = blacklist or {} + + local hit, point do + while true do + hit, point = Raycast(Ray.new(origin, (origin - character.PrimaryPart.Position).Unit * -range), blacklist) + + if hit and hit:IsDescendantOf(character) then + break + elseif hit and ignoreIf(hit) then + debug("IGNORING OFF IF", hit:GetFullName()) + blacklist[#blacklist + 1] = hit + else + break + end + end + end + + debug("LOS RESULT", hit and hit:GetFullName()) + + return hit and hit:IsDescendantOf(character), point +end diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/no_roblox_syntax/tokens.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/no_roblox_syntax/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..1398d79266a7379872f00a5001eaf14de2185037 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/no_roblox_syntax/tokens.snap @@ -0,0 +1,4246 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: tokens +input_file: vvs_parser/tests/roblox_cases/pass/no_roblox_syntax +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 97 + line: 1 + character: 98 + token_type: + type: SingleLineComment + comment: " Taken from https://raw.githubusercontent.com/Kampfkarren/Roblox/master/Modules/LineOfSight.lua" +- start_position: + bytes: 97 + line: 1 + character: 98 + end_position: + bytes: 98 + line: 1 + character: 98 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 98 + line: 2 + character: 1 + end_position: + bytes: 103 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 103 + line: 2 + character: 6 + end_position: + bytes: 104 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 104 + line: 2 + character: 7 + end_position: + bytes: 121 + line: 2 + character: 24 + token_type: + type: Identifier + identifier: ReplicatedStorage +- start_position: + bytes: 121 + line: 2 + character: 24 + end_position: + bytes: 122 + line: 2 + character: 25 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 122 + line: 2 + character: 25 + end_position: + bytes: 123 + line: 2 + character: 26 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 123 + line: 2 + character: 26 + end_position: + bytes: 124 + line: 2 + character: 27 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 124 + line: 2 + character: 27 + end_position: + bytes: 128 + line: 2 + character: 31 + token_type: + type: Identifier + identifier: game +- start_position: + bytes: 128 + line: 2 + character: 31 + end_position: + bytes: 129 + line: 2 + character: 32 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 129 + line: 2 + character: 32 + end_position: + bytes: 139 + line: 2 + character: 42 + token_type: + type: Identifier + identifier: GetService +- start_position: + bytes: 139 + line: 2 + character: 42 + end_position: + bytes: 140 + line: 2 + character: 43 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 140 + line: 2 + character: 43 + end_position: + bytes: 159 + line: 2 + character: 62 + token_type: + type: StringLiteral + literal: ReplicatedStorage + quote_type: Double +- start_position: + bytes: 159 + line: 2 + character: 62 + end_position: + bytes: 160 + line: 2 + character: 63 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 160 + line: 2 + character: 63 + end_position: + bytes: 161 + line: 2 + character: 63 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 161 + line: 3 + character: 1 + end_position: + bytes: 166 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 166 + line: 3 + character: 6 + end_position: + bytes: 167 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 167 + line: 3 + character: 7 + end_position: + bytes: 177 + line: 3 + character: 17 + token_type: + type: Identifier + identifier: RunService +- start_position: + bytes: 177 + line: 3 + character: 17 + end_position: + bytes: 178 + line: 3 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 178 + line: 3 + character: 18 + end_position: + bytes: 179 + line: 3 + character: 19 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 179 + line: 3 + character: 19 + end_position: + bytes: 180 + line: 3 + character: 20 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 180 + line: 3 + character: 20 + end_position: + bytes: 184 + line: 3 + character: 24 + token_type: + type: Identifier + identifier: game +- start_position: + bytes: 184 + line: 3 + character: 24 + end_position: + bytes: 185 + line: 3 + character: 25 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 185 + line: 3 + character: 25 + end_position: + bytes: 195 + line: 3 + character: 35 + token_type: + type: Identifier + identifier: GetService +- start_position: + bytes: 195 + line: 3 + character: 35 + end_position: + bytes: 196 + line: 3 + character: 36 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 196 + line: 3 + character: 36 + end_position: + bytes: 208 + line: 3 + character: 48 + token_type: + type: StringLiteral + literal: RunService + quote_type: Double +- start_position: + bytes: 208 + line: 3 + character: 48 + end_position: + bytes: 209 + line: 3 + character: 49 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 209 + line: 3 + character: 49 + end_position: + bytes: 210 + line: 3 + character: 49 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 210 + line: 4 + character: 1 + end_position: + bytes: 211 + line: 4 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 211 + line: 5 + character: 1 + end_position: + bytes: 216 + line: 5 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 216 + line: 5 + character: 6 + end_position: + bytes: 217 + line: 5 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 217 + line: 5 + character: 7 + end_position: + bytes: 224 + line: 5 + character: 14 + token_type: + type: Identifier + identifier: Raycast +- start_position: + bytes: 224 + line: 5 + character: 14 + end_position: + bytes: 225 + line: 5 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 225 + line: 5 + character: 15 + end_position: + bytes: 226 + line: 5 + character: 16 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 226 + line: 5 + character: 16 + end_position: + bytes: 227 + line: 5 + character: 17 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 227 + line: 5 + character: 17 + end_position: + bytes: 234 + line: 5 + character: 24 + token_type: + type: Identifier + identifier: require +- start_position: + bytes: 234 + line: 5 + character: 24 + end_position: + bytes: 235 + line: 5 + character: 25 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 235 + line: 5 + character: 25 + end_position: + bytes: 252 + line: 5 + character: 42 + token_type: + type: Identifier + identifier: ReplicatedStorage +- start_position: + bytes: 252 + line: 5 + character: 42 + end_position: + bytes: 253 + line: 5 + character: 43 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 253 + line: 5 + character: 43 + end_position: + bytes: 260 + line: 5 + character: 50 + token_type: + type: Identifier + identifier: Modules +- start_position: + bytes: 260 + line: 5 + character: 50 + end_position: + bytes: 261 + line: 5 + character: 51 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 261 + line: 5 + character: 51 + end_position: + bytes: 268 + line: 5 + character: 58 + token_type: + type: Identifier + identifier: Raycast +- start_position: + bytes: 268 + line: 5 + character: 58 + end_position: + bytes: 269 + line: 5 + character: 59 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 269 + line: 5 + character: 59 + end_position: + bytes: 270 + line: 5 + character: 59 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 270 + line: 6 + character: 1 + end_position: + bytes: 271 + line: 6 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 271 + line: 7 + character: 1 + end_position: + bytes: 276 + line: 7 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 276 + line: 7 + character: 6 + end_position: + bytes: 277 + line: 7 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 277 + line: 7 + character: 7 + end_position: + bytes: 282 + line: 7 + character: 12 + token_type: + type: Identifier + identifier: DEBUG +- start_position: + bytes: 282 + line: 7 + character: 12 + end_position: + bytes: 283 + line: 7 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 283 + line: 7 + character: 13 + end_position: + bytes: 284 + line: 7 + character: 14 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 284 + line: 7 + character: 14 + end_position: + bytes: 285 + line: 7 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 285 + line: 7 + character: 15 + end_position: + bytes: 289 + line: 7 + character: 19 + token_type: + type: Symbol + symbol: "true" +- start_position: + bytes: 289 + line: 7 + character: 19 + end_position: + bytes: 290 + line: 7 + character: 19 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 290 + line: 8 + character: 1 + end_position: + bytes: 295 + line: 8 + character: 6 + token_type: + type: Identifier + identifier: DEBUG +- start_position: + bytes: 295 + line: 8 + character: 6 + end_position: + bytes: 296 + line: 8 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 296 + line: 8 + character: 7 + end_position: + bytes: 297 + line: 8 + character: 8 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 297 + line: 8 + character: 8 + end_position: + bytes: 298 + line: 8 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 298 + line: 8 + character: 9 + end_position: + bytes: 303 + line: 8 + character: 14 + token_type: + type: Identifier + identifier: DEBUG +- start_position: + bytes: 303 + line: 8 + character: 14 + end_position: + bytes: 304 + line: 8 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 304 + line: 8 + character: 15 + end_position: + bytes: 307 + line: 8 + character: 18 + token_type: + type: Symbol + symbol: and +- start_position: + bytes: 307 + line: 8 + character: 18 + end_position: + bytes: 308 + line: 8 + character: 19 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 308 + line: 8 + character: 19 + end_position: + bytes: 318 + line: 8 + character: 29 + token_type: + type: Identifier + identifier: RunService +- start_position: + bytes: 318 + line: 8 + character: 29 + end_position: + bytes: 319 + line: 8 + character: 30 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 319 + line: 8 + character: 30 + end_position: + bytes: 327 + line: 8 + character: 38 + token_type: + type: Identifier + identifier: IsStudio +- start_position: + bytes: 327 + line: 8 + character: 38 + end_position: + bytes: 328 + line: 8 + character: 39 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 328 + line: 8 + character: 39 + end_position: + bytes: 329 + line: 8 + character: 40 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 329 + line: 8 + character: 40 + end_position: + bytes: 330 + line: 8 + character: 40 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 330 + line: 9 + character: 1 + end_position: + bytes: 331 + line: 9 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 331 + line: 10 + character: 1 + end_position: + bytes: 336 + line: 10 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 336 + line: 10 + character: 6 + end_position: + bytes: 337 + line: 10 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 337 + line: 10 + character: 7 + end_position: + bytes: 342 + line: 10 + character: 12 + token_type: + type: Identifier + identifier: debug +- start_position: + bytes: 342 + line: 10 + character: 12 + end_position: + bytes: 343 + line: 10 + character: 12 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 343 + line: 11 + character: 1 + end_position: + bytes: 344 + line: 11 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 344 + line: 12 + character: 1 + end_position: + bytes: 346 + line: 12 + character: 3 + token_type: + type: Symbol + symbol: if +- start_position: + bytes: 346 + line: 12 + character: 3 + end_position: + bytes: 347 + line: 12 + character: 4 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 347 + line: 12 + character: 4 + end_position: + bytes: 352 + line: 12 + character: 9 + token_type: + type: Identifier + identifier: DEBUG +- start_position: + bytes: 352 + line: 12 + character: 9 + end_position: + bytes: 353 + line: 12 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 353 + line: 12 + character: 10 + end_position: + bytes: 357 + line: 12 + character: 14 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 357 + line: 12 + character: 14 + end_position: + bytes: 358 + line: 12 + character: 14 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 358 + line: 13 + character: 1 + end_position: + bytes: 359 + line: 13 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 359 + line: 13 + character: 2 + end_position: + bytes: 367 + line: 13 + character: 10 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 367 + line: 13 + character: 10 + end_position: + bytes: 368 + line: 13 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 368 + line: 13 + character: 11 + end_position: + bytes: 373 + line: 13 + character: 16 + token_type: + type: Identifier + identifier: debug +- start_position: + bytes: 373 + line: 13 + character: 16 + end_position: + bytes: 374 + line: 13 + character: 17 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 374 + line: 13 + character: 17 + end_position: + bytes: 379 + line: 13 + character: 22 + token_type: + type: Identifier + identifier: table +- start_position: + bytes: 379 + line: 13 + character: 22 + end_position: + bytes: 380 + line: 13 + character: 23 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 380 + line: 13 + character: 23 + end_position: + bytes: 381 + line: 13 + character: 23 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 381 + line: 14 + character: 1 + end_position: + bytes: 383 + line: 14 + character: 3 + token_type: + type: Whitespace + characters: "\t\t" +- start_position: + bytes: 383 + line: 14 + character: 3 + end_position: + bytes: 388 + line: 14 + character: 8 + token_type: + type: Identifier + identifier: print +- start_position: + bytes: 388 + line: 14 + character: 8 + end_position: + bytes: 389 + line: 14 + character: 9 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 389 + line: 14 + character: 9 + end_position: + bytes: 404 + line: 14 + character: 24 + token_type: + type: StringLiteral + literal: "[LineOfSight]" + quote_type: Double +- start_position: + bytes: 404 + line: 14 + character: 24 + end_position: + bytes: 405 + line: 14 + character: 25 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 405 + line: 14 + character: 25 + end_position: + bytes: 406 + line: 14 + character: 26 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 406 + line: 14 + character: 26 + end_position: + bytes: 411 + line: 14 + character: 31 + token_type: + type: Identifier + identifier: table +- start_position: + bytes: 411 + line: 14 + character: 31 + end_position: + bytes: 412 + line: 14 + character: 32 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 412 + line: 14 + character: 32 + end_position: + bytes: 413 + line: 14 + character: 32 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 413 + line: 15 + character: 1 + end_position: + bytes: 414 + line: 15 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 414 + line: 15 + character: 2 + end_position: + bytes: 417 + line: 15 + character: 5 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 417 + line: 15 + character: 5 + end_position: + bytes: 418 + line: 15 + character: 5 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 418 + line: 16 + character: 1 + end_position: + bytes: 422 + line: 16 + character: 5 + token_type: + type: Symbol + symbol: else +- start_position: + bytes: 422 + line: 16 + character: 5 + end_position: + bytes: 423 + line: 16 + character: 5 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 423 + line: 17 + character: 1 + end_position: + bytes: 424 + line: 17 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 424 + line: 17 + character: 2 + end_position: + bytes: 432 + line: 17 + character: 10 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 432 + line: 17 + character: 10 + end_position: + bytes: 433 + line: 17 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 433 + line: 17 + character: 11 + end_position: + bytes: 438 + line: 17 + character: 16 + token_type: + type: Identifier + identifier: debug +- start_position: + bytes: 438 + line: 17 + character: 16 + end_position: + bytes: 439 + line: 17 + character: 17 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 439 + line: 17 + character: 17 + end_position: + bytes: 440 + line: 17 + character: 18 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 440 + line: 17 + character: 18 + end_position: + bytes: 441 + line: 17 + character: 18 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 441 + line: 18 + character: 1 + end_position: + bytes: 442 + line: 18 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 442 + line: 18 + character: 2 + end_position: + bytes: 445 + line: 18 + character: 5 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 445 + line: 18 + character: 5 + end_position: + bytes: 446 + line: 18 + character: 5 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 446 + line: 19 + character: 1 + end_position: + bytes: 449 + line: 19 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 449 + line: 19 + character: 4 + end_position: + bytes: 450 + line: 19 + character: 4 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 450 + line: 20 + character: 1 + end_position: + bytes: 451 + line: 20 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 451 + line: 21 + character: 1 + end_position: + bytes: 457 + line: 21 + character: 7 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 457 + line: 21 + character: 7 + end_position: + bytes: 458 + line: 21 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 458 + line: 21 + character: 8 + end_position: + bytes: 466 + line: 21 + character: 16 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 466 + line: 21 + character: 16 + end_position: + bytes: 467 + line: 21 + character: 17 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 467 + line: 21 + character: 17 + end_position: + bytes: 473 + line: 21 + character: 23 + token_type: + type: Identifier + identifier: origin +- start_position: + bytes: 473 + line: 21 + character: 23 + end_position: + bytes: 474 + line: 21 + character: 24 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 474 + line: 21 + character: 24 + end_position: + bytes: 475 + line: 21 + character: 25 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 475 + line: 21 + character: 25 + end_position: + bytes: 484 + line: 21 + character: 34 + token_type: + type: Identifier + identifier: character +- start_position: + bytes: 484 + line: 21 + character: 34 + end_position: + bytes: 485 + line: 21 + character: 35 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 485 + line: 21 + character: 35 + end_position: + bytes: 486 + line: 21 + character: 36 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 486 + line: 21 + character: 36 + end_position: + bytes: 491 + line: 21 + character: 41 + token_type: + type: Identifier + identifier: range +- start_position: + bytes: 491 + line: 21 + character: 41 + end_position: + bytes: 492 + line: 21 + character: 42 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 492 + line: 21 + character: 42 + end_position: + bytes: 493 + line: 21 + character: 43 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 493 + line: 21 + character: 43 + end_position: + bytes: 501 + line: 21 + character: 51 + token_type: + type: Identifier + identifier: ignoreIf +- start_position: + bytes: 501 + line: 21 + character: 51 + end_position: + bytes: 502 + line: 21 + character: 52 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 502 + line: 21 + character: 52 + end_position: + bytes: 503 + line: 21 + character: 53 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 503 + line: 21 + character: 53 + end_position: + bytes: 512 + line: 21 + character: 62 + token_type: + type: Identifier + identifier: blacklist +- start_position: + bytes: 512 + line: 21 + character: 62 + end_position: + bytes: 513 + line: 21 + character: 63 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 513 + line: 21 + character: 63 + end_position: + bytes: 514 + line: 21 + character: 63 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 514 + line: 22 + character: 1 + end_position: + bytes: 515 + line: 22 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 515 + line: 22 + character: 2 + end_position: + bytes: 517 + line: 22 + character: 4 + token_type: + type: Symbol + symbol: if +- start_position: + bytes: 517 + line: 22 + character: 4 + end_position: + bytes: 518 + line: 22 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 518 + line: 22 + character: 5 + end_position: + bytes: 524 + line: 22 + character: 11 + token_type: + type: Identifier + identifier: typeof +- start_position: + bytes: 524 + line: 22 + character: 11 + end_position: + bytes: 525 + line: 22 + character: 12 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 525 + line: 22 + character: 12 + end_position: + bytes: 531 + line: 22 + character: 18 + token_type: + type: Identifier + identifier: origin +- start_position: + bytes: 531 + line: 22 + character: 18 + end_position: + bytes: 532 + line: 22 + character: 19 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 532 + line: 22 + character: 19 + end_position: + bytes: 533 + line: 22 + character: 20 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 533 + line: 22 + character: 20 + end_position: + bytes: 535 + line: 22 + character: 22 + token_type: + type: Symbol + symbol: "==" +- start_position: + bytes: 535 + line: 22 + character: 22 + end_position: + bytes: 536 + line: 22 + character: 23 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 536 + line: 22 + character: 23 + end_position: + bytes: 546 + line: 22 + character: 33 + token_type: + type: StringLiteral + literal: Instance + quote_type: Double +- start_position: + bytes: 546 + line: 22 + character: 33 + end_position: + bytes: 547 + line: 22 + character: 34 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 547 + line: 22 + character: 34 + end_position: + bytes: 551 + line: 22 + character: 38 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 551 + line: 22 + character: 38 + end_position: + bytes: 552 + line: 22 + character: 38 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 552 + line: 23 + character: 1 + end_position: + bytes: 554 + line: 23 + character: 3 + token_type: + type: Whitespace + characters: "\t\t" +- start_position: + bytes: 554 + line: 23 + character: 3 + end_position: + bytes: 556 + line: 23 + character: 5 + token_type: + type: Symbol + symbol: if +- start_position: + bytes: 556 + line: 23 + character: 5 + end_position: + bytes: 557 + line: 23 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 557 + line: 23 + character: 6 + end_position: + bytes: 563 + line: 23 + character: 12 + token_type: + type: Identifier + identifier: origin +- start_position: + bytes: 563 + line: 23 + character: 12 + end_position: + bytes: 564 + line: 23 + character: 13 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 564 + line: 23 + character: 13 + end_position: + bytes: 572 + line: 23 + character: 21 + token_type: + type: Identifier + identifier: Position +- start_position: + bytes: 572 + line: 23 + character: 21 + end_position: + bytes: 573 + line: 23 + character: 22 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 573 + line: 23 + character: 22 + end_position: + bytes: 580 + line: 23 + character: 29 + token_type: + type: Identifier + identifier: FuzzyEq +- start_position: + bytes: 580 + line: 23 + character: 29 + end_position: + bytes: 581 + line: 23 + character: 30 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 581 + line: 23 + character: 30 + end_position: + bytes: 590 + line: 23 + character: 39 + token_type: + type: Identifier + identifier: character +- start_position: + bytes: 590 + line: 23 + character: 39 + end_position: + bytes: 591 + line: 23 + character: 40 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 591 + line: 23 + character: 40 + end_position: + bytes: 602 + line: 23 + character: 51 + token_type: + type: Identifier + identifier: PrimaryPart +- start_position: + bytes: 602 + line: 23 + character: 51 + end_position: + bytes: 603 + line: 23 + character: 52 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 603 + line: 23 + character: 52 + end_position: + bytes: 611 + line: 23 + character: 60 + token_type: + type: Identifier + identifier: Position +- start_position: + bytes: 611 + line: 23 + character: 60 + end_position: + bytes: 612 + line: 23 + character: 61 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 612 + line: 23 + character: 61 + end_position: + bytes: 613 + line: 23 + character: 62 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 613 + line: 23 + character: 62 + end_position: + bytes: 617 + line: 23 + character: 66 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 617 + line: 23 + character: 66 + end_position: + bytes: 618 + line: 23 + character: 66 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 618 + line: 24 + character: 1 + end_position: + bytes: 621 + line: 24 + character: 4 + token_type: + type: Whitespace + characters: "\t\t\t" +- start_position: + bytes: 621 + line: 24 + character: 4 + end_position: + bytes: 626 + line: 24 + character: 9 + token_type: + type: Identifier + identifier: debug +- start_position: + bytes: 626 + line: 24 + character: 9 + end_position: + bytes: 627 + line: 24 + character: 10 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 627 + line: 24 + character: 10 + end_position: + bytes: 649 + line: 24 + character: 32 + token_type: + type: StringLiteral + literal: ORIGIN WAS CHARACTER + quote_type: Double +- start_position: + bytes: 649 + line: 24 + character: 32 + end_position: + bytes: 650 + line: 24 + character: 33 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 650 + line: 24 + character: 33 + end_position: + bytes: 651 + line: 24 + character: 33 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 651 + line: 25 + character: 1 + end_position: + bytes: 654 + line: 25 + character: 4 + token_type: + type: Whitespace + characters: "\t\t\t" +- start_position: + bytes: 654 + line: 25 + character: 4 + end_position: + bytes: 660 + line: 25 + character: 10 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 660 + line: 25 + character: 10 + end_position: + bytes: 661 + line: 25 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 661 + line: 25 + character: 11 + end_position: + bytes: 667 + line: 25 + character: 17 + token_type: + type: Identifier + identifier: origin +- start_position: + bytes: 667 + line: 25 + character: 17 + end_position: + bytes: 668 + line: 25 + character: 18 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 668 + line: 25 + character: 18 + end_position: + bytes: 669 + line: 25 + character: 19 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 669 + line: 25 + character: 19 + end_position: + bytes: 675 + line: 25 + character: 25 + token_type: + type: Identifier + identifier: origin +- start_position: + bytes: 675 + line: 25 + character: 25 + end_position: + bytes: 676 + line: 25 + character: 26 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 676 + line: 25 + character: 26 + end_position: + bytes: 684 + line: 25 + character: 34 + token_type: + type: Identifier + identifier: Position +- start_position: + bytes: 684 + line: 25 + character: 34 + end_position: + bytes: 685 + line: 25 + character: 34 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 685 + line: 26 + character: 1 + end_position: + bytes: 687 + line: 26 + character: 3 + token_type: + type: Whitespace + characters: "\t\t" +- start_position: + bytes: 687 + line: 26 + character: 3 + end_position: + bytes: 690 + line: 26 + character: 6 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 690 + line: 26 + character: 6 + end_position: + bytes: 691 + line: 26 + character: 6 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 691 + line: 27 + character: 1 + end_position: + bytes: 692 + line: 27 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 692 + line: 28 + character: 1 + end_position: + bytes: 694 + line: 28 + character: 3 + token_type: + type: Whitespace + characters: "\t\t" +- start_position: + bytes: 694 + line: 28 + character: 3 + end_position: + bytes: 700 + line: 28 + character: 9 + token_type: + type: Identifier + identifier: origin +- start_position: + bytes: 700 + line: 28 + character: 9 + end_position: + bytes: 701 + line: 28 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 701 + line: 28 + character: 10 + end_position: + bytes: 702 + line: 28 + character: 11 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 702 + line: 28 + character: 11 + end_position: + bytes: 703 + line: 28 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 703 + line: 28 + character: 12 + end_position: + bytes: 709 + line: 28 + character: 18 + token_type: + type: Identifier + identifier: origin +- start_position: + bytes: 709 + line: 28 + character: 18 + end_position: + bytes: 710 + line: 28 + character: 19 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 710 + line: 28 + character: 19 + end_position: + bytes: 718 + line: 28 + character: 27 + token_type: + type: Identifier + identifier: Position +- start_position: + bytes: 718 + line: 28 + character: 27 + end_position: + bytes: 719 + line: 28 + character: 27 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 719 + line: 29 + character: 1 + end_position: + bytes: 720 + line: 29 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 720 + line: 29 + character: 2 + end_position: + bytes: 723 + line: 29 + character: 5 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 723 + line: 29 + character: 5 + end_position: + bytes: 724 + line: 29 + character: 5 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 724 + line: 30 + character: 1 + end_position: + bytes: 725 + line: 30 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 725 + line: 31 + character: 1 + end_position: + bytes: 726 + line: 31 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 726 + line: 31 + character: 2 + end_position: + bytes: 735 + line: 31 + character: 11 + token_type: + type: Identifier + identifier: blacklist +- start_position: + bytes: 735 + line: 31 + character: 11 + end_position: + bytes: 736 + line: 31 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 736 + line: 31 + character: 12 + end_position: + bytes: 737 + line: 31 + character: 13 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 737 + line: 31 + character: 13 + end_position: + bytes: 738 + line: 31 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 738 + line: 31 + character: 14 + end_position: + bytes: 747 + line: 31 + character: 23 + token_type: + type: Identifier + identifier: blacklist +- start_position: + bytes: 747 + line: 31 + character: 23 + end_position: + bytes: 748 + line: 31 + character: 24 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 748 + line: 31 + character: 24 + end_position: + bytes: 750 + line: 31 + character: 26 + token_type: + type: Symbol + symbol: or +- start_position: + bytes: 750 + line: 31 + character: 26 + end_position: + bytes: 751 + line: 31 + character: 27 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 751 + line: 31 + character: 27 + end_position: + bytes: 752 + line: 31 + character: 28 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 752 + line: 31 + character: 28 + end_position: + bytes: 753 + line: 31 + character: 29 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 753 + line: 31 + character: 29 + end_position: + bytes: 754 + line: 31 + character: 29 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 754 + line: 32 + character: 1 + end_position: + bytes: 755 + line: 32 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 755 + line: 33 + character: 1 + end_position: + bytes: 756 + line: 33 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 756 + line: 33 + character: 2 + end_position: + bytes: 761 + line: 33 + character: 7 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 761 + line: 33 + character: 7 + end_position: + bytes: 762 + line: 33 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 762 + line: 33 + character: 8 + end_position: + bytes: 765 + line: 33 + character: 11 + token_type: + type: Identifier + identifier: hit +- start_position: + bytes: 765 + line: 33 + character: 11 + end_position: + bytes: 766 + line: 33 + character: 12 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 766 + line: 33 + character: 12 + end_position: + bytes: 767 + line: 33 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 767 + line: 33 + character: 13 + end_position: + bytes: 772 + line: 33 + character: 18 + token_type: + type: Identifier + identifier: point +- start_position: + bytes: 772 + line: 33 + character: 18 + end_position: + bytes: 773 + line: 33 + character: 19 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 773 + line: 33 + character: 19 + end_position: + bytes: 775 + line: 33 + character: 21 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 775 + line: 33 + character: 21 + end_position: + bytes: 776 + line: 33 + character: 21 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 776 + line: 34 + character: 1 + end_position: + bytes: 778 + line: 34 + character: 3 + token_type: + type: Whitespace + characters: "\t\t" +- start_position: + bytes: 778 + line: 34 + character: 3 + end_position: + bytes: 783 + line: 34 + character: 8 + token_type: + type: Symbol + symbol: while +- start_position: + bytes: 783 + line: 34 + character: 8 + end_position: + bytes: 784 + line: 34 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 784 + line: 34 + character: 9 + end_position: + bytes: 788 + line: 34 + character: 13 + token_type: + type: Symbol + symbol: "true" +- start_position: + bytes: 788 + line: 34 + character: 13 + end_position: + bytes: 789 + line: 34 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 789 + line: 34 + character: 14 + end_position: + bytes: 791 + line: 34 + character: 16 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 791 + line: 34 + character: 16 + end_position: + bytes: 792 + line: 34 + character: 16 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 792 + line: 35 + character: 1 + end_position: + bytes: 795 + line: 35 + character: 4 + token_type: + type: Whitespace + characters: "\t\t\t" +- start_position: + bytes: 795 + line: 35 + character: 4 + end_position: + bytes: 798 + line: 35 + character: 7 + token_type: + type: Identifier + identifier: hit +- start_position: + bytes: 798 + line: 35 + character: 7 + end_position: + bytes: 799 + line: 35 + character: 8 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 799 + line: 35 + character: 8 + end_position: + bytes: 800 + line: 35 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 800 + line: 35 + character: 9 + end_position: + bytes: 805 + line: 35 + character: 14 + token_type: + type: Identifier + identifier: point +- start_position: + bytes: 805 + line: 35 + character: 14 + end_position: + bytes: 806 + line: 35 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 806 + line: 35 + character: 15 + end_position: + bytes: 807 + line: 35 + character: 16 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 807 + line: 35 + character: 16 + end_position: + bytes: 808 + line: 35 + character: 17 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 808 + line: 35 + character: 17 + end_position: + bytes: 815 + line: 35 + character: 24 + token_type: + type: Identifier + identifier: Raycast +- start_position: + bytes: 815 + line: 35 + character: 24 + end_position: + bytes: 816 + line: 35 + character: 25 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 816 + line: 35 + character: 25 + end_position: + bytes: 819 + line: 35 + character: 28 + token_type: + type: Identifier + identifier: Ray +- start_position: + bytes: 819 + line: 35 + character: 28 + end_position: + bytes: 820 + line: 35 + character: 29 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 820 + line: 35 + character: 29 + end_position: + bytes: 823 + line: 35 + character: 32 + token_type: + type: Identifier + identifier: new +- start_position: + bytes: 823 + line: 35 + character: 32 + end_position: + bytes: 824 + line: 35 + character: 33 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 824 + line: 35 + character: 33 + end_position: + bytes: 830 + line: 35 + character: 39 + token_type: + type: Identifier + identifier: origin +- start_position: + bytes: 830 + line: 35 + character: 39 + end_position: + bytes: 831 + line: 35 + character: 40 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 831 + line: 35 + character: 40 + end_position: + bytes: 832 + line: 35 + character: 41 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 832 + line: 35 + character: 41 + end_position: + bytes: 833 + line: 35 + character: 42 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 833 + line: 35 + character: 42 + end_position: + bytes: 839 + line: 35 + character: 48 + token_type: + type: Identifier + identifier: origin +- start_position: + bytes: 839 + line: 35 + character: 48 + end_position: + bytes: 840 + line: 35 + character: 49 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 840 + line: 35 + character: 49 + end_position: + bytes: 841 + line: 35 + character: 50 + token_type: + type: Symbol + symbol: "-" +- start_position: + bytes: 841 + line: 35 + character: 50 + end_position: + bytes: 842 + line: 35 + character: 51 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 842 + line: 35 + character: 51 + end_position: + bytes: 851 + line: 35 + character: 60 + token_type: + type: Identifier + identifier: character +- start_position: + bytes: 851 + line: 35 + character: 60 + end_position: + bytes: 852 + line: 35 + character: 61 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 852 + line: 35 + character: 61 + end_position: + bytes: 863 + line: 35 + character: 72 + token_type: + type: Identifier + identifier: PrimaryPart +- start_position: + bytes: 863 + line: 35 + character: 72 + end_position: + bytes: 864 + line: 35 + character: 73 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 864 + line: 35 + character: 73 + end_position: + bytes: 872 + line: 35 + character: 81 + token_type: + type: Identifier + identifier: Position +- start_position: + bytes: 872 + line: 35 + character: 81 + end_position: + bytes: 873 + line: 35 + character: 82 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 873 + line: 35 + character: 82 + end_position: + bytes: 874 + line: 35 + character: 83 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 874 + line: 35 + character: 83 + end_position: + bytes: 878 + line: 35 + character: 87 + token_type: + type: Identifier + identifier: Unit +- start_position: + bytes: 878 + line: 35 + character: 87 + end_position: + bytes: 879 + line: 35 + character: 88 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 879 + line: 35 + character: 88 + end_position: + bytes: 880 + line: 35 + character: 89 + token_type: + type: Symbol + symbol: "*" +- start_position: + bytes: 880 + line: 35 + character: 89 + end_position: + bytes: 881 + line: 35 + character: 90 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 881 + line: 35 + character: 90 + end_position: + bytes: 882 + line: 35 + character: 91 + token_type: + type: Symbol + symbol: "-" +- start_position: + bytes: 882 + line: 35 + character: 91 + end_position: + bytes: 887 + line: 35 + character: 96 + token_type: + type: Identifier + identifier: range +- start_position: + bytes: 887 + line: 35 + character: 96 + end_position: + bytes: 888 + line: 35 + character: 97 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 888 + line: 35 + character: 97 + end_position: + bytes: 889 + line: 35 + character: 98 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 889 + line: 35 + character: 98 + end_position: + bytes: 890 + line: 35 + character: 99 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 890 + line: 35 + character: 99 + end_position: + bytes: 899 + line: 35 + character: 108 + token_type: + type: Identifier + identifier: blacklist +- start_position: + bytes: 899 + line: 35 + character: 108 + end_position: + bytes: 900 + line: 35 + character: 109 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 900 + line: 35 + character: 109 + end_position: + bytes: 901 + line: 35 + character: 109 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 901 + line: 36 + character: 1 + end_position: + bytes: 902 + line: 36 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 902 + line: 37 + character: 1 + end_position: + bytes: 905 + line: 37 + character: 4 + token_type: + type: Whitespace + characters: "\t\t\t" +- start_position: + bytes: 905 + line: 37 + character: 4 + end_position: + bytes: 907 + line: 37 + character: 6 + token_type: + type: Symbol + symbol: if +- start_position: + bytes: 907 + line: 37 + character: 6 + end_position: + bytes: 908 + line: 37 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 908 + line: 37 + character: 7 + end_position: + bytes: 911 + line: 37 + character: 10 + token_type: + type: Identifier + identifier: hit +- start_position: + bytes: 911 + line: 37 + character: 10 + end_position: + bytes: 912 + line: 37 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 912 + line: 37 + character: 11 + end_position: + bytes: 915 + line: 37 + character: 14 + token_type: + type: Symbol + symbol: and +- start_position: + bytes: 915 + line: 37 + character: 14 + end_position: + bytes: 916 + line: 37 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 916 + line: 37 + character: 15 + end_position: + bytes: 919 + line: 37 + character: 18 + token_type: + type: Identifier + identifier: hit +- start_position: + bytes: 919 + line: 37 + character: 18 + end_position: + bytes: 920 + line: 37 + character: 19 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 920 + line: 37 + character: 19 + end_position: + bytes: 934 + line: 37 + character: 33 + token_type: + type: Identifier + identifier: IsDescendantOf +- start_position: + bytes: 934 + line: 37 + character: 33 + end_position: + bytes: 935 + line: 37 + character: 34 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 935 + line: 37 + character: 34 + end_position: + bytes: 944 + line: 37 + character: 43 + token_type: + type: Identifier + identifier: character +- start_position: + bytes: 944 + line: 37 + character: 43 + end_position: + bytes: 945 + line: 37 + character: 44 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 945 + line: 37 + character: 44 + end_position: + bytes: 946 + line: 37 + character: 45 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 946 + line: 37 + character: 45 + end_position: + bytes: 950 + line: 37 + character: 49 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 950 + line: 37 + character: 49 + end_position: + bytes: 951 + line: 37 + character: 49 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 951 + line: 38 + character: 1 + end_position: + bytes: 955 + line: 38 + character: 5 + token_type: + type: Whitespace + characters: "\t\t\t\t" +- start_position: + bytes: 955 + line: 38 + character: 5 + end_position: + bytes: 960 + line: 38 + character: 10 + token_type: + type: Symbol + symbol: break +- start_position: + bytes: 960 + line: 38 + character: 10 + end_position: + bytes: 961 + line: 38 + character: 10 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 961 + line: 39 + character: 1 + end_position: + bytes: 964 + line: 39 + character: 4 + token_type: + type: Whitespace + characters: "\t\t\t" +- start_position: + bytes: 964 + line: 39 + character: 4 + end_position: + bytes: 970 + line: 39 + character: 10 + token_type: + type: Symbol + symbol: elseif +- start_position: + bytes: 970 + line: 39 + character: 10 + end_position: + bytes: 971 + line: 39 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 971 + line: 39 + character: 11 + end_position: + bytes: 974 + line: 39 + character: 14 + token_type: + type: Identifier + identifier: hit +- start_position: + bytes: 974 + line: 39 + character: 14 + end_position: + bytes: 975 + line: 39 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 975 + line: 39 + character: 15 + end_position: + bytes: 978 + line: 39 + character: 18 + token_type: + type: Symbol + symbol: and +- start_position: + bytes: 978 + line: 39 + character: 18 + end_position: + bytes: 979 + line: 39 + character: 19 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 979 + line: 39 + character: 19 + end_position: + bytes: 987 + line: 39 + character: 27 + token_type: + type: Identifier + identifier: ignoreIf +- start_position: + bytes: 987 + line: 39 + character: 27 + end_position: + bytes: 988 + line: 39 + character: 28 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 988 + line: 39 + character: 28 + end_position: + bytes: 991 + line: 39 + character: 31 + token_type: + type: Identifier + identifier: hit +- start_position: + bytes: 991 + line: 39 + character: 31 + end_position: + bytes: 992 + line: 39 + character: 32 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 992 + line: 39 + character: 32 + end_position: + bytes: 993 + line: 39 + character: 33 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 993 + line: 39 + character: 33 + end_position: + bytes: 997 + line: 39 + character: 37 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 997 + line: 39 + character: 37 + end_position: + bytes: 998 + line: 39 + character: 37 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 998 + line: 40 + character: 1 + end_position: + bytes: 1002 + line: 40 + character: 5 + token_type: + type: Whitespace + characters: "\t\t\t\t" +- start_position: + bytes: 1002 + line: 40 + character: 5 + end_position: + bytes: 1007 + line: 40 + character: 10 + token_type: + type: Identifier + identifier: debug +- start_position: + bytes: 1007 + line: 40 + character: 10 + end_position: + bytes: 1008 + line: 40 + character: 11 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 1008 + line: 40 + character: 11 + end_position: + bytes: 1025 + line: 40 + character: 28 + token_type: + type: StringLiteral + literal: IGNORING OFF IF + quote_type: Double +- start_position: + bytes: 1025 + line: 40 + character: 28 + end_position: + bytes: 1026 + line: 40 + character: 29 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 1026 + line: 40 + character: 29 + end_position: + bytes: 1027 + line: 40 + character: 30 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 1027 + line: 40 + character: 30 + end_position: + bytes: 1030 + line: 40 + character: 33 + token_type: + type: Identifier + identifier: hit +- start_position: + bytes: 1030 + line: 40 + character: 33 + end_position: + bytes: 1031 + line: 40 + character: 34 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 1031 + line: 40 + character: 34 + end_position: + bytes: 1042 + line: 40 + character: 45 + token_type: + type: Identifier + identifier: GetFullName +- start_position: + bytes: 1042 + line: 40 + character: 45 + end_position: + bytes: 1043 + line: 40 + character: 46 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 1043 + line: 40 + character: 46 + end_position: + bytes: 1044 + line: 40 + character: 47 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 1044 + line: 40 + character: 47 + end_position: + bytes: 1045 + line: 40 + character: 48 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 1045 + line: 40 + character: 48 + end_position: + bytes: 1046 + line: 40 + character: 48 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 1046 + line: 41 + character: 1 + end_position: + bytes: 1050 + line: 41 + character: 5 + token_type: + type: Whitespace + characters: "\t\t\t\t" +- start_position: + bytes: 1050 + line: 41 + character: 5 + end_position: + bytes: 1059 + line: 41 + character: 14 + token_type: + type: Identifier + identifier: blacklist +- start_position: + bytes: 1059 + line: 41 + character: 14 + end_position: + bytes: 1060 + line: 41 + character: 15 + token_type: + type: Symbol + symbol: "[" +- start_position: + bytes: 1060 + line: 41 + character: 15 + end_position: + bytes: 1061 + line: 41 + character: 16 + token_type: + type: Symbol + symbol: "#" +- start_position: + bytes: 1061 + line: 41 + character: 16 + end_position: + bytes: 1070 + line: 41 + character: 25 + token_type: + type: Identifier + identifier: blacklist +- start_position: + bytes: 1070 + line: 41 + character: 25 + end_position: + bytes: 1071 + line: 41 + character: 26 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 1071 + line: 41 + character: 26 + end_position: + bytes: 1072 + line: 41 + character: 27 + token_type: + type: Symbol + symbol: + +- start_position: + bytes: 1072 + line: 41 + character: 27 + end_position: + bytes: 1073 + line: 41 + character: 28 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 1073 + line: 41 + character: 28 + end_position: + bytes: 1074 + line: 41 + character: 29 + token_type: + type: Number + text: "1" +- start_position: + bytes: 1074 + line: 41 + character: 29 + end_position: + bytes: 1075 + line: 41 + character: 30 + token_type: + type: Symbol + symbol: "]" +- start_position: + bytes: 1075 + line: 41 + character: 30 + end_position: + bytes: 1076 + line: 41 + character: 31 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 1076 + line: 41 + character: 31 + end_position: + bytes: 1077 + line: 41 + character: 32 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 1077 + line: 41 + character: 32 + end_position: + bytes: 1078 + line: 41 + character: 33 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 1078 + line: 41 + character: 33 + end_position: + bytes: 1081 + line: 41 + character: 36 + token_type: + type: Identifier + identifier: hit +- start_position: + bytes: 1081 + line: 41 + character: 36 + end_position: + bytes: 1082 + line: 41 + character: 36 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 1082 + line: 42 + character: 1 + end_position: + bytes: 1085 + line: 42 + character: 4 + token_type: + type: Whitespace + characters: "\t\t\t" +- start_position: + bytes: 1085 + line: 42 + character: 4 + end_position: + bytes: 1089 + line: 42 + character: 8 + token_type: + type: Symbol + symbol: else +- start_position: + bytes: 1089 + line: 42 + character: 8 + end_position: + bytes: 1090 + line: 42 + character: 8 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 1090 + line: 43 + character: 1 + end_position: + bytes: 1094 + line: 43 + character: 5 + token_type: + type: Whitespace + characters: "\t\t\t\t" +- start_position: + bytes: 1094 + line: 43 + character: 5 + end_position: + bytes: 1099 + line: 43 + character: 10 + token_type: + type: Symbol + symbol: break +- start_position: + bytes: 1099 + line: 43 + character: 10 + end_position: + bytes: 1100 + line: 43 + character: 10 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 1100 + line: 44 + character: 1 + end_position: + bytes: 1103 + line: 44 + character: 4 + token_type: + type: Whitespace + characters: "\t\t\t" +- start_position: + bytes: 1103 + line: 44 + character: 4 + end_position: + bytes: 1106 + line: 44 + character: 7 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 1106 + line: 44 + character: 7 + end_position: + bytes: 1107 + line: 44 + character: 7 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 1107 + line: 45 + character: 1 + end_position: + bytes: 1109 + line: 45 + character: 3 + token_type: + type: Whitespace + characters: "\t\t" +- start_position: + bytes: 1109 + line: 45 + character: 3 + end_position: + bytes: 1112 + line: 45 + character: 6 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 1112 + line: 45 + character: 6 + end_position: + bytes: 1113 + line: 45 + character: 6 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 1113 + line: 46 + character: 1 + end_position: + bytes: 1114 + line: 46 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 1114 + line: 46 + character: 2 + end_position: + bytes: 1117 + line: 46 + character: 5 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 1117 + line: 46 + character: 5 + end_position: + bytes: 1118 + line: 46 + character: 5 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 1118 + line: 47 + character: 1 + end_position: + bytes: 1119 + line: 47 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 1119 + line: 48 + character: 1 + end_position: + bytes: 1120 + line: 48 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 1120 + line: 48 + character: 2 + end_position: + bytes: 1125 + line: 48 + character: 7 + token_type: + type: Identifier + identifier: debug +- start_position: + bytes: 1125 + line: 48 + character: 7 + end_position: + bytes: 1126 + line: 48 + character: 8 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 1126 + line: 48 + character: 8 + end_position: + bytes: 1138 + line: 48 + character: 20 + token_type: + type: StringLiteral + literal: LOS RESULT + quote_type: Double +- start_position: + bytes: 1138 + line: 48 + character: 20 + end_position: + bytes: 1139 + line: 48 + character: 21 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 1139 + line: 48 + character: 21 + end_position: + bytes: 1140 + line: 48 + character: 22 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 1140 + line: 48 + character: 22 + end_position: + bytes: 1143 + line: 48 + character: 25 + token_type: + type: Identifier + identifier: hit +- start_position: + bytes: 1143 + line: 48 + character: 25 + end_position: + bytes: 1144 + line: 48 + character: 26 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 1144 + line: 48 + character: 26 + end_position: + bytes: 1147 + line: 48 + character: 29 + token_type: + type: Symbol + symbol: and +- start_position: + bytes: 1147 + line: 48 + character: 29 + end_position: + bytes: 1148 + line: 48 + character: 30 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 1148 + line: 48 + character: 30 + end_position: + bytes: 1151 + line: 48 + character: 33 + token_type: + type: Identifier + identifier: hit +- start_position: + bytes: 1151 + line: 48 + character: 33 + end_position: + bytes: 1152 + line: 48 + character: 34 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 1152 + line: 48 + character: 34 + end_position: + bytes: 1163 + line: 48 + character: 45 + token_type: + type: Identifier + identifier: GetFullName +- start_position: + bytes: 1163 + line: 48 + character: 45 + end_position: + bytes: 1164 + line: 48 + character: 46 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 1164 + line: 48 + character: 46 + end_position: + bytes: 1165 + line: 48 + character: 47 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 1165 + line: 48 + character: 47 + end_position: + bytes: 1166 + line: 48 + character: 48 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 1166 + line: 48 + character: 48 + end_position: + bytes: 1167 + line: 48 + character: 48 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 1167 + line: 49 + character: 1 + end_position: + bytes: 1168 + line: 49 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 1168 + line: 50 + character: 1 + end_position: + bytes: 1169 + line: 50 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 1169 + line: 50 + character: 2 + end_position: + bytes: 1175 + line: 50 + character: 8 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 1175 + line: 50 + character: 8 + end_position: + bytes: 1176 + line: 50 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 1176 + line: 50 + character: 9 + end_position: + bytes: 1179 + line: 50 + character: 12 + token_type: + type: Identifier + identifier: hit +- start_position: + bytes: 1179 + line: 50 + character: 12 + end_position: + bytes: 1180 + line: 50 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 1180 + line: 50 + character: 13 + end_position: + bytes: 1183 + line: 50 + character: 16 + token_type: + type: Symbol + symbol: and +- start_position: + bytes: 1183 + line: 50 + character: 16 + end_position: + bytes: 1184 + line: 50 + character: 17 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 1184 + line: 50 + character: 17 + end_position: + bytes: 1187 + line: 50 + character: 20 + token_type: + type: Identifier + identifier: hit +- start_position: + bytes: 1187 + line: 50 + character: 20 + end_position: + bytes: 1188 + line: 50 + character: 21 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 1188 + line: 50 + character: 21 + end_position: + bytes: 1202 + line: 50 + character: 35 + token_type: + type: Identifier + identifier: IsDescendantOf +- start_position: + bytes: 1202 + line: 50 + character: 35 + end_position: + bytes: 1203 + line: 50 + character: 36 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 1203 + line: 50 + character: 36 + end_position: + bytes: 1212 + line: 50 + character: 45 + token_type: + type: Identifier + identifier: character +- start_position: + bytes: 1212 + line: 50 + character: 45 + end_position: + bytes: 1213 + line: 50 + character: 46 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 1213 + line: 50 + character: 46 + end_position: + bytes: 1214 + line: 50 + character: 47 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 1214 + line: 50 + character: 47 + end_position: + bytes: 1215 + line: 50 + character: 48 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 1215 + line: 50 + character: 48 + end_position: + bytes: 1220 + line: 50 + character: 53 + token_type: + type: Identifier + identifier: point +- start_position: + bytes: 1220 + line: 50 + character: 53 + end_position: + bytes: 1221 + line: 50 + character: 53 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 1221 + line: 51 + character: 1 + end_position: + bytes: 1224 + line: 51 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 1224 + line: 51 + character: 4 + end_position: + bytes: 1225 + line: 51 + character: 4 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 1225 + line: 52 + character: 1 + end_position: + bytes: 1225 + line: 52 + character: 1 + token_type: + type: Eof diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types/ast.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..57bbae685c1370920bc1aa5df4202995fa523fda --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types/ast.snap @@ -0,0 +1,3823 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: ast.nodes() +input_file: vvs_parser/tests/roblox_cases/pass/types +--- +stmts: + - - LocalAssignment: + local_token: + leading_trivia: + - start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: SingleLineComment + comment: "!strict" + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 10 + line: 2 + character: 1 + end_position: + bytes: 15 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 15 + line: 2 + character: 6 + end_position: + bytes: 16 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 16 + line: 2 + character: 7 + end_position: + bytes: 20 + line: 2 + character: 11 + token_type: + type: Identifier + identifier: _fn3 + trailing_trivia: + - start_position: + bytes: 20 + line: 2 + character: 11 + end_position: + bytes: 21 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: "\n" + equal_token: ~ + expr_list: + pairs: [] + - ~ + - - TypeDeclaration: + type_token: + leading_trivia: [] + token: + start_position: + bytes: 21 + line: 3 + character: 1 + end_position: + bytes: 25 + line: 3 + character: 5 + token_type: + type: Identifier + identifier: type + trailing_trivia: + - start_position: + bytes: 25 + line: 3 + character: 5 + end_position: + bytes: 26 + line: 3 + character: 6 + token_type: + type: Whitespace + characters: " " + base: + leading_trivia: [] + token: + start_position: + bytes: 26 + line: 3 + character: 6 + end_position: + bytes: 32 + line: 3 + character: 12 + token_type: + type: Identifier + identifier: Object + trailing_trivia: + - start_position: + bytes: 32 + line: 3 + character: 12 + end_position: + bytes: 33 + line: 3 + character: 13 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 33 + line: 3 + character: 13 + end_position: + bytes: 34 + line: 3 + character: 14 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 34 + line: 3 + character: 14 + end_position: + bytes: 35 + line: 3 + character: 15 + token_type: + type: Whitespace + characters: " " + declare_as: + Table: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 35 + line: 3 + character: 15 + end_position: + bytes: 36 + line: 3 + character: 16 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 36 + line: 3 + character: 16 + end_position: + bytes: 37 + line: 3 + character: 17 + token_type: + type: Whitespace + characters: " " + - leading_trivia: [] + token: + start_position: + bytes: 58 + line: 3 + character: 38 + end_position: + bytes: 59 + line: 3 + character: 39 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: + - start_position: + bytes: 59 + line: 3 + character: 39 + end_position: + bytes: 60 + line: 3 + character: 39 + token_type: + type: Whitespace + characters: "\n" + fields: + pairs: + - Punctuated: + - key: + Name: + leading_trivia: [] + token: + start_position: + bytes: 37 + line: 3 + character: 17 + end_position: + bytes: 38 + line: 3 + character: 18 + token_type: + type: Identifier + identifier: x + trailing_trivia: [] + colon: + leading_trivia: [] + token: + start_position: + bytes: 38 + line: 3 + character: 18 + end_position: + bytes: 39 + line: 3 + character: 19 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 39 + line: 3 + character: 19 + end_position: + bytes: 40 + line: 3 + character: 20 + token_type: + type: Whitespace + characters: " " + value: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 40 + line: 3 + character: 20 + end_position: + bytes: 46 + line: 3 + character: 26 + token_type: + type: Identifier + identifier: number + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 46 + line: 3 + character: 26 + end_position: + bytes: 47 + line: 3 + character: 27 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 47 + line: 3 + character: 27 + end_position: + bytes: 48 + line: 3 + character: 28 + token_type: + type: Whitespace + characters: " " + - End: + key: + Name: + leading_trivia: [] + token: + start_position: + bytes: 48 + line: 3 + character: 28 + end_position: + bytes: 49 + line: 3 + character: 29 + token_type: + type: Identifier + identifier: y + trailing_trivia: [] + colon: + leading_trivia: [] + token: + start_position: + bytes: 49 + line: 3 + character: 29 + end_position: + bytes: 50 + line: 3 + character: 30 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 50 + line: 3 + character: 30 + end_position: + bytes: 51 + line: 3 + character: 31 + token_type: + type: Whitespace + characters: " " + value: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 51 + line: 3 + character: 31 + end_position: + bytes: 57 + line: 3 + character: 37 + token_type: + type: Identifier + identifier: number + trailing_trivia: + - start_position: + bytes: 57 + line: 3 + character: 37 + end_position: + bytes: 58 + line: 3 + character: 38 + token_type: + type: Whitespace + characters: " " + - ~ + - - TypeDeclaration: + type_token: + leading_trivia: [] + token: + start_position: + bytes: 60 + line: 4 + character: 1 + end_position: + bytes: 64 + line: 4 + character: 5 + token_type: + type: Identifier + identifier: type + trailing_trivia: + - start_position: + bytes: 64 + line: 4 + character: 5 + end_position: + bytes: 65 + line: 4 + character: 6 + token_type: + type: Whitespace + characters: " " + base: + leading_trivia: [] + token: + start_position: + bytes: 65 + line: 4 + character: 6 + end_position: + bytes: 71 + line: 4 + character: 12 + token_type: + type: Identifier + identifier: Typeof + trailing_trivia: + - start_position: + bytes: 71 + line: 4 + character: 12 + end_position: + bytes: 72 + line: 4 + character: 13 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 72 + line: 4 + character: 13 + end_position: + bytes: 73 + line: 4 + character: 14 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 73 + line: 4 + character: 14 + end_position: + bytes: 74 + line: 4 + character: 15 + token_type: + type: Whitespace + characters: " " + declare_as: + Typeof: + typeof_token: + leading_trivia: [] + token: + start_position: + bytes: 74 + line: 4 + character: 15 + end_position: + bytes: 80 + line: 4 + character: 21 + token_type: + type: Identifier + identifier: typeof + trailing_trivia: [] + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 80 + line: 4 + character: 21 + end_position: + bytes: 81 + line: 4 + character: 22 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 95 + line: 4 + character: 36 + end_position: + bytes: 96 + line: 4 + character: 37 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 96 + line: 4 + character: 37 + end_position: + bytes: 97 + line: 4 + character: 37 + token_type: + type: Whitespace + characters: "\n" + inner: + BinaryOperator: + lhs: + BinaryOperator: + lhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 81 + line: 4 + character: 22 + end_position: + bytes: 82 + line: 4 + character: 23 + token_type: + type: Number + text: "2" + trailing_trivia: + - start_position: + bytes: 82 + line: 4 + character: 23 + end_position: + bytes: 83 + line: 4 + character: 24 + token_type: + type: Whitespace + characters: " " + binop: + Plus: + leading_trivia: [] + token: + start_position: + bytes: 83 + line: 4 + character: 24 + end_position: + bytes: 84 + line: 4 + character: 25 + token_type: + type: Symbol + symbol: + + trailing_trivia: + - start_position: + bytes: 84 + line: 4 + character: 25 + end_position: + bytes: 85 + line: 4 + character: 26 + token_type: + type: Whitespace + characters: " " + rhs: + Number: + leading_trivia: [] + token: + start_position: + bytes: 85 + line: 4 + character: 26 + end_position: + bytes: 86 + line: 4 + character: 27 + token_type: + type: Number + text: "2" + trailing_trivia: + - start_position: + bytes: 86 + line: 4 + character: 27 + end_position: + bytes: 87 + line: 4 + character: 28 + token_type: + type: Whitespace + characters: " " + binop: + Plus: + leading_trivia: [] + token: + start_position: + bytes: 87 + line: 4 + character: 28 + end_position: + bytes: 88 + line: 4 + character: 29 + token_type: + type: Symbol + symbol: + + trailing_trivia: + - start_position: + bytes: 88 + line: 4 + character: 29 + end_position: + bytes: 89 + line: 4 + character: 30 + token_type: + type: Whitespace + characters: " " + rhs: + FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 89 + line: 4 + character: 30 + end_position: + bytes: 93 + line: 4 + character: 34 + token_type: + type: Identifier + identifier: _fn3 + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 93 + line: 4 + character: 34 + end_position: + bytes: 94 + line: 4 + character: 35 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 94 + line: 4 + character: 35 + end_position: + bytes: 95 + line: 4 + character: 36 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + arguments: + pairs: [] + - ~ + - - TypeDeclaration: + type_token: + leading_trivia: [] + token: + start_position: + bytes: 97 + line: 5 + character: 1 + end_position: + bytes: 101 + line: 5 + character: 5 + token_type: + type: Identifier + identifier: type + trailing_trivia: + - start_position: + bytes: 101 + line: 5 + character: 5 + end_position: + bytes: 102 + line: 5 + character: 6 + token_type: + type: Whitespace + characters: " " + base: + leading_trivia: [] + token: + start_position: + bytes: 102 + line: 5 + character: 6 + end_position: + bytes: 109 + line: 5 + character: 13 + token_type: + type: Identifier + identifier: Element + trailing_trivia: + - start_position: + bytes: 109 + line: 5 + character: 13 + end_position: + bytes: 110 + line: 5 + character: 14 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 110 + line: 5 + character: 14 + end_position: + bytes: 111 + line: 5 + character: 15 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 111 + line: 5 + character: 15 + end_position: + bytes: 112 + line: 5 + character: 16 + token_type: + type: Whitespace + characters: " " + declare_as: + Table: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 112 + line: 5 + character: 16 + end_position: + bytes: 113 + line: 5 + character: 17 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 113 + line: 5 + character: 17 + end_position: + bytes: 114 + line: 5 + character: 18 + token_type: + type: Whitespace + characters: " " + - leading_trivia: [] + token: + start_position: + bytes: 131 + line: 5 + character: 35 + end_position: + bytes: 132 + line: 5 + character: 36 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: + - start_position: + bytes: 132 + line: 5 + character: 36 + end_position: + bytes: 133 + line: 5 + character: 36 + token_type: + type: Whitespace + characters: "\n" + fields: + pairs: + - End: + key: + IndexSignature: + brackets: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 114 + line: 5 + character: 18 + end_position: + bytes: 115 + line: 5 + character: 19 + token_type: + type: Symbol + symbol: "[" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 121 + line: 5 + character: 25 + end_position: + bytes: 122 + line: 5 + character: 26 + token_type: + type: Symbol + symbol: "]" + trailing_trivia: [] + inner: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 115 + line: 5 + character: 19 + end_position: + bytes: 121 + line: 5 + character: 25 + token_type: + type: Identifier + identifier: string + trailing_trivia: [] + colon: + leading_trivia: [] + token: + start_position: + bytes: 122 + line: 5 + character: 26 + end_position: + bytes: 123 + line: 5 + character: 27 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 123 + line: 5 + character: 27 + end_position: + bytes: 124 + line: 5 + character: 28 + token_type: + type: Whitespace + characters: " " + value: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 124 + line: 5 + character: 28 + end_position: + bytes: 130 + line: 5 + character: 34 + token_type: + type: Identifier + identifier: number + trailing_trivia: + - start_position: + bytes: 130 + line: 5 + character: 34 + end_position: + bytes: 131 + line: 5 + character: 35 + token_type: + type: Whitespace + characters: " " + - ~ + - - TypeDeclaration: + type_token: + leading_trivia: + - start_position: + bytes: 133 + line: 6 + character: 1 + end_position: + bytes: 134 + line: 6 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 134 + line: 7 + character: 1 + end_position: + bytes: 138 + line: 7 + character: 5 + token_type: + type: Identifier + identifier: type + trailing_trivia: + - start_position: + bytes: 138 + line: 7 + character: 5 + end_position: + bytes: 139 + line: 7 + character: 6 + token_type: + type: Whitespace + characters: " " + base: + leading_trivia: [] + token: + start_position: + bytes: 139 + line: 7 + character: 6 + end_position: + bytes: 148 + line: 7 + character: 15 + token_type: + type: Identifier + identifier: Callback1 + trailing_trivia: + - start_position: + bytes: 148 + line: 7 + character: 15 + end_position: + bytes: 149 + line: 7 + character: 16 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 149 + line: 7 + character: 16 + end_position: + bytes: 150 + line: 7 + character: 17 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 150 + line: 7 + character: 17 + end_position: + bytes: 151 + line: 7 + character: 18 + token_type: + type: Whitespace + characters: " " + declare_as: + Callback: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 151 + line: 7 + character: 18 + end_position: + bytes: 152 + line: 7 + character: 19 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 158 + line: 7 + character: 25 + end_position: + bytes: 159 + line: 7 + character: 26 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 159 + line: 7 + character: 26 + end_position: + bytes: 160 + line: 7 + character: 27 + token_type: + type: Whitespace + characters: " " + arguments: + pairs: + - End: + name: ~ + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 152 + line: 7 + character: 19 + end_position: + bytes: 158 + line: 7 + character: 25 + token_type: + type: Identifier + identifier: string + trailing_trivia: [] + arrow: + leading_trivia: [] + token: + start_position: + bytes: 160 + line: 7 + character: 27 + end_position: + bytes: 162 + line: 7 + character: 29 + token_type: + type: Symbol + symbol: "->" + trailing_trivia: + - start_position: + bytes: 162 + line: 7 + character: 29 + end_position: + bytes: 163 + line: 7 + character: 30 + token_type: + type: Whitespace + characters: " " + return_type: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 163 + line: 7 + character: 30 + end_position: + bytes: 169 + line: 7 + character: 36 + token_type: + type: Identifier + identifier: number + trailing_trivia: + - start_position: + bytes: 169 + line: 7 + character: 36 + end_position: + bytes: 170 + line: 7 + character: 36 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - TypeDeclaration: + type_token: + leading_trivia: [] + token: + start_position: + bytes: 170 + line: 8 + character: 1 + end_position: + bytes: 174 + line: 8 + character: 5 + token_type: + type: Identifier + identifier: type + trailing_trivia: + - start_position: + bytes: 174 + line: 8 + character: 5 + end_position: + bytes: 175 + line: 8 + character: 6 + token_type: + type: Whitespace + characters: " " + base: + leading_trivia: [] + token: + start_position: + bytes: 175 + line: 8 + character: 6 + end_position: + bytes: 184 + line: 8 + character: 15 + token_type: + type: Identifier + identifier: Callback2 + trailing_trivia: + - start_position: + bytes: 184 + line: 8 + character: 15 + end_position: + bytes: 185 + line: 8 + character: 16 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 185 + line: 8 + character: 16 + end_position: + bytes: 186 + line: 8 + character: 17 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 186 + line: 8 + character: 17 + end_position: + bytes: 187 + line: 8 + character: 18 + token_type: + type: Whitespace + characters: " " + declare_as: + Callback: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 187 + line: 8 + character: 18 + end_position: + bytes: 188 + line: 8 + character: 19 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 202 + line: 8 + character: 33 + end_position: + bytes: 203 + line: 8 + character: 34 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 203 + line: 8 + character: 34 + end_position: + bytes: 204 + line: 8 + character: 35 + token_type: + type: Whitespace + characters: " " + arguments: + pairs: + - Punctuated: + - name: ~ + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 188 + line: 8 + character: 19 + end_position: + bytes: 194 + line: 8 + character: 25 + token_type: + type: Identifier + identifier: string + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 194 + line: 8 + character: 25 + end_position: + bytes: 195 + line: 8 + character: 26 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 195 + line: 8 + character: 26 + end_position: + bytes: 196 + line: 8 + character: 27 + token_type: + type: Whitespace + characters: " " + - End: + name: ~ + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 196 + line: 8 + character: 27 + end_position: + bytes: 202 + line: 8 + character: 33 + token_type: + type: Identifier + identifier: string + trailing_trivia: [] + arrow: + leading_trivia: [] + token: + start_position: + bytes: 204 + line: 8 + character: 35 + end_position: + bytes: 206 + line: 8 + character: 37 + token_type: + type: Symbol + symbol: "->" + trailing_trivia: + - start_position: + bytes: 206 + line: 8 + character: 37 + end_position: + bytes: 207 + line: 8 + character: 38 + token_type: + type: Whitespace + characters: " " + return_type: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 207 + line: 8 + character: 38 + end_position: + bytes: 213 + line: 8 + character: 44 + token_type: + type: Identifier + identifier: number + trailing_trivia: + - start_position: + bytes: 213 + line: 8 + character: 44 + end_position: + bytes: 214 + line: 8 + character: 44 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - TypeDeclaration: + type_token: + leading_trivia: [] + token: + start_position: + bytes: 214 + line: 9 + character: 1 + end_position: + bytes: 218 + line: 9 + character: 5 + token_type: + type: Identifier + identifier: type + trailing_trivia: + - start_position: + bytes: 218 + line: 9 + character: 5 + end_position: + bytes: 219 + line: 9 + character: 6 + token_type: + type: Whitespace + characters: " " + base: + leading_trivia: [] + token: + start_position: + bytes: 219 + line: 9 + character: 6 + end_position: + bytes: 228 + line: 9 + character: 15 + token_type: + type: Identifier + identifier: Callback3 + trailing_trivia: + - start_position: + bytes: 228 + line: 9 + character: 15 + end_position: + bytes: 229 + line: 9 + character: 16 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 229 + line: 9 + character: 16 + end_position: + bytes: 230 + line: 9 + character: 17 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 230 + line: 9 + character: 17 + end_position: + bytes: 231 + line: 9 + character: 18 + token_type: + type: Whitespace + characters: " " + declare_as: + Callback: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 231 + line: 9 + character: 18 + end_position: + bytes: 232 + line: 9 + character: 19 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 246 + line: 9 + character: 33 + end_position: + bytes: 247 + line: 9 + character: 34 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 247 + line: 9 + character: 34 + end_position: + bytes: 248 + line: 9 + character: 35 + token_type: + type: Whitespace + characters: " " + arguments: + pairs: + - Punctuated: + - name: ~ + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 232 + line: 9 + character: 19 + end_position: + bytes: 238 + line: 9 + character: 25 + token_type: + type: Identifier + identifier: string + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 238 + line: 9 + character: 25 + end_position: + bytes: 239 + line: 9 + character: 26 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 239 + line: 9 + character: 26 + end_position: + bytes: 240 + line: 9 + character: 27 + token_type: + type: Whitespace + characters: " " + - End: + name: ~ + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 240 + line: 9 + character: 27 + end_position: + bytes: 246 + line: 9 + character: 33 + token_type: + type: Identifier + identifier: string + trailing_trivia: [] + arrow: + leading_trivia: [] + token: + start_position: + bytes: 248 + line: 9 + character: 35 + end_position: + bytes: 250 + line: 9 + character: 37 + token_type: + type: Symbol + symbol: "->" + trailing_trivia: + - start_position: + bytes: 250 + line: 9 + character: 37 + end_position: + bytes: 251 + line: 9 + character: 38 + token_type: + type: Whitespace + characters: " " + return_type: + Tuple: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 251 + line: 9 + character: 38 + end_position: + bytes: 252 + line: 9 + character: 39 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 263 + line: 9 + character: 50 + end_position: + bytes: 264 + line: 9 + character: 51 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 264 + line: 9 + character: 51 + end_position: + bytes: 265 + line: 9 + character: 51 + token_type: + type: Whitespace + characters: "\n" + types: + pairs: + - Punctuated: + - Basic: + leading_trivia: [] + token: + start_position: + bytes: 252 + line: 9 + character: 39 + end_position: + bytes: 258 + line: 9 + character: 45 + token_type: + type: Identifier + identifier: string + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 258 + line: 9 + character: 45 + end_position: + bytes: 259 + line: 9 + character: 46 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 259 + line: 9 + character: 46 + end_position: + bytes: 260 + line: 9 + character: 47 + token_type: + type: Whitespace + characters: " " + - End: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 260 + line: 9 + character: 47 + end_position: + bytes: 263 + line: 9 + character: 50 + token_type: + type: Symbol + symbol: nil + trailing_trivia: [] + - ~ + - - TypeDeclaration: + type_token: + leading_trivia: [] + token: + start_position: + bytes: 265 + line: 10 + character: 1 + end_position: + bytes: 269 + line: 10 + character: 5 + token_type: + type: Identifier + identifier: type + trailing_trivia: + - start_position: + bytes: 269 + line: 10 + character: 5 + end_position: + bytes: 270 + line: 10 + character: 6 + token_type: + type: Whitespace + characters: " " + base: + leading_trivia: [] + token: + start_position: + bytes: 270 + line: 10 + character: 6 + end_position: + bytes: 279 + line: 10 + character: 15 + token_type: + type: Identifier + identifier: Callback4 + trailing_trivia: + - start_position: + bytes: 279 + line: 10 + character: 15 + end_position: + bytes: 280 + line: 10 + character: 16 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 280 + line: 10 + character: 16 + end_position: + bytes: 281 + line: 10 + character: 17 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 281 + line: 10 + character: 17 + end_position: + bytes: 282 + line: 10 + character: 18 + token_type: + type: Whitespace + characters: " " + declare_as: + Callback: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 282 + line: 10 + character: 18 + end_position: + bytes: 283 + line: 10 + character: 19 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 289 + line: 10 + character: 25 + end_position: + bytes: 290 + line: 10 + character: 26 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 290 + line: 10 + character: 26 + end_position: + bytes: 291 + line: 10 + character: 27 + token_type: + type: Whitespace + characters: " " + arguments: + pairs: + - End: + name: ~ + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 283 + line: 10 + character: 19 + end_position: + bytes: 289 + line: 10 + character: 25 + token_type: + type: Identifier + identifier: string + trailing_trivia: [] + arrow: + leading_trivia: [] + token: + start_position: + bytes: 291 + line: 10 + character: 27 + end_position: + bytes: 293 + line: 10 + character: 29 + token_type: + type: Symbol + symbol: "->" + trailing_trivia: + - start_position: + bytes: 293 + line: 10 + character: 29 + end_position: + bytes: 294 + line: 10 + character: 30 + token_type: + type: Whitespace + characters: " " + return_type: + Callback: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 294 + line: 10 + character: 30 + end_position: + bytes: 295 + line: 10 + character: 31 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 301 + line: 10 + character: 37 + end_position: + bytes: 302 + line: 10 + character: 38 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 302 + line: 10 + character: 38 + end_position: + bytes: 303 + line: 10 + character: 39 + token_type: + type: Whitespace + characters: " " + arguments: + pairs: + - End: + name: ~ + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 295 + line: 10 + character: 31 + end_position: + bytes: 301 + line: 10 + character: 37 + token_type: + type: Identifier + identifier: string + trailing_trivia: [] + arrow: + leading_trivia: [] + token: + start_position: + bytes: 303 + line: 10 + character: 39 + end_position: + bytes: 305 + line: 10 + character: 41 + token_type: + type: Symbol + symbol: "->" + trailing_trivia: + - start_position: + bytes: 305 + line: 10 + character: 41 + end_position: + bytes: 306 + line: 10 + character: 42 + token_type: + type: Whitespace + characters: " " + return_type: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 306 + line: 10 + character: 42 + end_position: + bytes: 309 + line: 10 + character: 45 + token_type: + type: Symbol + symbol: nil + trailing_trivia: + - start_position: + bytes: 309 + line: 10 + character: 45 + end_position: + bytes: 310 + line: 10 + character: 45 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - TypeDeclaration: + type_token: + leading_trivia: + - start_position: + bytes: 310 + line: 11 + character: 1 + end_position: + bytes: 311 + line: 11 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 311 + line: 12 + character: 1 + end_position: + bytes: 315 + line: 12 + character: 5 + token_type: + type: Identifier + identifier: type + trailing_trivia: + - start_position: + bytes: 315 + line: 12 + character: 5 + end_position: + bytes: 316 + line: 12 + character: 6 + token_type: + type: Whitespace + characters: " " + base: + leading_trivia: [] + token: + start_position: + bytes: 316 + line: 12 + character: 6 + end_position: + bytes: 319 + line: 12 + character: 9 + token_type: + type: Identifier + identifier: Foo + trailing_trivia: + - start_position: + bytes: 319 + line: 12 + character: 9 + end_position: + bytes: 320 + line: 12 + character: 10 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 320 + line: 12 + character: 10 + end_position: + bytes: 321 + line: 12 + character: 11 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 321 + line: 12 + character: 11 + end_position: + bytes: 322 + line: 12 + character: 12 + token_type: + type: Whitespace + characters: " " + declare_as: + Table: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 322 + line: 12 + character: 12 + end_position: + bytes: 323 + line: 12 + character: 13 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 323 + line: 12 + character: 13 + end_position: + bytes: 324 + line: 12 + character: 13 + token_type: + type: Whitespace + characters: "\n" + - leading_trivia: [] + token: + start_position: + bytes: 352 + line: 15 + character: 1 + end_position: + bytes: 353 + line: 15 + character: 2 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: + - start_position: + bytes: 353 + line: 15 + character: 2 + end_position: + bytes: 354 + line: 15 + character: 2 + token_type: + type: Whitespace + characters: "\n" + fields: + pairs: + - Punctuated: + - key: + Name: + leading_trivia: + - start_position: + bytes: 324 + line: 13 + character: 1 + end_position: + bytes: 325 + line: 13 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 325 + line: 13 + character: 2 + end_position: + bytes: 328 + line: 13 + character: 5 + token_type: + type: Identifier + identifier: bar + trailing_trivia: [] + colon: + leading_trivia: [] + token: + start_position: + bytes: 328 + line: 13 + character: 5 + end_position: + bytes: 329 + line: 13 + character: 6 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 329 + line: 13 + character: 6 + end_position: + bytes: 330 + line: 13 + character: 7 + token_type: + type: Whitespace + characters: " " + value: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 330 + line: 13 + character: 7 + end_position: + bytes: 336 + line: 13 + character: 13 + token_type: + type: Identifier + identifier: number + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 336 + line: 13 + character: 13 + end_position: + bytes: 337 + line: 13 + character: 14 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 337 + line: 13 + character: 14 + end_position: + bytes: 338 + line: 13 + character: 14 + token_type: + type: Whitespace + characters: "\n" + - Punctuated: + - key: + Name: + leading_trivia: + - start_position: + bytes: 338 + line: 14 + character: 1 + end_position: + bytes: 339 + line: 14 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 339 + line: 14 + character: 2 + end_position: + bytes: 342 + line: 14 + character: 5 + token_type: + type: Identifier + identifier: baz + trailing_trivia: [] + colon: + leading_trivia: [] + token: + start_position: + bytes: 342 + line: 14 + character: 5 + end_position: + bytes: 343 + line: 14 + character: 6 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 343 + line: 14 + character: 6 + end_position: + bytes: 344 + line: 14 + character: 7 + token_type: + type: Whitespace + characters: " " + value: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 344 + line: 14 + character: 7 + end_position: + bytes: 350 + line: 14 + character: 13 + token_type: + type: Identifier + identifier: number + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 350 + line: 14 + character: 13 + end_position: + bytes: 351 + line: 14 + character: 14 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 351 + line: 14 + character: 14 + end_position: + bytes: 352 + line: 14 + character: 14 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: + - start_position: + bytes: 354 + line: 16 + character: 1 + end_position: + bytes: 355 + line: 16 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 355 + line: 17 + character: 1 + end_position: + bytes: 360 + line: 17 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 360 + line: 17 + character: 6 + end_position: + bytes: 361 + line: 17 + character: 7 + token_type: + type: Whitespace + characters: " " + type_specifiers: + - punctuation: + leading_trivia: [] + token: + start_position: + bytes: 365 + line: 17 + character: 11 + end_position: + bytes: 366 + line: 17 + character: 12 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 366 + line: 17 + character: 12 + end_position: + bytes: 367 + line: 17 + character: 13 + token_type: + type: Whitespace + characters: " " + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 367 + line: 17 + character: 13 + end_position: + bytes: 373 + line: 17 + character: 19 + token_type: + type: Identifier + identifier: number + trailing_trivia: + - start_position: + bytes: 373 + line: 17 + character: 19 + end_position: + bytes: 374 + line: 17 + character: 20 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 361 + line: 17 + character: 7 + end_position: + bytes: 365 + line: 17 + character: 11 + token_type: + type: Identifier + identifier: foo0 + trailing_trivia: [] + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 374 + line: 17 + character: 20 + end_position: + bytes: 375 + line: 17 + character: 21 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 375 + line: 17 + character: 21 + end_position: + bytes: 376 + line: 17 + character: 22 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 376 + line: 17 + character: 22 + end_position: + bytes: 377 + line: 17 + character: 23 + token_type: + type: Number + text: "3" + trailing_trivia: + - start_position: + bytes: 377 + line: 17 + character: 23 + end_position: + bytes: 378 + line: 17 + character: 23 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 378 + line: 18 + character: 1 + end_position: + bytes: 383 + line: 18 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 383 + line: 18 + character: 6 + end_position: + bytes: 384 + line: 18 + character: 7 + token_type: + type: Whitespace + characters: " " + type_specifiers: + - punctuation: + leading_trivia: [] + token: + start_position: + bytes: 389 + line: 18 + character: 12 + end_position: + bytes: 390 + line: 18 + character: 13 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 390 + line: 18 + character: 13 + end_position: + bytes: 391 + line: 18 + character: 14 + token_type: + type: Whitespace + characters: " " + type_info: + Optional: + base: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 391 + line: 18 + character: 14 + end_position: + bytes: 397 + line: 18 + character: 20 + token_type: + type: Identifier + identifier: number + trailing_trivia: [] + question_mark: + leading_trivia: [] + token: + start_position: + bytes: 397 + line: 18 + character: 20 + end_position: + bytes: 398 + line: 18 + character: 21 + token_type: + type: Symbol + symbol: "?" + trailing_trivia: + - start_position: + bytes: 398 + line: 18 + character: 21 + end_position: + bytes: 399 + line: 18 + character: 21 + token_type: + type: Whitespace + characters: "\n" + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 384 + line: 18 + character: 7 + end_position: + bytes: 389 + line: 18 + character: 12 + token_type: + type: Identifier + identifier: _foo1 + trailing_trivia: [] + equal_token: ~ + expr_list: + pairs: [] + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 399 + line: 19 + character: 1 + end_position: + bytes: 404 + line: 19 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 404 + line: 19 + character: 6 + end_position: + bytes: 405 + line: 19 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 405 + line: 19 + character: 7 + end_position: + bytes: 410 + line: 19 + character: 12 + token_type: + type: Identifier + identifier: _bar0 + trailing_trivia: + - start_position: + bytes: 410 + line: 19 + character: 12 + end_position: + bytes: 411 + line: 19 + character: 13 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 411 + line: 19 + character: 13 + end_position: + bytes: 412 + line: 19 + character: 14 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 412 + line: 19 + character: 14 + end_position: + bytes: 413 + line: 19 + character: 15 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + TypeAssertion: + expression: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 413 + line: 19 + character: 15 + end_position: + bytes: 417 + line: 19 + character: 19 + token_type: + type: Identifier + identifier: foo0 + trailing_trivia: + - start_position: + bytes: 417 + line: 19 + character: 19 + end_position: + bytes: 418 + line: 19 + character: 20 + token_type: + type: Whitespace + characters: " " + type_assertion: + assertion_op: + leading_trivia: [] + token: + start_position: + bytes: 418 + line: 19 + character: 20 + end_position: + bytes: 420 + line: 19 + character: 22 + token_type: + type: Symbol + symbol: "::" + trailing_trivia: + - start_position: + bytes: 420 + line: 19 + character: 22 + end_position: + bytes: 421 + line: 19 + character: 23 + token_type: + type: Whitespace + characters: " " + cast_to: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 421 + line: 19 + character: 23 + end_position: + bytes: 427 + line: 19 + character: 29 + token_type: + type: Identifier + identifier: number + trailing_trivia: + - start_position: + bytes: 427 + line: 19 + character: 29 + end_position: + bytes: 428 + line: 19 + character: 29 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: [] + token: + start_position: + bytes: 428 + line: 20 + character: 1 + end_position: + bytes: 433 + line: 20 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 433 + line: 20 + character: 6 + end_position: + bytes: 434 + line: 20 + character: 7 + token_type: + type: Whitespace + characters: " " + type_specifiers: + - punctuation: + leading_trivia: [] + token: + start_position: + bytes: 439 + line: 20 + character: 12 + end_position: + bytes: 440 + line: 20 + character: 13 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 440 + line: 20 + character: 13 + end_position: + bytes: 441 + line: 20 + character: 14 + token_type: + type: Whitespace + characters: " " + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 441 + line: 20 + character: 14 + end_position: + bytes: 447 + line: 20 + character: 20 + token_type: + type: Identifier + identifier: string + trailing_trivia: [] + - punctuation: + leading_trivia: [] + token: + start_position: + bytes: 454 + line: 20 + character: 27 + end_position: + bytes: 455 + line: 20 + character: 28 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 455 + line: 20 + character: 28 + end_position: + bytes: 456 + line: 20 + character: 29 + token_type: + type: Whitespace + characters: " " + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 456 + line: 20 + character: 29 + end_position: + bytes: 462 + line: 20 + character: 35 + token_type: + type: Identifier + identifier: string + trailing_trivia: + - start_position: + bytes: 462 + line: 20 + character: 35 + end_position: + bytes: 463 + line: 20 + character: 35 + token_type: + type: Whitespace + characters: "\n" + name_list: + pairs: + - Punctuated: + - leading_trivia: [] + token: + start_position: + bytes: 434 + line: 20 + character: 7 + end_position: + bytes: 439 + line: 20 + character: 12 + token_type: + type: Identifier + identifier: _foo4 + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 447 + line: 20 + character: 20 + end_position: + bytes: 448 + line: 20 + character: 21 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 448 + line: 20 + character: 21 + end_position: + bytes: 449 + line: 20 + character: 22 + token_type: + type: Whitespace + characters: " " + - End: + leading_trivia: [] + token: + start_position: + bytes: 449 + line: 20 + character: 22 + end_position: + bytes: 454 + line: 20 + character: 27 + token_type: + type: Identifier + identifier: _bar1 + trailing_trivia: [] + equal_token: ~ + expr_list: + pairs: [] + - ~ + - - FunctionDeclaration: + function_token: + leading_trivia: + - start_position: + bytes: 463 + line: 21 + character: 1 + end_position: + bytes: 464 + line: 21 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 464 + line: 22 + character: 1 + end_position: + bytes: 472 + line: 22 + character: 9 + token_type: + type: Symbol + symbol: function + trailing_trivia: + - start_position: + bytes: 472 + line: 22 + character: 9 + end_position: + bytes: 473 + line: 22 + character: 10 + token_type: + type: Whitespace + characters: " " + name: + names: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 473 + line: 22 + character: 10 + end_position: + bytes: 477 + line: 22 + character: 14 + token_type: + type: Identifier + identifier: _fn0 + trailing_trivia: [] + colon_name: ~ + body: + parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 477 + line: 22 + character: 14 + end_position: + bytes: 478 + line: 22 + character: 15 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 491 + line: 22 + character: 28 + end_position: + bytes: 492 + line: 22 + character: 29 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + parameters: + pairs: + - End: + name: + leading_trivia: [] + token: + start_position: + bytes: 478 + line: 22 + character: 15 + end_position: + bytes: 483 + line: 22 + character: 20 + token_type: + type: Identifier + identifier: param + trailing_trivia: [] + type_specifiers: + - punctuation: + leading_trivia: [] + token: + start_position: + bytes: 483 + line: 22 + character: 20 + end_position: + bytes: 484 + line: 22 + character: 21 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 484 + line: 22 + character: 21 + end_position: + bytes: 485 + line: 22 + character: 22 + token_type: + type: Whitespace + characters: " " + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 485 + line: 22 + character: 22 + end_position: + bytes: 491 + line: 22 + character: 28 + token_type: + type: Identifier + identifier: string + trailing_trivia: [] + return_type: + punctuation: + leading_trivia: [] + token: + start_position: + bytes: 492 + line: 22 + character: 29 + end_position: + bytes: 493 + line: 22 + character: 30 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 493 + line: 22 + character: 30 + end_position: + bytes: 494 + line: 22 + character: 31 + token_type: + type: Whitespace + characters: " " + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 494 + line: 22 + character: 31 + end_position: + bytes: 500 + line: 22 + character: 37 + token_type: + type: Identifier + identifier: string + trailing_trivia: + - start_position: + bytes: 500 + line: 22 + character: 37 + end_position: + bytes: 501 + line: 22 + character: 37 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: [] + last_stmt: + - Return: + token: + leading_trivia: + - start_position: + bytes: 501 + line: 23 + character: 1 + end_position: + bytes: 502 + line: 23 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 502 + line: 23 + character: 2 + end_position: + bytes: 508 + line: 23 + character: 8 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 508 + line: 23 + character: 8 + end_position: + bytes: 509 + line: 23 + character: 9 + token_type: + type: Whitespace + characters: " " + returns: + pairs: + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 509 + line: 23 + character: 9 + end_position: + bytes: 514 + line: 23 + character: 14 + token_type: + type: Identifier + identifier: param + trailing_trivia: + - start_position: + bytes: 514 + line: 23 + character: 14 + end_position: + bytes: 515 + line: 23 + character: 14 + token_type: + type: Whitespace + characters: "\n" + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 515 + line: 24 + character: 1 + end_position: + bytes: 518 + line: 24 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 518 + line: 24 + character: 4 + end_position: + bytes: 519 + line: 24 + character: 4 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - FunctionDeclaration: + function_token: + leading_trivia: + - start_position: + bytes: 519 + line: 25 + character: 1 + end_position: + bytes: 520 + line: 25 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 520 + line: 26 + character: 1 + end_position: + bytes: 528 + line: 26 + character: 9 + token_type: + type: Symbol + symbol: function + trailing_trivia: + - start_position: + bytes: 528 + line: 26 + character: 9 + end_position: + bytes: 529 + line: 26 + character: 10 + token_type: + type: Whitespace + characters: " " + name: + names: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 529 + line: 26 + character: 10 + end_position: + bytes: 533 + line: 26 + character: 14 + token_type: + type: Identifier + identifier: _fn2 + trailing_trivia: [] + colon_name: ~ + body: + parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 533 + line: 26 + character: 14 + end_position: + bytes: 534 + line: 26 + character: 15 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 554 + line: 26 + character: 35 + end_position: + bytes: 555 + line: 26 + character: 36 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 555 + line: 26 + character: 36 + end_position: + bytes: 556 + line: 26 + character: 37 + token_type: + type: Whitespace + characters: " " + parameters: + pairs: + - Punctuated: + - name: + leading_trivia: [] + token: + start_position: + bytes: 534 + line: 26 + character: 15 + end_position: + bytes: 535 + line: 26 + character: 16 + token_type: + type: Identifier + identifier: a + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 543 + line: 26 + character: 24 + end_position: + bytes: 544 + line: 26 + character: 25 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 544 + line: 26 + character: 25 + end_position: + bytes: 545 + line: 26 + character: 26 + token_type: + type: Whitespace + characters: " " + - End: + name: + leading_trivia: [] + token: + start_position: + bytes: 545 + line: 26 + character: 26 + end_position: + bytes: 546 + line: 26 + character: 27 + token_type: + type: Identifier + identifier: b + trailing_trivia: [] + type_specifiers: + - punctuation: + leading_trivia: [] + token: + start_position: + bytes: 535 + line: 26 + character: 16 + end_position: + bytes: 536 + line: 26 + character: 17 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 536 + line: 26 + character: 17 + end_position: + bytes: 537 + line: 26 + character: 18 + token_type: + type: Whitespace + characters: " " + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 537 + line: 26 + character: 18 + end_position: + bytes: 543 + line: 26 + character: 24 + token_type: + type: Identifier + identifier: string + trailing_trivia: [] + - punctuation: + leading_trivia: [] + token: + start_position: + bytes: 546 + line: 26 + character: 27 + end_position: + bytes: 547 + line: 26 + character: 28 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 547 + line: 26 + character: 28 + end_position: + bytes: 548 + line: 26 + character: 29 + token_type: + type: Whitespace + characters: " " + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 548 + line: 26 + character: 29 + end_position: + bytes: 554 + line: 26 + character: 35 + token_type: + type: Identifier + identifier: string + trailing_trivia: [] + block: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 556 + line: 26 + character: 37 + end_position: + bytes: 559 + line: 26 + character: 40 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 559 + line: 26 + character: 40 + end_position: + bytes: 560 + line: 26 + character: 40 + token_type: + type: Whitespace + characters: "\n" + - ~ + - - LocalAssignment: + local_token: + leading_trivia: + - start_position: + bytes: 560 + line: 27 + character: 1 + end_position: + bytes: 561 + line: 27 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 561 + line: 28 + character: 1 + end_position: + bytes: 566 + line: 28 + character: 6 + token_type: + type: Symbol + symbol: local + trailing_trivia: + - start_position: + bytes: 566 + line: 28 + character: 6 + end_position: + bytes: 567 + line: 28 + character: 7 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 567 + line: 28 + character: 7 + end_position: + bytes: 571 + line: 28 + character: 11 + token_type: + type: Identifier + identifier: _fn3 + trailing_trivia: + - start_position: + bytes: 571 + line: 28 + character: 11 + end_position: + bytes: 572 + line: 28 + character: 12 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 572 + line: 28 + character: 12 + end_position: + bytes: 573 + line: 28 + character: 13 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 573 + line: 28 + character: 13 + end_position: + bytes: 574 + line: 28 + character: 14 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Function: + - leading_trivia: [] + token: + start_position: + bytes: 574 + line: 28 + character: 14 + end_position: + bytes: 582 + line: 28 + character: 22 + token_type: + type: Symbol + symbol: function + trailing_trivia: [] + - parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 582 + line: 28 + character: 22 + end_position: + bytes: 583 + line: 28 + character: 23 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 583 + line: 28 + character: 23 + end_position: + bytes: 584 + line: 28 + character: 24 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + parameters: + pairs: [] + type_specifiers: [] + return_type: + punctuation: + leading_trivia: [] + token: + start_position: + bytes: 584 + line: 28 + character: 24 + end_position: + bytes: 585 + line: 28 + character: 25 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 585 + line: 28 + character: 25 + end_position: + bytes: 586 + line: 28 + character: 26 + token_type: + type: Whitespace + characters: " " + type_info: + Optional: + base: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 586 + line: 28 + character: 26 + end_position: + bytes: 592 + line: 28 + character: 32 + token_type: + type: Identifier + identifier: number + trailing_trivia: [] + question_mark: + leading_trivia: [] + token: + start_position: + bytes: 592 + line: 28 + character: 32 + end_position: + bytes: 593 + line: 28 + character: 33 + token_type: + type: Symbol + symbol: "?" + trailing_trivia: + - start_position: + bytes: 593 + line: 28 + character: 33 + end_position: + bytes: 594 + line: 28 + character: 33 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: [] + last_stmt: + - Return: + token: + leading_trivia: + - start_position: + bytes: 594 + line: 29 + character: 1 + end_position: + bytes: 595 + line: 29 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 595 + line: 29 + character: 2 + end_position: + bytes: 601 + line: 29 + character: 8 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 601 + line: 29 + character: 8 + end_position: + bytes: 602 + line: 29 + character: 9 + token_type: + type: Whitespace + characters: " " + returns: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 602 + line: 29 + character: 9 + end_position: + bytes: 603 + line: 29 + character: 10 + token_type: + type: Number + text: "3" + trailing_trivia: + - start_position: + bytes: 603 + line: 29 + character: 10 + end_position: + bytes: 604 + line: 29 + character: 10 + token_type: + type: Whitespace + characters: "\n" + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 604 + line: 30 + character: 1 + end_position: + bytes: 607 + line: 30 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 607 + line: 30 + character: 4 + end_position: + bytes: 608 + line: 30 + character: 4 + token_type: + type: Whitespace + characters: "\n" + - ~ diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types/source.lua b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..5a7f78387858afaa3c7b098bca6bbcaa04ec59f5 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types/source.lua @@ -0,0 +1,30 @@ +--!strict +local _fn3 +type Object = { x: number, y: number } +type Typeof = typeof(2 + 2 + _fn3()) +type Element = { [string]: number } + +type Callback1 = (string) -> number +type Callback2 = (string, string) -> number +type Callback3 = (string, string) -> (string, nil) +type Callback4 = (string) -> (string) -> nil + +type Foo = { + bar: number, + baz: number, +} + +local foo0: number = 3 +local _foo1: number? +local _bar0 = foo0 :: number +local _foo4: string, _bar1: string + +function _fn0(param: string): string + return param +end + +function _fn2(a: string, b: string) end + +local _fn3 = function(): number? + return 3 +end diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types/tokens.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..d8097659cdfa24d7d4ba105f2d6e6174264a2507 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types/tokens.snap @@ -0,0 +1,2996 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: tokens +input_file: vvs_parser/tests/roblox_cases/pass/types +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: SingleLineComment + comment: "!strict" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 10 + line: 2 + character: 1 + end_position: + bytes: 15 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 15 + line: 2 + character: 6 + end_position: + bytes: 16 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 16 + line: 2 + character: 7 + end_position: + bytes: 20 + line: 2 + character: 11 + token_type: + type: Identifier + identifier: _fn3 +- start_position: + bytes: 20 + line: 2 + character: 11 + end_position: + bytes: 21 + line: 2 + character: 11 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 21 + line: 3 + character: 1 + end_position: + bytes: 25 + line: 3 + character: 5 + token_type: + type: Identifier + identifier: type +- start_position: + bytes: 25 + line: 3 + character: 5 + end_position: + bytes: 26 + line: 3 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 26 + line: 3 + character: 6 + end_position: + bytes: 32 + line: 3 + character: 12 + token_type: + type: Identifier + identifier: Object +- start_position: + bytes: 32 + line: 3 + character: 12 + end_position: + bytes: 33 + line: 3 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 33 + line: 3 + character: 13 + end_position: + bytes: 34 + line: 3 + character: 14 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 34 + line: 3 + character: 14 + end_position: + bytes: 35 + line: 3 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 35 + line: 3 + character: 15 + end_position: + bytes: 36 + line: 3 + character: 16 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 36 + line: 3 + character: 16 + end_position: + bytes: 37 + line: 3 + character: 17 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 37 + line: 3 + character: 17 + end_position: + bytes: 38 + line: 3 + character: 18 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 38 + line: 3 + character: 18 + end_position: + bytes: 39 + line: 3 + character: 19 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 39 + line: 3 + character: 19 + end_position: + bytes: 40 + line: 3 + character: 20 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 40 + line: 3 + character: 20 + end_position: + bytes: 46 + line: 3 + character: 26 + token_type: + type: Identifier + identifier: number +- start_position: + bytes: 46 + line: 3 + character: 26 + end_position: + bytes: 47 + line: 3 + character: 27 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 47 + line: 3 + character: 27 + end_position: + bytes: 48 + line: 3 + character: 28 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 48 + line: 3 + character: 28 + end_position: + bytes: 49 + line: 3 + character: 29 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 49 + line: 3 + character: 29 + end_position: + bytes: 50 + line: 3 + character: 30 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 50 + line: 3 + character: 30 + end_position: + bytes: 51 + line: 3 + character: 31 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 51 + line: 3 + character: 31 + end_position: + bytes: 57 + line: 3 + character: 37 + token_type: + type: Identifier + identifier: number +- start_position: + bytes: 57 + line: 3 + character: 37 + end_position: + bytes: 58 + line: 3 + character: 38 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 58 + line: 3 + character: 38 + end_position: + bytes: 59 + line: 3 + character: 39 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 59 + line: 3 + character: 39 + end_position: + bytes: 60 + line: 3 + character: 39 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 60 + line: 4 + character: 1 + end_position: + bytes: 64 + line: 4 + character: 5 + token_type: + type: Identifier + identifier: type +- start_position: + bytes: 64 + line: 4 + character: 5 + end_position: + bytes: 65 + line: 4 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 65 + line: 4 + character: 6 + end_position: + bytes: 71 + line: 4 + character: 12 + token_type: + type: Identifier + identifier: Typeof +- start_position: + bytes: 71 + line: 4 + character: 12 + end_position: + bytes: 72 + line: 4 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 72 + line: 4 + character: 13 + end_position: + bytes: 73 + line: 4 + character: 14 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 73 + line: 4 + character: 14 + end_position: + bytes: 74 + line: 4 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 74 + line: 4 + character: 15 + end_position: + bytes: 80 + line: 4 + character: 21 + token_type: + type: Identifier + identifier: typeof +- start_position: + bytes: 80 + line: 4 + character: 21 + end_position: + bytes: 81 + line: 4 + character: 22 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 81 + line: 4 + character: 22 + end_position: + bytes: 82 + line: 4 + character: 23 + token_type: + type: Number + text: "2" +- start_position: + bytes: 82 + line: 4 + character: 23 + end_position: + bytes: 83 + line: 4 + character: 24 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 83 + line: 4 + character: 24 + end_position: + bytes: 84 + line: 4 + character: 25 + token_type: + type: Symbol + symbol: + +- start_position: + bytes: 84 + line: 4 + character: 25 + end_position: + bytes: 85 + line: 4 + character: 26 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 85 + line: 4 + character: 26 + end_position: + bytes: 86 + line: 4 + character: 27 + token_type: + type: Number + text: "2" +- start_position: + bytes: 86 + line: 4 + character: 27 + end_position: + bytes: 87 + line: 4 + character: 28 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 87 + line: 4 + character: 28 + end_position: + bytes: 88 + line: 4 + character: 29 + token_type: + type: Symbol + symbol: + +- start_position: + bytes: 88 + line: 4 + character: 29 + end_position: + bytes: 89 + line: 4 + character: 30 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 89 + line: 4 + character: 30 + end_position: + bytes: 93 + line: 4 + character: 34 + token_type: + type: Identifier + identifier: _fn3 +- start_position: + bytes: 93 + line: 4 + character: 34 + end_position: + bytes: 94 + line: 4 + character: 35 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 94 + line: 4 + character: 35 + end_position: + bytes: 95 + line: 4 + character: 36 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 95 + line: 4 + character: 36 + end_position: + bytes: 96 + line: 4 + character: 37 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 96 + line: 4 + character: 37 + end_position: + bytes: 97 + line: 4 + character: 37 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 97 + line: 5 + character: 1 + end_position: + bytes: 101 + line: 5 + character: 5 + token_type: + type: Identifier + identifier: type +- start_position: + bytes: 101 + line: 5 + character: 5 + end_position: + bytes: 102 + line: 5 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 102 + line: 5 + character: 6 + end_position: + bytes: 109 + line: 5 + character: 13 + token_type: + type: Identifier + identifier: Element +- start_position: + bytes: 109 + line: 5 + character: 13 + end_position: + bytes: 110 + line: 5 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 110 + line: 5 + character: 14 + end_position: + bytes: 111 + line: 5 + character: 15 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 111 + line: 5 + character: 15 + end_position: + bytes: 112 + line: 5 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 112 + line: 5 + character: 16 + end_position: + bytes: 113 + line: 5 + character: 17 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 113 + line: 5 + character: 17 + end_position: + bytes: 114 + line: 5 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 114 + line: 5 + character: 18 + end_position: + bytes: 115 + line: 5 + character: 19 + token_type: + type: Symbol + symbol: "[" +- start_position: + bytes: 115 + line: 5 + character: 19 + end_position: + bytes: 121 + line: 5 + character: 25 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 121 + line: 5 + character: 25 + end_position: + bytes: 122 + line: 5 + character: 26 + token_type: + type: Symbol + symbol: "]" +- start_position: + bytes: 122 + line: 5 + character: 26 + end_position: + bytes: 123 + line: 5 + character: 27 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 123 + line: 5 + character: 27 + end_position: + bytes: 124 + line: 5 + character: 28 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 124 + line: 5 + character: 28 + end_position: + bytes: 130 + line: 5 + character: 34 + token_type: + type: Identifier + identifier: number +- start_position: + bytes: 130 + line: 5 + character: 34 + end_position: + bytes: 131 + line: 5 + character: 35 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 131 + line: 5 + character: 35 + end_position: + bytes: 132 + line: 5 + character: 36 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 132 + line: 5 + character: 36 + end_position: + bytes: 133 + line: 5 + character: 36 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 133 + line: 6 + character: 1 + end_position: + bytes: 134 + line: 6 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 134 + line: 7 + character: 1 + end_position: + bytes: 138 + line: 7 + character: 5 + token_type: + type: Identifier + identifier: type +- start_position: + bytes: 138 + line: 7 + character: 5 + end_position: + bytes: 139 + line: 7 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 139 + line: 7 + character: 6 + end_position: + bytes: 148 + line: 7 + character: 15 + token_type: + type: Identifier + identifier: Callback1 +- start_position: + bytes: 148 + line: 7 + character: 15 + end_position: + bytes: 149 + line: 7 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 149 + line: 7 + character: 16 + end_position: + bytes: 150 + line: 7 + character: 17 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 150 + line: 7 + character: 17 + end_position: + bytes: 151 + line: 7 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 151 + line: 7 + character: 18 + end_position: + bytes: 152 + line: 7 + character: 19 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 152 + line: 7 + character: 19 + end_position: + bytes: 158 + line: 7 + character: 25 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 158 + line: 7 + character: 25 + end_position: + bytes: 159 + line: 7 + character: 26 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 159 + line: 7 + character: 26 + end_position: + bytes: 160 + line: 7 + character: 27 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 160 + line: 7 + character: 27 + end_position: + bytes: 162 + line: 7 + character: 29 + token_type: + type: Symbol + symbol: "->" +- start_position: + bytes: 162 + line: 7 + character: 29 + end_position: + bytes: 163 + line: 7 + character: 30 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 163 + line: 7 + character: 30 + end_position: + bytes: 169 + line: 7 + character: 36 + token_type: + type: Identifier + identifier: number +- start_position: + bytes: 169 + line: 7 + character: 36 + end_position: + bytes: 170 + line: 7 + character: 36 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 170 + line: 8 + character: 1 + end_position: + bytes: 174 + line: 8 + character: 5 + token_type: + type: Identifier + identifier: type +- start_position: + bytes: 174 + line: 8 + character: 5 + end_position: + bytes: 175 + line: 8 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 175 + line: 8 + character: 6 + end_position: + bytes: 184 + line: 8 + character: 15 + token_type: + type: Identifier + identifier: Callback2 +- start_position: + bytes: 184 + line: 8 + character: 15 + end_position: + bytes: 185 + line: 8 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 185 + line: 8 + character: 16 + end_position: + bytes: 186 + line: 8 + character: 17 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 186 + line: 8 + character: 17 + end_position: + bytes: 187 + line: 8 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 187 + line: 8 + character: 18 + end_position: + bytes: 188 + line: 8 + character: 19 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 188 + line: 8 + character: 19 + end_position: + bytes: 194 + line: 8 + character: 25 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 194 + line: 8 + character: 25 + end_position: + bytes: 195 + line: 8 + character: 26 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 195 + line: 8 + character: 26 + end_position: + bytes: 196 + line: 8 + character: 27 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 196 + line: 8 + character: 27 + end_position: + bytes: 202 + line: 8 + character: 33 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 202 + line: 8 + character: 33 + end_position: + bytes: 203 + line: 8 + character: 34 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 203 + line: 8 + character: 34 + end_position: + bytes: 204 + line: 8 + character: 35 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 204 + line: 8 + character: 35 + end_position: + bytes: 206 + line: 8 + character: 37 + token_type: + type: Symbol + symbol: "->" +- start_position: + bytes: 206 + line: 8 + character: 37 + end_position: + bytes: 207 + line: 8 + character: 38 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 207 + line: 8 + character: 38 + end_position: + bytes: 213 + line: 8 + character: 44 + token_type: + type: Identifier + identifier: number +- start_position: + bytes: 213 + line: 8 + character: 44 + end_position: + bytes: 214 + line: 8 + character: 44 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 214 + line: 9 + character: 1 + end_position: + bytes: 218 + line: 9 + character: 5 + token_type: + type: Identifier + identifier: type +- start_position: + bytes: 218 + line: 9 + character: 5 + end_position: + bytes: 219 + line: 9 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 219 + line: 9 + character: 6 + end_position: + bytes: 228 + line: 9 + character: 15 + token_type: + type: Identifier + identifier: Callback3 +- start_position: + bytes: 228 + line: 9 + character: 15 + end_position: + bytes: 229 + line: 9 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 229 + line: 9 + character: 16 + end_position: + bytes: 230 + line: 9 + character: 17 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 230 + line: 9 + character: 17 + end_position: + bytes: 231 + line: 9 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 231 + line: 9 + character: 18 + end_position: + bytes: 232 + line: 9 + character: 19 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 232 + line: 9 + character: 19 + end_position: + bytes: 238 + line: 9 + character: 25 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 238 + line: 9 + character: 25 + end_position: + bytes: 239 + line: 9 + character: 26 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 239 + line: 9 + character: 26 + end_position: + bytes: 240 + line: 9 + character: 27 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 240 + line: 9 + character: 27 + end_position: + bytes: 246 + line: 9 + character: 33 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 246 + line: 9 + character: 33 + end_position: + bytes: 247 + line: 9 + character: 34 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 247 + line: 9 + character: 34 + end_position: + bytes: 248 + line: 9 + character: 35 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 248 + line: 9 + character: 35 + end_position: + bytes: 250 + line: 9 + character: 37 + token_type: + type: Symbol + symbol: "->" +- start_position: + bytes: 250 + line: 9 + character: 37 + end_position: + bytes: 251 + line: 9 + character: 38 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 251 + line: 9 + character: 38 + end_position: + bytes: 252 + line: 9 + character: 39 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 252 + line: 9 + character: 39 + end_position: + bytes: 258 + line: 9 + character: 45 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 258 + line: 9 + character: 45 + end_position: + bytes: 259 + line: 9 + character: 46 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 259 + line: 9 + character: 46 + end_position: + bytes: 260 + line: 9 + character: 47 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 260 + line: 9 + character: 47 + end_position: + bytes: 263 + line: 9 + character: 50 + token_type: + type: Symbol + symbol: nil +- start_position: + bytes: 263 + line: 9 + character: 50 + end_position: + bytes: 264 + line: 9 + character: 51 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 264 + line: 9 + character: 51 + end_position: + bytes: 265 + line: 9 + character: 51 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 265 + line: 10 + character: 1 + end_position: + bytes: 269 + line: 10 + character: 5 + token_type: + type: Identifier + identifier: type +- start_position: + bytes: 269 + line: 10 + character: 5 + end_position: + bytes: 270 + line: 10 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 270 + line: 10 + character: 6 + end_position: + bytes: 279 + line: 10 + character: 15 + token_type: + type: Identifier + identifier: Callback4 +- start_position: + bytes: 279 + line: 10 + character: 15 + end_position: + bytes: 280 + line: 10 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 280 + line: 10 + character: 16 + end_position: + bytes: 281 + line: 10 + character: 17 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 281 + line: 10 + character: 17 + end_position: + bytes: 282 + line: 10 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 282 + line: 10 + character: 18 + end_position: + bytes: 283 + line: 10 + character: 19 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 283 + line: 10 + character: 19 + end_position: + bytes: 289 + line: 10 + character: 25 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 289 + line: 10 + character: 25 + end_position: + bytes: 290 + line: 10 + character: 26 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 290 + line: 10 + character: 26 + end_position: + bytes: 291 + line: 10 + character: 27 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 291 + line: 10 + character: 27 + end_position: + bytes: 293 + line: 10 + character: 29 + token_type: + type: Symbol + symbol: "->" +- start_position: + bytes: 293 + line: 10 + character: 29 + end_position: + bytes: 294 + line: 10 + character: 30 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 294 + line: 10 + character: 30 + end_position: + bytes: 295 + line: 10 + character: 31 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 295 + line: 10 + character: 31 + end_position: + bytes: 301 + line: 10 + character: 37 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 301 + line: 10 + character: 37 + end_position: + bytes: 302 + line: 10 + character: 38 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 302 + line: 10 + character: 38 + end_position: + bytes: 303 + line: 10 + character: 39 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 303 + line: 10 + character: 39 + end_position: + bytes: 305 + line: 10 + character: 41 + token_type: + type: Symbol + symbol: "->" +- start_position: + bytes: 305 + line: 10 + character: 41 + end_position: + bytes: 306 + line: 10 + character: 42 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 306 + line: 10 + character: 42 + end_position: + bytes: 309 + line: 10 + character: 45 + token_type: + type: Symbol + symbol: nil +- start_position: + bytes: 309 + line: 10 + character: 45 + end_position: + bytes: 310 + line: 10 + character: 45 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 310 + line: 11 + character: 1 + end_position: + bytes: 311 + line: 11 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 311 + line: 12 + character: 1 + end_position: + bytes: 315 + line: 12 + character: 5 + token_type: + type: Identifier + identifier: type +- start_position: + bytes: 315 + line: 12 + character: 5 + end_position: + bytes: 316 + line: 12 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 316 + line: 12 + character: 6 + end_position: + bytes: 319 + line: 12 + character: 9 + token_type: + type: Identifier + identifier: Foo +- start_position: + bytes: 319 + line: 12 + character: 9 + end_position: + bytes: 320 + line: 12 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 320 + line: 12 + character: 10 + end_position: + bytes: 321 + line: 12 + character: 11 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 321 + line: 12 + character: 11 + end_position: + bytes: 322 + line: 12 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 322 + line: 12 + character: 12 + end_position: + bytes: 323 + line: 12 + character: 13 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 323 + line: 12 + character: 13 + end_position: + bytes: 324 + line: 12 + character: 13 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 324 + line: 13 + character: 1 + end_position: + bytes: 325 + line: 13 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 325 + line: 13 + character: 2 + end_position: + bytes: 328 + line: 13 + character: 5 + token_type: + type: Identifier + identifier: bar +- start_position: + bytes: 328 + line: 13 + character: 5 + end_position: + bytes: 329 + line: 13 + character: 6 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 329 + line: 13 + character: 6 + end_position: + bytes: 330 + line: 13 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 330 + line: 13 + character: 7 + end_position: + bytes: 336 + line: 13 + character: 13 + token_type: + type: Identifier + identifier: number +- start_position: + bytes: 336 + line: 13 + character: 13 + end_position: + bytes: 337 + line: 13 + character: 14 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 337 + line: 13 + character: 14 + end_position: + bytes: 338 + line: 13 + character: 14 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 338 + line: 14 + character: 1 + end_position: + bytes: 339 + line: 14 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 339 + line: 14 + character: 2 + end_position: + bytes: 342 + line: 14 + character: 5 + token_type: + type: Identifier + identifier: baz +- start_position: + bytes: 342 + line: 14 + character: 5 + end_position: + bytes: 343 + line: 14 + character: 6 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 343 + line: 14 + character: 6 + end_position: + bytes: 344 + line: 14 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 344 + line: 14 + character: 7 + end_position: + bytes: 350 + line: 14 + character: 13 + token_type: + type: Identifier + identifier: number +- start_position: + bytes: 350 + line: 14 + character: 13 + end_position: + bytes: 351 + line: 14 + character: 14 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 351 + line: 14 + character: 14 + end_position: + bytes: 352 + line: 14 + character: 14 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 352 + line: 15 + character: 1 + end_position: + bytes: 353 + line: 15 + character: 2 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 353 + line: 15 + character: 2 + end_position: + bytes: 354 + line: 15 + character: 2 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 354 + line: 16 + character: 1 + end_position: + bytes: 355 + line: 16 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 355 + line: 17 + character: 1 + end_position: + bytes: 360 + line: 17 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 360 + line: 17 + character: 6 + end_position: + bytes: 361 + line: 17 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 361 + line: 17 + character: 7 + end_position: + bytes: 365 + line: 17 + character: 11 + token_type: + type: Identifier + identifier: foo0 +- start_position: + bytes: 365 + line: 17 + character: 11 + end_position: + bytes: 366 + line: 17 + character: 12 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 366 + line: 17 + character: 12 + end_position: + bytes: 367 + line: 17 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 367 + line: 17 + character: 13 + end_position: + bytes: 373 + line: 17 + character: 19 + token_type: + type: Identifier + identifier: number +- start_position: + bytes: 373 + line: 17 + character: 19 + end_position: + bytes: 374 + line: 17 + character: 20 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 374 + line: 17 + character: 20 + end_position: + bytes: 375 + line: 17 + character: 21 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 375 + line: 17 + character: 21 + end_position: + bytes: 376 + line: 17 + character: 22 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 376 + line: 17 + character: 22 + end_position: + bytes: 377 + line: 17 + character: 23 + token_type: + type: Number + text: "3" +- start_position: + bytes: 377 + line: 17 + character: 23 + end_position: + bytes: 378 + line: 17 + character: 23 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 378 + line: 18 + character: 1 + end_position: + bytes: 383 + line: 18 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 383 + line: 18 + character: 6 + end_position: + bytes: 384 + line: 18 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 384 + line: 18 + character: 7 + end_position: + bytes: 389 + line: 18 + character: 12 + token_type: + type: Identifier + identifier: _foo1 +- start_position: + bytes: 389 + line: 18 + character: 12 + end_position: + bytes: 390 + line: 18 + character: 13 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 390 + line: 18 + character: 13 + end_position: + bytes: 391 + line: 18 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 391 + line: 18 + character: 14 + end_position: + bytes: 397 + line: 18 + character: 20 + token_type: + type: Identifier + identifier: number +- start_position: + bytes: 397 + line: 18 + character: 20 + end_position: + bytes: 398 + line: 18 + character: 21 + token_type: + type: Symbol + symbol: "?" +- start_position: + bytes: 398 + line: 18 + character: 21 + end_position: + bytes: 399 + line: 18 + character: 21 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 399 + line: 19 + character: 1 + end_position: + bytes: 404 + line: 19 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 404 + line: 19 + character: 6 + end_position: + bytes: 405 + line: 19 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 405 + line: 19 + character: 7 + end_position: + bytes: 410 + line: 19 + character: 12 + token_type: + type: Identifier + identifier: _bar0 +- start_position: + bytes: 410 + line: 19 + character: 12 + end_position: + bytes: 411 + line: 19 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 411 + line: 19 + character: 13 + end_position: + bytes: 412 + line: 19 + character: 14 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 412 + line: 19 + character: 14 + end_position: + bytes: 413 + line: 19 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 413 + line: 19 + character: 15 + end_position: + bytes: 417 + line: 19 + character: 19 + token_type: + type: Identifier + identifier: foo0 +- start_position: + bytes: 417 + line: 19 + character: 19 + end_position: + bytes: 418 + line: 19 + character: 20 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 418 + line: 19 + character: 20 + end_position: + bytes: 420 + line: 19 + character: 22 + token_type: + type: Symbol + symbol: "::" +- start_position: + bytes: 420 + line: 19 + character: 22 + end_position: + bytes: 421 + line: 19 + character: 23 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 421 + line: 19 + character: 23 + end_position: + bytes: 427 + line: 19 + character: 29 + token_type: + type: Identifier + identifier: number +- start_position: + bytes: 427 + line: 19 + character: 29 + end_position: + bytes: 428 + line: 19 + character: 29 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 428 + line: 20 + character: 1 + end_position: + bytes: 433 + line: 20 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 433 + line: 20 + character: 6 + end_position: + bytes: 434 + line: 20 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 434 + line: 20 + character: 7 + end_position: + bytes: 439 + line: 20 + character: 12 + token_type: + type: Identifier + identifier: _foo4 +- start_position: + bytes: 439 + line: 20 + character: 12 + end_position: + bytes: 440 + line: 20 + character: 13 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 440 + line: 20 + character: 13 + end_position: + bytes: 441 + line: 20 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 441 + line: 20 + character: 14 + end_position: + bytes: 447 + line: 20 + character: 20 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 447 + line: 20 + character: 20 + end_position: + bytes: 448 + line: 20 + character: 21 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 448 + line: 20 + character: 21 + end_position: + bytes: 449 + line: 20 + character: 22 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 449 + line: 20 + character: 22 + end_position: + bytes: 454 + line: 20 + character: 27 + token_type: + type: Identifier + identifier: _bar1 +- start_position: + bytes: 454 + line: 20 + character: 27 + end_position: + bytes: 455 + line: 20 + character: 28 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 455 + line: 20 + character: 28 + end_position: + bytes: 456 + line: 20 + character: 29 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 456 + line: 20 + character: 29 + end_position: + bytes: 462 + line: 20 + character: 35 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 462 + line: 20 + character: 35 + end_position: + bytes: 463 + line: 20 + character: 35 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 463 + line: 21 + character: 1 + end_position: + bytes: 464 + line: 21 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 464 + line: 22 + character: 1 + end_position: + bytes: 472 + line: 22 + character: 9 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 472 + line: 22 + character: 9 + end_position: + bytes: 473 + line: 22 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 473 + line: 22 + character: 10 + end_position: + bytes: 477 + line: 22 + character: 14 + token_type: + type: Identifier + identifier: _fn0 +- start_position: + bytes: 477 + line: 22 + character: 14 + end_position: + bytes: 478 + line: 22 + character: 15 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 478 + line: 22 + character: 15 + end_position: + bytes: 483 + line: 22 + character: 20 + token_type: + type: Identifier + identifier: param +- start_position: + bytes: 483 + line: 22 + character: 20 + end_position: + bytes: 484 + line: 22 + character: 21 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 484 + line: 22 + character: 21 + end_position: + bytes: 485 + line: 22 + character: 22 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 485 + line: 22 + character: 22 + end_position: + bytes: 491 + line: 22 + character: 28 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 491 + line: 22 + character: 28 + end_position: + bytes: 492 + line: 22 + character: 29 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 492 + line: 22 + character: 29 + end_position: + bytes: 493 + line: 22 + character: 30 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 493 + line: 22 + character: 30 + end_position: + bytes: 494 + line: 22 + character: 31 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 494 + line: 22 + character: 31 + end_position: + bytes: 500 + line: 22 + character: 37 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 500 + line: 22 + character: 37 + end_position: + bytes: 501 + line: 22 + character: 37 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 501 + line: 23 + character: 1 + end_position: + bytes: 502 + line: 23 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 502 + line: 23 + character: 2 + end_position: + bytes: 508 + line: 23 + character: 8 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 508 + line: 23 + character: 8 + end_position: + bytes: 509 + line: 23 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 509 + line: 23 + character: 9 + end_position: + bytes: 514 + line: 23 + character: 14 + token_type: + type: Identifier + identifier: param +- start_position: + bytes: 514 + line: 23 + character: 14 + end_position: + bytes: 515 + line: 23 + character: 14 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 515 + line: 24 + character: 1 + end_position: + bytes: 518 + line: 24 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 518 + line: 24 + character: 4 + end_position: + bytes: 519 + line: 24 + character: 4 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 519 + line: 25 + character: 1 + end_position: + bytes: 520 + line: 25 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 520 + line: 26 + character: 1 + end_position: + bytes: 528 + line: 26 + character: 9 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 528 + line: 26 + character: 9 + end_position: + bytes: 529 + line: 26 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 529 + line: 26 + character: 10 + end_position: + bytes: 533 + line: 26 + character: 14 + token_type: + type: Identifier + identifier: _fn2 +- start_position: + bytes: 533 + line: 26 + character: 14 + end_position: + bytes: 534 + line: 26 + character: 15 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 534 + line: 26 + character: 15 + end_position: + bytes: 535 + line: 26 + character: 16 + token_type: + type: Identifier + identifier: a +- start_position: + bytes: 535 + line: 26 + character: 16 + end_position: + bytes: 536 + line: 26 + character: 17 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 536 + line: 26 + character: 17 + end_position: + bytes: 537 + line: 26 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 537 + line: 26 + character: 18 + end_position: + bytes: 543 + line: 26 + character: 24 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 543 + line: 26 + character: 24 + end_position: + bytes: 544 + line: 26 + character: 25 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 544 + line: 26 + character: 25 + end_position: + bytes: 545 + line: 26 + character: 26 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 545 + line: 26 + character: 26 + end_position: + bytes: 546 + line: 26 + character: 27 + token_type: + type: Identifier + identifier: b +- start_position: + bytes: 546 + line: 26 + character: 27 + end_position: + bytes: 547 + line: 26 + character: 28 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 547 + line: 26 + character: 28 + end_position: + bytes: 548 + line: 26 + character: 29 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 548 + line: 26 + character: 29 + end_position: + bytes: 554 + line: 26 + character: 35 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 554 + line: 26 + character: 35 + end_position: + bytes: 555 + line: 26 + character: 36 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 555 + line: 26 + character: 36 + end_position: + bytes: 556 + line: 26 + character: 37 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 556 + line: 26 + character: 37 + end_position: + bytes: 559 + line: 26 + character: 40 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 559 + line: 26 + character: 40 + end_position: + bytes: 560 + line: 26 + character: 40 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 560 + line: 27 + character: 1 + end_position: + bytes: 561 + line: 27 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 561 + line: 28 + character: 1 + end_position: + bytes: 566 + line: 28 + character: 6 + token_type: + type: Symbol + symbol: local +- start_position: + bytes: 566 + line: 28 + character: 6 + end_position: + bytes: 567 + line: 28 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 567 + line: 28 + character: 7 + end_position: + bytes: 571 + line: 28 + character: 11 + token_type: + type: Identifier + identifier: _fn3 +- start_position: + bytes: 571 + line: 28 + character: 11 + end_position: + bytes: 572 + line: 28 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 572 + line: 28 + character: 12 + end_position: + bytes: 573 + line: 28 + character: 13 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 573 + line: 28 + character: 13 + end_position: + bytes: 574 + line: 28 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 574 + line: 28 + character: 14 + end_position: + bytes: 582 + line: 28 + character: 22 + token_type: + type: Symbol + symbol: function +- start_position: + bytes: 582 + line: 28 + character: 22 + end_position: + bytes: 583 + line: 28 + character: 23 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 583 + line: 28 + character: 23 + end_position: + bytes: 584 + line: 28 + character: 24 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 584 + line: 28 + character: 24 + end_position: + bytes: 585 + line: 28 + character: 25 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 585 + line: 28 + character: 25 + end_position: + bytes: 586 + line: 28 + character: 26 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 586 + line: 28 + character: 26 + end_position: + bytes: 592 + line: 28 + character: 32 + token_type: + type: Identifier + identifier: number +- start_position: + bytes: 592 + line: 28 + character: 32 + end_position: + bytes: 593 + line: 28 + character: 33 + token_type: + type: Symbol + symbol: "?" +- start_position: + bytes: 593 + line: 28 + character: 33 + end_position: + bytes: 594 + line: 28 + character: 33 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 594 + line: 29 + character: 1 + end_position: + bytes: 595 + line: 29 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 595 + line: 29 + character: 2 + end_position: + bytes: 601 + line: 29 + character: 8 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 601 + line: 29 + character: 8 + end_position: + bytes: 602 + line: 29 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 602 + line: 29 + character: 9 + end_position: + bytes: 603 + line: 29 + character: 10 + token_type: + type: Number + text: "3" +- start_position: + bytes: 603 + line: 29 + character: 10 + end_position: + bytes: 604 + line: 29 + character: 10 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 604 + line: 30 + character: 1 + end_position: + bytes: 607 + line: 30 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 607 + line: 30 + character: 4 + end_position: + bytes: 608 + line: 30 + character: 4 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 608 + line: 31 + character: 1 + end_position: + bytes: 608 + line: 31 + character: 1 + token_type: + type: Eof diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_chained_optionals/ast.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_chained_optionals/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..571b14414d2b8904c09890b554ea3800a11392d8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_chained_optionals/ast.snap @@ -0,0 +1,655 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: ast.nodes() +input_file: vvs_parser/tests/roblox_cases/pass/types_chained_optionals +--- +stmts: + - - TypeDeclaration: + type_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: type + trailing_trivia: + - start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " + base: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Identifier + identifier: Config + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: " " + declare_as: + Table: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: "\n" + - leading_trivia: [] + token: + start_position: + bytes: 166 + line: 5 + character: 1 + end_position: + bytes: 167 + line: 5 + character: 2 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: [] + fields: + pairs: + - Punctuated: + - key: + Name: + leading_trivia: + - start_position: + bytes: 16 + line: 2 + character: 1 + end_position: + bytes: 20 + line: 2 + character: 5 + token_type: + type: Whitespace + characters: " " + token: + start_position: + bytes: 20 + line: 2 + character: 5 + end_position: + bytes: 27 + line: 2 + character: 12 + token_type: + type: Identifier + identifier: option1 + trailing_trivia: [] + colon: + leading_trivia: [] + token: + start_position: + bytes: 27 + line: 2 + character: 12 + end_position: + bytes: 28 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 28 + line: 2 + character: 13 + end_position: + bytes: 29 + line: 2 + character: 14 + token_type: + type: Whitespace + characters: " " + value: + Optional: + base: + Optional: + base: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 29 + line: 2 + character: 14 + end_position: + bytes: 35 + line: 2 + character: 20 + token_type: + type: Identifier + identifier: string + trailing_trivia: [] + question_mark: + leading_trivia: [] + token: + start_position: + bytes: 35 + line: 2 + character: 20 + end_position: + bytes: 36 + line: 2 + character: 21 + token_type: + type: Symbol + symbol: "?" + trailing_trivia: [] + question_mark: + leading_trivia: [] + token: + start_position: + bytes: 36 + line: 2 + character: 21 + end_position: + bytes: 37 + line: 2 + character: 22 + token_type: + type: Symbol + symbol: "?" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 37 + line: 2 + character: 22 + end_position: + bytes: 38 + line: 2 + character: 23 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 38 + line: 2 + character: 23 + end_position: + bytes: 39 + line: 2 + character: 24 + token_type: + type: Whitespace + characters: " " + - start_position: + bytes: 39 + line: 2 + character: 24 + end_position: + bytes: 78 + line: 2 + character: 63 + token_type: + type: SingleLineComment + comment: " you probably need it once in a while" + - start_position: + bytes: 78 + line: 2 + character: 63 + end_position: + bytes: 79 + line: 2 + character: 63 + token_type: + type: Whitespace + characters: "\n" + - Punctuated: + - key: + Name: + leading_trivia: + - start_position: + bytes: 79 + line: 3 + character: 1 + end_position: + bytes: 83 + line: 3 + character: 5 + token_type: + type: Whitespace + characters: " " + token: + start_position: + bytes: 83 + line: 3 + character: 5 + end_position: + bytes: 90 + line: 3 + character: 12 + token_type: + type: Identifier + identifier: option2 + trailing_trivia: [] + colon: + leading_trivia: [] + token: + start_position: + bytes: 90 + line: 3 + character: 12 + end_position: + bytes: 91 + line: 3 + character: 13 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 91 + line: 3 + character: 13 + end_position: + bytes: 92 + line: 3 + character: 14 + token_type: + type: Whitespace + characters: " " + value: + Optional: + base: + Optional: + base: + Optional: + base: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 92 + line: 3 + character: 14 + end_position: + bytes: 98 + line: 3 + character: 20 + token_type: + type: Identifier + identifier: string + trailing_trivia: [] + question_mark: + leading_trivia: [] + token: + start_position: + bytes: 98 + line: 3 + character: 20 + end_position: + bytes: 99 + line: 3 + character: 21 + token_type: + type: Symbol + symbol: "?" + trailing_trivia: [] + question_mark: + leading_trivia: [] + token: + start_position: + bytes: 99 + line: 3 + character: 21 + end_position: + bytes: 100 + line: 3 + character: 22 + token_type: + type: Symbol + symbol: "?" + trailing_trivia: [] + question_mark: + leading_trivia: [] + token: + start_position: + bytes: 100 + line: 3 + character: 22 + end_position: + bytes: 101 + line: 3 + character: 23 + token_type: + type: Symbol + symbol: "?" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 101 + line: 3 + character: 23 + end_position: + bytes: 102 + line: 3 + character: 24 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 102 + line: 3 + character: 24 + end_position: + bytes: 103 + line: 3 + character: 25 + token_type: + type: Whitespace + characters: " " + - start_position: + bytes: 103 + line: 3 + character: 25 + end_position: + bytes: 117 + line: 3 + character: 39 + token_type: + type: SingleLineComment + comment: " once a year" + - start_position: + bytes: 117 + line: 3 + character: 39 + end_position: + bytes: 118 + line: 3 + character: 39 + token_type: + type: Whitespace + characters: "\n" + - End: + key: + Name: + leading_trivia: + - start_position: + bytes: 118 + line: 4 + character: 1 + end_position: + bytes: 122 + line: 4 + character: 5 + token_type: + type: Whitespace + characters: " " + token: + start_position: + bytes: 122 + line: 4 + character: 5 + end_position: + bytes: 129 + line: 4 + character: 12 + token_type: + type: Identifier + identifier: option3 + trailing_trivia: [] + colon: + leading_trivia: [] + token: + start_position: + bytes: 129 + line: 4 + character: 12 + end_position: + bytes: 130 + line: 4 + character: 13 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 130 + line: 4 + character: 13 + end_position: + bytes: 131 + line: 4 + character: 14 + token_type: + type: Whitespace + characters: " " + value: + Optional: + base: + Optional: + base: + Optional: + base: + Optional: + base: + Optional: + base: + Optional: + base: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 131 + line: 4 + character: 14 + end_position: + bytes: 137 + line: 4 + character: 20 + token_type: + type: Identifier + identifier: string + trailing_trivia: [] + question_mark: + leading_trivia: [] + token: + start_position: + bytes: 137 + line: 4 + character: 20 + end_position: + bytes: 138 + line: 4 + character: 21 + token_type: + type: Symbol + symbol: "?" + trailing_trivia: [] + question_mark: + leading_trivia: [] + token: + start_position: + bytes: 138 + line: 4 + character: 21 + end_position: + bytes: 139 + line: 4 + character: 22 + token_type: + type: Symbol + symbol: "?" + trailing_trivia: [] + question_mark: + leading_trivia: [] + token: + start_position: + bytes: 139 + line: 4 + character: 22 + end_position: + bytes: 140 + line: 4 + character: 23 + token_type: + type: Symbol + symbol: "?" + trailing_trivia: [] + question_mark: + leading_trivia: [] + token: + start_position: + bytes: 140 + line: 4 + character: 23 + end_position: + bytes: 141 + line: 4 + character: 24 + token_type: + type: Symbol + symbol: "?" + trailing_trivia: [] + question_mark: + leading_trivia: [] + token: + start_position: + bytes: 141 + line: 4 + character: 24 + end_position: + bytes: 142 + line: 4 + character: 25 + token_type: + type: Symbol + symbol: "?" + trailing_trivia: [] + question_mark: + leading_trivia: [] + token: + start_position: + bytes: 142 + line: 4 + character: 25 + end_position: + bytes: 143 + line: 4 + character: 26 + token_type: + type: Symbol + symbol: "?" + trailing_trivia: + - start_position: + bytes: 143 + line: 4 + character: 26 + end_position: + bytes: 144 + line: 4 + character: 27 + token_type: + type: Whitespace + characters: " " + - start_position: + bytes: 144 + line: 4 + character: 27 + end_position: + bytes: 165 + line: 4 + character: 48 + token_type: + type: SingleLineComment + comment: " once in your life!" + - start_position: + bytes: 165 + line: 4 + character: 48 + end_position: + bytes: 166 + line: 4 + character: 48 + token_type: + type: Whitespace + characters: "\n" + - ~ diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_chained_optionals/source.lua b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_chained_optionals/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..0809eac6534258c3e682f19f6323304df3f07bb8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_chained_optionals/source.lua @@ -0,0 +1,5 @@ +type Config = { + option1: string??, -- you probably need it once in a while + option2: string???, -- once a year + option3: string?????? -- once in your life! +} \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_chained_optionals/tokens.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_chained_optionals/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..30a578174dfc2eb856cfc4e8521e89f9424bf064 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_chained_optionals/tokens.snap @@ -0,0 +1,521 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: type +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Identifier + identifier: Config +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 16 + line: 2 + character: 1 + end_position: + bytes: 20 + line: 2 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 20 + line: 2 + character: 5 + end_position: + bytes: 27 + line: 2 + character: 12 + token_type: + type: Identifier + identifier: option1 +- start_position: + bytes: 27 + line: 2 + character: 12 + end_position: + bytes: 28 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 28 + line: 2 + character: 13 + end_position: + bytes: 29 + line: 2 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 29 + line: 2 + character: 14 + end_position: + bytes: 35 + line: 2 + character: 20 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 35 + line: 2 + character: 20 + end_position: + bytes: 36 + line: 2 + character: 21 + token_type: + type: Symbol + symbol: "?" +- start_position: + bytes: 36 + line: 2 + character: 21 + end_position: + bytes: 37 + line: 2 + character: 22 + token_type: + type: Symbol + symbol: "?" +- start_position: + bytes: 37 + line: 2 + character: 22 + end_position: + bytes: 38 + line: 2 + character: 23 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 38 + line: 2 + character: 23 + end_position: + bytes: 39 + line: 2 + character: 24 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 39 + line: 2 + character: 24 + end_position: + bytes: 78 + line: 2 + character: 63 + token_type: + type: SingleLineComment + comment: " you probably need it once in a while" +- start_position: + bytes: 78 + line: 2 + character: 63 + end_position: + bytes: 79 + line: 2 + character: 63 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 79 + line: 3 + character: 1 + end_position: + bytes: 83 + line: 3 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 83 + line: 3 + character: 5 + end_position: + bytes: 90 + line: 3 + character: 12 + token_type: + type: Identifier + identifier: option2 +- start_position: + bytes: 90 + line: 3 + character: 12 + end_position: + bytes: 91 + line: 3 + character: 13 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 91 + line: 3 + character: 13 + end_position: + bytes: 92 + line: 3 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 92 + line: 3 + character: 14 + end_position: + bytes: 98 + line: 3 + character: 20 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 98 + line: 3 + character: 20 + end_position: + bytes: 99 + line: 3 + character: 21 + token_type: + type: Symbol + symbol: "?" +- start_position: + bytes: 99 + line: 3 + character: 21 + end_position: + bytes: 100 + line: 3 + character: 22 + token_type: + type: Symbol + symbol: "?" +- start_position: + bytes: 100 + line: 3 + character: 22 + end_position: + bytes: 101 + line: 3 + character: 23 + token_type: + type: Symbol + symbol: "?" +- start_position: + bytes: 101 + line: 3 + character: 23 + end_position: + bytes: 102 + line: 3 + character: 24 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 102 + line: 3 + character: 24 + end_position: + bytes: 103 + line: 3 + character: 25 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 103 + line: 3 + character: 25 + end_position: + bytes: 117 + line: 3 + character: 39 + token_type: + type: SingleLineComment + comment: " once a year" +- start_position: + bytes: 117 + line: 3 + character: 39 + end_position: + bytes: 118 + line: 3 + character: 39 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 118 + line: 4 + character: 1 + end_position: + bytes: 122 + line: 4 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 122 + line: 4 + character: 5 + end_position: + bytes: 129 + line: 4 + character: 12 + token_type: + type: Identifier + identifier: option3 +- start_position: + bytes: 129 + line: 4 + character: 12 + end_position: + bytes: 130 + line: 4 + character: 13 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 130 + line: 4 + character: 13 + end_position: + bytes: 131 + line: 4 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 131 + line: 4 + character: 14 + end_position: + bytes: 137 + line: 4 + character: 20 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 137 + line: 4 + character: 20 + end_position: + bytes: 138 + line: 4 + character: 21 + token_type: + type: Symbol + symbol: "?" +- start_position: + bytes: 138 + line: 4 + character: 21 + end_position: + bytes: 139 + line: 4 + character: 22 + token_type: + type: Symbol + symbol: "?" +- start_position: + bytes: 139 + line: 4 + character: 22 + end_position: + bytes: 140 + line: 4 + character: 23 + token_type: + type: Symbol + symbol: "?" +- start_position: + bytes: 140 + line: 4 + character: 23 + end_position: + bytes: 141 + line: 4 + character: 24 + token_type: + type: Symbol + symbol: "?" +- start_position: + bytes: 141 + line: 4 + character: 24 + end_position: + bytes: 142 + line: 4 + character: 25 + token_type: + type: Symbol + symbol: "?" +- start_position: + bytes: 142 + line: 4 + character: 25 + end_position: + bytes: 143 + line: 4 + character: 26 + token_type: + type: Symbol + symbol: "?" +- start_position: + bytes: 143 + line: 4 + character: 26 + end_position: + bytes: 144 + line: 4 + character: 27 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 144 + line: 4 + character: 27 + end_position: + bytes: 165 + line: 4 + character: 48 + token_type: + type: SingleLineComment + comment: " once in your life!" +- start_position: + bytes: 165 + line: 4 + character: 48 + end_position: + bytes: 166 + line: 4 + character: 48 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 166 + line: 5 + character: 1 + end_position: + bytes: 167 + line: 5 + character: 2 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 167 + line: 5 + character: 2 + end_position: + bytes: 167 + line: 5 + character: 2 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_loops/ast.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_loops/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..09e4dc03bdf21f57b721a53731c6eea34189515f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_loops/ast.snap @@ -0,0 +1,605 @@ +--- +source: full-moon/tests/pass_cases.rs +assertion_line: 52 +expression: ast.nodes() +input_file: full-moon/tests/roblox_cases/pass/types_loops +--- +stmts: + - - GenericFor: + for_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: for + trailing_trivia: + - start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " + names: + pairs: + - Punctuated: + - leading_trivia: [] + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Identifier + identifier: i + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + - End: + leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Identifier + identifier: v + trailing_trivia: [] + in_token: + leading_trivia: [] + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: in + trailing_trivia: + - start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Identifier + identifier: pairs + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 26 + line: 1 + character: 27 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 26 + line: 1 + character: 27 + end_position: + bytes: 27 + line: 1 + character: 28 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 27 + line: 1 + character: 28 + end_position: + bytes: 28 + line: 1 + character: 29 + token_type: + type: Whitespace + characters: " " + arguments: + pairs: [] + do_token: + leading_trivia: [] + token: + start_position: + bytes: 28 + line: 1 + character: 29 + end_position: + bytes: 30 + line: 1 + character: 31 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 30 + line: 1 + character: 31 + end_position: + bytes: 31 + line: 1 + character: 31 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: [] + end_token: + leading_trivia: + - start_position: + bytes: 31 + line: 2 + character: 1 + end_position: + bytes: 32 + line: 2 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 32 + line: 3 + character: 1 + end_position: + bytes: 35 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 35 + line: 3 + character: 4 + end_position: + bytes: 36 + line: 3 + character: 4 + token_type: + type: Whitespace + characters: "\n" + type_specifiers: + - ~ + - punctuation: + leading_trivia: [] + token: + start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Identifier + identifier: string + trailing_trivia: + - start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Whitespace + characters: " " + - ~ + - - NumericFor: + for_token: + leading_trivia: + - start_position: + bytes: 36 + line: 4 + character: 1 + end_position: + bytes: 37 + line: 4 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 37 + line: 5 + character: 1 + end_position: + bytes: 40 + line: 5 + character: 4 + token_type: + type: Symbol + symbol: for + trailing_trivia: + - start_position: + bytes: 40 + line: 5 + character: 4 + end_position: + bytes: 41 + line: 5 + character: 5 + token_type: + type: Whitespace + characters: " " + index_variable: + leading_trivia: [] + token: + start_position: + bytes: 41 + line: 5 + character: 5 + end_position: + bytes: 42 + line: 5 + character: 6 + token_type: + type: Identifier + identifier: i + trailing_trivia: [] + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 51 + line: 5 + character: 15 + end_position: + bytes: 52 + line: 5 + character: 16 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 52 + line: 5 + character: 16 + end_position: + bytes: 53 + line: 5 + character: 17 + token_type: + type: Whitespace + characters: " " + start: + Number: + leading_trivia: [] + token: + start_position: + bytes: 53 + line: 5 + character: 17 + end_position: + bytes: 54 + line: 5 + character: 18 + token_type: + type: Number + text: "1" + trailing_trivia: [] + start_end_comma: + leading_trivia: [] + token: + start_position: + bytes: 54 + line: 5 + character: 18 + end_position: + bytes: 55 + line: 5 + character: 19 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 55 + line: 5 + character: 19 + end_position: + bytes: 56 + line: 5 + character: 20 + token_type: + type: Whitespace + characters: " " + end: + Number: + leading_trivia: [] + token: + start_position: + bytes: 56 + line: 5 + character: 20 + end_position: + bytes: 58 + line: 5 + character: 22 + token_type: + type: Number + text: "10" + trailing_trivia: [] + end_step_comma: + leading_trivia: [] + token: + start_position: + bytes: 58 + line: 5 + character: 22 + end_position: + bytes: 59 + line: 5 + character: 23 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 59 + line: 5 + character: 23 + end_position: + bytes: 60 + line: 5 + character: 24 + token_type: + type: Whitespace + characters: " " + step: + Number: + leading_trivia: [] + token: + start_position: + bytes: 60 + line: 5 + character: 24 + end_position: + bytes: 61 + line: 5 + character: 25 + token_type: + type: Number + text: "2" + trailing_trivia: + - start_position: + bytes: 61 + line: 5 + character: 25 + end_position: + bytes: 62 + line: 5 + character: 26 + token_type: + type: Whitespace + characters: " " + do_token: + leading_trivia: [] + token: + start_position: + bytes: 62 + line: 5 + character: 26 + end_position: + bytes: 64 + line: 5 + character: 28 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 64 + line: 5 + character: 28 + end_position: + bytes: 65 + line: 5 + character: 28 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: [] + end_token: + leading_trivia: + - start_position: + bytes: 65 + line: 6 + character: 1 + end_position: + bytes: 70 + line: 6 + character: 5 + token_type: + type: Whitespace + characters: " \n" + token: + start_position: + bytes: 70 + line: 7 + character: 1 + end_position: + bytes: 73 + line: 7 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: [] + type_specifier: + punctuation: + leading_trivia: [] + token: + start_position: + bytes: 42 + line: 5 + character: 6 + end_position: + bytes: 43 + line: 5 + character: 7 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 43 + line: 5 + character: 7 + end_position: + bytes: 44 + line: 5 + character: 8 + token_type: + type: Whitespace + characters: " " + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 44 + line: 5 + character: 8 + end_position: + bytes: 50 + line: 5 + character: 14 + token_type: + type: Identifier + identifier: number + trailing_trivia: + - start_position: + bytes: 50 + line: 5 + character: 14 + end_position: + bytes: 51 + line: 5 + character: 15 + token_type: + type: Whitespace + characters: " " + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_loops/source.lua b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_loops/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..cd3905656fb7f04ba8925a393de9c31b37d94f0c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_loops/source.lua @@ -0,0 +1,7 @@ +for i, v: string in pairs() do + +end + +for i: number = 1, 10, 2 do + +end \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_loops/tokens.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_loops/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..84b58afe8b64d5f5e3561b8f972b0a98a05adad4 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_loops/tokens.snap @@ -0,0 +1,490 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +input_file: full-moon/tests/roblox_cases/pass/types_loops + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: for +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Identifier + identifier: i +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Identifier + identifier: v +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Symbol + symbol: in +- start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Identifier + identifier: pairs +- start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 26 + line: 1 + character: 27 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 26 + line: 1 + character: 27 + end_position: + bytes: 27 + line: 1 + character: 28 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 27 + line: 1 + character: 28 + end_position: + bytes: 28 + line: 1 + character: 29 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 28 + line: 1 + character: 29 + end_position: + bytes: 30 + line: 1 + character: 31 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 30 + line: 1 + character: 31 + end_position: + bytes: 31 + line: 1 + character: 31 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 31 + line: 2 + character: 1 + end_position: + bytes: 32 + line: 2 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 32 + line: 3 + character: 1 + end_position: + bytes: 35 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 35 + line: 3 + character: 4 + end_position: + bytes: 36 + line: 3 + character: 4 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 36 + line: 4 + character: 1 + end_position: + bytes: 37 + line: 4 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 37 + line: 5 + character: 1 + end_position: + bytes: 40 + line: 5 + character: 4 + token_type: + type: Symbol + symbol: for +- start_position: + bytes: 40 + line: 5 + character: 4 + end_position: + bytes: 41 + line: 5 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 41 + line: 5 + character: 5 + end_position: + bytes: 42 + line: 5 + character: 6 + token_type: + type: Identifier + identifier: i +- start_position: + bytes: 42 + line: 5 + character: 6 + end_position: + bytes: 43 + line: 5 + character: 7 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 43 + line: 5 + character: 7 + end_position: + bytes: 44 + line: 5 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 44 + line: 5 + character: 8 + end_position: + bytes: 50 + line: 5 + character: 14 + token_type: + type: Identifier + identifier: number +- start_position: + bytes: 50 + line: 5 + character: 14 + end_position: + bytes: 51 + line: 5 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 51 + line: 5 + character: 15 + end_position: + bytes: 52 + line: 5 + character: 16 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 52 + line: 5 + character: 16 + end_position: + bytes: 53 + line: 5 + character: 17 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 53 + line: 5 + character: 17 + end_position: + bytes: 54 + line: 5 + character: 18 + token_type: + type: Number + text: "1" +- start_position: + bytes: 54 + line: 5 + character: 18 + end_position: + bytes: 55 + line: 5 + character: 19 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 55 + line: 5 + character: 19 + end_position: + bytes: 56 + line: 5 + character: 20 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 56 + line: 5 + character: 20 + end_position: + bytes: 58 + line: 5 + character: 22 + token_type: + type: Number + text: "10" +- start_position: + bytes: 58 + line: 5 + character: 22 + end_position: + bytes: 59 + line: 5 + character: 23 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 59 + line: 5 + character: 23 + end_position: + bytes: 60 + line: 5 + character: 24 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 60 + line: 5 + character: 24 + end_position: + bytes: 61 + line: 5 + character: 25 + token_type: + type: Number + text: "2" +- start_position: + bytes: 61 + line: 5 + character: 25 + end_position: + bytes: 62 + line: 5 + character: 26 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 62 + line: 5 + character: 26 + end_position: + bytes: 64 + line: 5 + character: 28 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 64 + line: 5 + character: 28 + end_position: + bytes: 65 + line: 5 + character: 28 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 65 + line: 6 + character: 1 + end_position: + bytes: 70 + line: 6 + character: 5 + token_type: + type: Whitespace + characters: " \n" +- start_position: + bytes: 70 + line: 7 + character: 1 + end_position: + bytes: 73 + line: 7 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 73 + line: 7 + character: 4 + end_position: + bytes: 73 + line: 7 + character: 4 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_nested_array/ast.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_nested_array/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..8030101cfaaa22092b8927b1f05a1d52eeb3122e --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_nested_array/ast.snap @@ -0,0 +1,532 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: ast.nodes() +input_file: vvs_parser/tests/roblox_cases/pass/types_nested_array +--- +stmts: + - - TypeDeclaration: + type_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: type + trailing_trivia: + - start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " + base: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Identifier + identifier: Foo + trailing_trivia: + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " + declare_as: + Array: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Whitespace + characters: " " + - leading_trivia: [] + token: + start_position: + bytes: 24 + line: 1 + character: 25 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: + - start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 26 + line: 1 + character: 26 + token_type: + type: Whitespace + characters: "\n" + type_info: + Array: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " + - leading_trivia: [] + token: + start_position: + bytes: 22 + line: 1 + character: 23 + end_position: + bytes: 23 + line: 1 + character: 24 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: + - start_position: + bytes: 23 + line: 1 + character: 24 + end_position: + bytes: 24 + line: 1 + character: 25 + token_type: + type: Whitespace + characters: " " + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Identifier + identifier: string + trailing_trivia: + - start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Whitespace + characters: " " + - ~ + - - TypeDeclaration: + type_token: + leading_trivia: [] + token: + start_position: + bytes: 26 + line: 2 + character: 1 + end_position: + bytes: 30 + line: 2 + character: 5 + token_type: + type: Identifier + identifier: type + trailing_trivia: + - start_position: + bytes: 30 + line: 2 + character: 5 + end_position: + bytes: 31 + line: 2 + character: 6 + token_type: + type: Whitespace + characters: " " + base: + leading_trivia: [] + token: + start_position: + bytes: 31 + line: 2 + character: 6 + end_position: + bytes: 34 + line: 2 + character: 9 + token_type: + type: Identifier + identifier: Foo + trailing_trivia: + - start_position: + bytes: 34 + line: 2 + character: 9 + end_position: + bytes: 35 + line: 2 + character: 10 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 35 + line: 2 + character: 10 + end_position: + bytes: 36 + line: 2 + character: 11 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 36 + line: 2 + character: 11 + end_position: + bytes: 37 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: " " + declare_as: + Array: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 37 + line: 2 + character: 12 + end_position: + bytes: 38 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 38 + line: 2 + character: 13 + end_position: + bytes: 39 + line: 2 + character: 14 + token_type: + type: Whitespace + characters: " " + - leading_trivia: [] + token: + start_position: + bytes: 67 + line: 2 + character: 42 + end_position: + bytes: 68 + line: 2 + character: 43 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: [] + type_info: + Table: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 39 + line: 2 + character: 14 + end_position: + bytes: 40 + line: 2 + character: 15 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 65 + line: 2 + character: 40 + end_position: + bytes: 66 + line: 2 + character: 41 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: + - start_position: + bytes: 66 + line: 2 + character: 41 + end_position: + bytes: 67 + line: 2 + character: 42 + token_type: + type: Whitespace + characters: " " + fields: + pairs: + - Punctuated: + - key: + Name: + leading_trivia: [] + token: + start_position: + bytes: 40 + line: 2 + character: 15 + end_position: + bytes: 44 + line: 2 + character: 19 + token_type: + type: Identifier + identifier: Name + trailing_trivia: [] + colon: + leading_trivia: [] + token: + start_position: + bytes: 44 + line: 2 + character: 19 + end_position: + bytes: 45 + line: 2 + character: 20 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 45 + line: 2 + character: 20 + end_position: + bytes: 46 + line: 2 + character: 21 + token_type: + type: Whitespace + characters: " " + value: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 46 + line: 2 + character: 21 + end_position: + bytes: 52 + line: 2 + character: 27 + token_type: + type: Identifier + identifier: string + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 52 + line: 2 + character: 27 + end_position: + bytes: 53 + line: 2 + character: 28 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 53 + line: 2 + character: 28 + end_position: + bytes: 54 + line: 2 + character: 29 + token_type: + type: Whitespace + characters: " " + - End: + key: + Name: + leading_trivia: [] + token: + start_position: + bytes: 54 + line: 2 + character: 29 + end_position: + bytes: 57 + line: 2 + character: 32 + token_type: + type: Identifier + identifier: Foo + trailing_trivia: [] + colon: + leading_trivia: [] + token: + start_position: + bytes: 57 + line: 2 + character: 32 + end_position: + bytes: 58 + line: 2 + character: 33 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 58 + line: 2 + character: 33 + end_position: + bytes: 59 + line: 2 + character: 34 + token_type: + type: Whitespace + characters: " " + value: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 59 + line: 2 + character: 34 + end_position: + bytes: 65 + line: 2 + character: 40 + token_type: + type: Identifier + identifier: number + trailing_trivia: [] + - ~ diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_nested_array/source.lua b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_nested_array/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..a479e797e53add700159b98ed1896f98aa628e28 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_nested_array/source.lua @@ -0,0 +1,2 @@ +type Foo = { { string } } +type Foo = { {Name: string, Foo: number} } \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_nested_array/tokens.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_nested_array/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..b7bc4f7a556b8cfbc93b1a8631d31392bed41352 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_nested_array/tokens.snap @@ -0,0 +1,434 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: type +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Identifier + identifier: Foo +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 22 + line: 1 + character: 23 + end_position: + bytes: 23 + line: 1 + character: 24 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 23 + line: 1 + character: 24 + end_position: + bytes: 24 + line: 1 + character: 25 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 24 + line: 1 + character: 25 + end_position: + bytes: 25 + line: 1 + character: 26 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 25 + line: 1 + character: 26 + end_position: + bytes: 26 + line: 1 + character: 26 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 26 + line: 2 + character: 1 + end_position: + bytes: 30 + line: 2 + character: 5 + token_type: + type: Identifier + identifier: type +- start_position: + bytes: 30 + line: 2 + character: 5 + end_position: + bytes: 31 + line: 2 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 31 + line: 2 + character: 6 + end_position: + bytes: 34 + line: 2 + character: 9 + token_type: + type: Identifier + identifier: Foo +- start_position: + bytes: 34 + line: 2 + character: 9 + end_position: + bytes: 35 + line: 2 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 35 + line: 2 + character: 10 + end_position: + bytes: 36 + line: 2 + character: 11 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 36 + line: 2 + character: 11 + end_position: + bytes: 37 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 37 + line: 2 + character: 12 + end_position: + bytes: 38 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 38 + line: 2 + character: 13 + end_position: + bytes: 39 + line: 2 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 39 + line: 2 + character: 14 + end_position: + bytes: 40 + line: 2 + character: 15 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 40 + line: 2 + character: 15 + end_position: + bytes: 44 + line: 2 + character: 19 + token_type: + type: Identifier + identifier: Name +- start_position: + bytes: 44 + line: 2 + character: 19 + end_position: + bytes: 45 + line: 2 + character: 20 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 45 + line: 2 + character: 20 + end_position: + bytes: 46 + line: 2 + character: 21 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 46 + line: 2 + character: 21 + end_position: + bytes: 52 + line: 2 + character: 27 + token_type: + type: Identifier + identifier: string +- start_position: + bytes: 52 + line: 2 + character: 27 + end_position: + bytes: 53 + line: 2 + character: 28 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 53 + line: 2 + character: 28 + end_position: + bytes: 54 + line: 2 + character: 29 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 54 + line: 2 + character: 29 + end_position: + bytes: 57 + line: 2 + character: 32 + token_type: + type: Identifier + identifier: Foo +- start_position: + bytes: 57 + line: 2 + character: 32 + end_position: + bytes: 58 + line: 2 + character: 33 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 58 + line: 2 + character: 33 + end_position: + bytes: 59 + line: 2 + character: 34 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 59 + line: 2 + character: 34 + end_position: + bytes: 65 + line: 2 + character: 40 + token_type: + type: Identifier + identifier: number +- start_position: + bytes: 65 + line: 2 + character: 40 + end_position: + bytes: 66 + line: 2 + character: 41 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 66 + line: 2 + character: 41 + end_position: + bytes: 67 + line: 2 + character: 42 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 67 + line: 2 + character: 42 + end_position: + bytes: 68 + line: 2 + character: 43 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 68 + line: 2 + character: 43 + end_position: + bytes: 68 + line: 2 + character: 43 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_semicolon_delimeter/ast.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_semicolon_delimeter/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..917421f1e862f78bd5833443b37b180ebe73dca8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_semicolon_delimeter/ast.snap @@ -0,0 +1,321 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: ast.nodes() +input_file: vvs_parser/tests/roblox_cases/pass/types_semicolon_delimeter +--- +stmts: + - - TypeDeclaration: + type_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: type + trailing_trivia: + - start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " + base: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Identifier + identifier: Foo + trailing_trivia: + - start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " + declare_as: + Table: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: "\n" + - leading_trivia: [] + token: + start_position: + bytes: 41 + line: 4 + character: 1 + end_position: + bytes: 42 + line: 4 + character: 2 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: [] + fields: + pairs: + - Punctuated: + - key: + Name: + leading_trivia: + - start_position: + bytes: 13 + line: 2 + character: 1 + end_position: + bytes: 14 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 14 + line: 2 + character: 2 + end_position: + bytes: 17 + line: 2 + character: 5 + token_type: + type: Identifier + identifier: bar + trailing_trivia: [] + colon: + leading_trivia: [] + token: + start_position: + bytes: 17 + line: 2 + character: 5 + end_position: + bytes: 18 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 18 + line: 2 + character: 6 + end_position: + bytes: 19 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " + value: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 19 + line: 2 + character: 7 + end_position: + bytes: 25 + line: 2 + character: 13 + token_type: + type: Identifier + identifier: number + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 25 + line: 2 + character: 13 + end_position: + bytes: 26 + line: 2 + character: 14 + token_type: + type: Symbol + symbol: ; + trailing_trivia: + - start_position: + bytes: 26 + line: 2 + character: 14 + end_position: + bytes: 27 + line: 2 + character: 14 + token_type: + type: Whitespace + characters: "\n" + - Punctuated: + - key: + Name: + leading_trivia: + - start_position: + bytes: 27 + line: 3 + character: 1 + end_position: + bytes: 28 + line: 3 + character: 2 + token_type: + type: Whitespace + characters: "\t" + token: + start_position: + bytes: 28 + line: 3 + character: 2 + end_position: + bytes: 31 + line: 3 + character: 5 + token_type: + type: Identifier + identifier: baz + trailing_trivia: [] + colon: + leading_trivia: [] + token: + start_position: + bytes: 31 + line: 3 + character: 5 + end_position: + bytes: 32 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 32 + line: 3 + character: 6 + end_position: + bytes: 33 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " + value: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 33 + line: 3 + character: 7 + end_position: + bytes: 39 + line: 3 + character: 13 + token_type: + type: Identifier + identifier: number + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 39 + line: 3 + character: 13 + end_position: + bytes: 40 + line: 3 + character: 14 + token_type: + type: Symbol + symbol: ; + trailing_trivia: + - start_position: + bytes: 40 + line: 3 + character: 14 + end_position: + bytes: 41 + line: 3 + character: 14 + token_type: + type: Whitespace + characters: "\n" + - ~ diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_semicolon_delimeter/source.lua b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_semicolon_delimeter/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..48a69f27ab9278207c7ffcd6b22aa06d244ce4ea --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_semicolon_delimeter/source.lua @@ -0,0 +1,4 @@ +type Foo = { + bar: number; + baz: number; +} \ No newline at end of file diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_semicolon_delimeter/tokens.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_semicolon_delimeter/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..38cffb0941ad3866e913597cdf2c00d382d99141 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/types_semicolon_delimeter/tokens.snap @@ -0,0 +1,269 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens + +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Identifier + identifier: type +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Identifier + identifier: Foo +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 13 + line: 2 + character: 1 + end_position: + bytes: 14 + line: 2 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 14 + line: 2 + character: 2 + end_position: + bytes: 17 + line: 2 + character: 5 + token_type: + type: Identifier + identifier: bar +- start_position: + bytes: 17 + line: 2 + character: 5 + end_position: + bytes: 18 + line: 2 + character: 6 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 18 + line: 2 + character: 6 + end_position: + bytes: 19 + line: 2 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 19 + line: 2 + character: 7 + end_position: + bytes: 25 + line: 2 + character: 13 + token_type: + type: Identifier + identifier: number +- start_position: + bytes: 25 + line: 2 + character: 13 + end_position: + bytes: 26 + line: 2 + character: 14 + token_type: + type: Symbol + symbol: ; +- start_position: + bytes: 26 + line: 2 + character: 14 + end_position: + bytes: 27 + line: 2 + character: 14 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 27 + line: 3 + character: 1 + end_position: + bytes: 28 + line: 3 + character: 2 + token_type: + type: Whitespace + characters: "\t" +- start_position: + bytes: 28 + line: 3 + character: 2 + end_position: + bytes: 31 + line: 3 + character: 5 + token_type: + type: Identifier + identifier: baz +- start_position: + bytes: 31 + line: 3 + character: 5 + end_position: + bytes: 32 + line: 3 + character: 6 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 32 + line: 3 + character: 6 + end_position: + bytes: 33 + line: 3 + character: 7 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 33 + line: 3 + character: 7 + end_position: + bytes: 39 + line: 3 + character: 13 + token_type: + type: Identifier + identifier: number +- start_position: + bytes: 39 + line: 3 + character: 13 + end_position: + bytes: 40 + line: 3 + character: 14 + token_type: + type: Symbol + symbol: ; +- start_position: + bytes: 40 + line: 3 + character: 14 + end_position: + bytes: 41 + line: 3 + character: 14 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 41 + line: 4 + character: 1 + end_position: + bytes: 42 + line: 4 + character: 2 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 42 + line: 4 + character: 2 + end_position: + bytes: 42 + line: 4 + character: 2 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/z-escape-string/ast.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/z-escape-string/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..6f787e5d6218fcb681b9b92b600cd8a6ff9471a6 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/z-escape-string/ast.snap @@ -0,0 +1,181 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: ast.nodes() +--- +stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Identifier + identifier: print + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 29 + line: 2 + character: 12 + end_position: + bytes: 30 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 30 + line: 2 + character: 13 + end_position: + bytes: 31 + line: 2 + character: 13 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 29 + line: 2 + character: 12 + token_type: + type: StringLiteral + literal: "testing \\z\n\t twelve" + quote_type: Double + trailing_trivia: [] + - ~ + - - FunctionCall: + prefix: + Name: + leading_trivia: + - start_position: + bytes: 31 + line: 3 + character: 1 + end_position: + bytes: 32 + line: 3 + character: 1 + token_type: + type: Whitespace + characters: "\n" + token: + start_position: + bytes: 32 + line: 4 + character: 1 + end_position: + bytes: 37 + line: 4 + character: 6 + token_type: + type: Identifier + identifier: print + trailing_trivia: [] + suffixes: + - Call: + AnonymousCall: + Parentheses: + parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 37 + line: 4 + character: 6 + end_position: + bytes: 38 + line: 4 + character: 7 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 54 + line: 5 + character: 8 + end_position: + bytes: 55 + line: 5 + character: 9 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 55 + line: 5 + character: 9 + end_position: + bytes: 56 + line: 5 + character: 9 + token_type: + type: Whitespace + characters: "\n" + arguments: + pairs: + - End: + String: + leading_trivia: [] + token: + start_position: + bytes: 38 + line: 4 + character: 7 + end_position: + bytes: 54 + line: 5 + character: 8 + token_type: + type: StringLiteral + literal: "Hello \\\n\tWorld" + quote_type: Double + trailing_trivia: [] + - ~ + diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/z-escape-string/source.lua b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/z-escape-string/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..3167d6c9333526ec55f3b7eda0195b0e88b0da28 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/z-escape-string/source.lua @@ -0,0 +1,5 @@ +print("testing \z + twelve") + +print("Hello \ + World") diff --git a/src/Rust/vvs_parser/src/tests/roblox_cases/pass/z-escape-string/tokens.snap b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/z-escape-string/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..42a20cf64cee1f2e8a24acafccd50735a10a2980 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/roblox_cases/pass/z-escape-string/tokens.snap @@ -0,0 +1,138 @@ +--- +source: full-moon/tests/pass_cases.rs +expression: tokens +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Identifier + identifier: print +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 29 + line: 2 + character: 12 + token_type: + type: StringLiteral + literal: "testing \\z\n\t twelve" + quote_type: Double +- start_position: + bytes: 29 + line: 2 + character: 12 + end_position: + bytes: 30 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 30 + line: 2 + character: 13 + end_position: + bytes: 31 + line: 2 + character: 13 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 31 + line: 3 + character: 1 + end_position: + bytes: 32 + line: 3 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 32 + line: 4 + character: 1 + end_position: + bytes: 37 + line: 4 + character: 6 + token_type: + type: Identifier + identifier: print +- start_position: + bytes: 37 + line: 4 + character: 6 + end_position: + bytes: 38 + line: 4 + character: 7 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 38 + line: 4 + character: 7 + end_position: + bytes: 54 + line: 5 + character: 8 + token_type: + type: StringLiteral + literal: "Hello \\\n\tWorld" + quote_type: Double +- start_position: + bytes: 54 + line: 5 + character: 8 + end_position: + bytes: 55 + line: 5 + character: 9 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 55 + line: 5 + character: 9 + end_position: + bytes: 56 + line: 5 + character: 9 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 56 + line: 6 + character: 1 + end_position: + bytes: 56 + line: 6 + character: 1 + token_type: + type: Eof + diff --git a/src/Rust/vvs_parser/src/tests/visitors.rs b/src/Rust/vvs_parser/src/tests/visitors.rs new file mode 100644 index 0000000000000000000000000000000000000000..838b32ed17e568437aa2b2faf3030ea8cfa6714f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/visitors.rs @@ -0,0 +1,164 @@ +use crate::{ + ast, + prelude::parser::parse_lua_tree as parse, + tokenizer::*, + visitors::{Visitor, VisitorMut}, +}; + +#[test] +fn test_visitor() { + struct FunctionCallVisitor { + called: Vec<String>, + } + + impl Visitor for FunctionCallVisitor { + fn visit_function_call(&mut self, call: &ast::FunctionCall) { + match call.prefix() { + ast::Prefix::Name(token) => { + self.called.push(token.to_string()); + } + + _ => unreachable!(), + } + } + } + + let code = parse("foo(bar())").unwrap(); + let mut visitor = FunctionCallVisitor { called: Vec::new() }; + + visitor.visit_ast(&code); + + assert_eq!(visitor.called, vec!["foo", "bar"]); +} + +#[test] +fn test_visitor_mut() { + struct SnakeNamer; + + impl VisitorMut for SnakeNamer { + fn visit_local_assignment(&mut self, assignment: ast::LocalAssignment) -> ast::LocalAssignment { + let name_list = assignment + .names() + .pairs() + .map(|name| { + name.to_owned().map(|value| { + value.with_token(Token::new(TokenType::Identifier { + identifier: value.token().to_string().replace('s', "sss").into(), + })) + }) + }) + .collect(); + + assignment.with_names(name_list) + } + } + + let code = parse("local dogs, snakes = 1").unwrap(); + let code = SnakeNamer.visit_ast(code); + assert_eq!(format!("{code}"), "local dogsss, sssnakesss = 1"); + + struct PositionValidator; + + impl Visitor for PositionValidator { + fn visit_local_assignment(&mut self, assignment: &ast::LocalAssignment) { + for name in assignment.names() { + assert_eq!(name.end_position().bytes() - name.start_position().bytes(), name.token().to_string().len()); + } + } + } + + let code = code.update_positions(); + PositionValidator.visit_ast(&code); +} + +#[test] +fn test_visit_token() { + #[derive(Default)] + struct CommentVisitor { + comments: Vec<String>, + } + + impl Visitor for CommentVisitor { + fn visit_single_line_comment(&mut self, token: &Token) { + self.comments.push(token.to_string()); + } + } + + let mut visitor = CommentVisitor::default(); + + let code = parse( + r#" + -- bla bla bla + --[[ + multi line comment + ]] + + -- comment here + local x = 1 + -- and here + "#, + ) + .unwrap(); + + visitor.visit_ast(&code); + assert_eq!(visitor.comments, vec!["-- bla bla bla", "-- comment here", "-- and here"]); +} + +#[test] +fn test_end_visit() { + #[derive(Default)] + struct LogVisitor { + instructions: usize, + if_start_at: usize, + if_end_at: usize, + called_at: usize, + } + + impl Visitor for LogVisitor { + fn visit_if(&mut self, _: &ast::If) { + self.instructions += 1; + self.if_start_at = self.instructions + } + + fn visit_if_end(&mut self, _: &ast::If) { + self.instructions += 1; + self.if_end_at = self.instructions; + } + + fn visit_call(&mut self, _: &ast::Call) { + self.instructions += 1; + self.called_at = self.instructions; + } + } + + let mut visitor = LogVisitor::default(); + visitor.visit_ast( + &parse( + r#" + if true then + call() + end + "#, + ) + .unwrap(), + ); + + assert_eq!(visitor.if_start_at, 1); + assert_eq!(visitor.called_at, 2); + assert_eq!(visitor.if_end_at, 3); +} + +#[test] +fn test_unary_visitor_regression() { + struct TestVisitor(bool); + + impl Visitor for TestVisitor { + fn visit_un_op(&mut self, _: &ast::UnOp) { + self.0 = true; + } + } + + let mut visitor = TestVisitor(false); + visitor.visit_ast(&parse("local x = #{}").unwrap()); + assert!(visitor.0, "Unary operation was not visited"); +} diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/job/ast.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/job/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..f1086135d4e9d45e1c919bc53ca1b46c3cc56073 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/job/ast.snap @@ -0,0 +1,21 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: result.ast() +input_file: vvs_parser/tests/vivy_cases/fail/parser/job +--- +nodes: + stmts: [] +eof: + leading_trivia: [] + token: + start_position: + bytes: 14 + line: 2 + character: 1 + end_position: + bytes: 14 + line: 2 + character: 1 + token_type: + type: Eof + trailing_trivia: [] diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/job/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/job/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..d95027ad42ce250ec1dcb4cd99f2a6d06807bf80 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/job/ast_to_string.snap @@ -0,0 +1,6 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: "vvs_parser::print(&ast)" +input_file: vvs_parser/tests/vivy_cases/fail/parser/job +--- +"" diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/job/error_display.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/job/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..a5166952a242cb194fc6458b65f748555408dad7 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/job/error_display.snap @@ -0,0 +1,10 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: vvs_parser/tests/vivy_cases/fail/parser/job +--- +error[ast]: invalid name for a job, can't be ponctuated or have columns + ┌─ source.lua:1:1 + │ +1 │ job x.y() end + │ ^^^ diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/job/errors.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/job/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..f04aec5a1a412075239264bb8d938cdbdb3b2cfe --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/job/errors.snap @@ -0,0 +1,19 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: result.errors() +input_file: vvs_parser/tests/vivy_cases/fail/parser/job +--- +- AstError: + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: job + additional: "invalid name for a job, can't be ponctuated or have columns" diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/job/source.lua b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/job/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..618768b8006870fc5c3aafb364fd3d2cb0282664 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/job/source.lua @@ -0,0 +1 @@ +job x.y() end diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/job/tokens.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/job/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..77d1ec72232e8ad6a0838f56f037d9eaa2b75f25 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/job/tokens.snap @@ -0,0 +1,125 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: tokens +input_file: vvs_parser/tests/vivy_cases/fail/parser/job +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: job +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Identifier + identifier: x +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Identifier + identifier: y +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 10 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 9 + line: 1 + character: 10 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 14 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 14 + line: 2 + character: 1 + end_position: + bytes: 14 + line: 2 + character: 1 + token_type: + type: Eof diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/main_after_returns/ast.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/main_after_returns/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..cdf8616bcaedc29ebcb8a6f8f87645dc0809e29d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/main_after_returns/ast.snap @@ -0,0 +1,169 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: result.ast() +input_file: vvs_parser/tests/vivy_cases/fail/parser/main_after_returns +--- +nodes: + stmts: + - - FunctionCall: + prefix: + Name: + leading_trivia: [] + token: + start_position: + bytes: 51 + line: 3 + character: 19 + end_position: + bytes: 52 + line: 3 + character: 20 + token_type: + type: Identifier + identifier: a + trailing_trivia: [] + suffixes: + - Index: + Dot: + dot: + leading_trivia: [] + token: + start_position: + bytes: 52 + line: 3 + character: 20 + end_position: + bytes: 53 + line: 3 + character: 21 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + name: + leading_trivia: [] + token: + start_position: + bytes: 53 + line: 3 + character: 21 + end_position: + bytes: 54 + line: 3 + character: 22 + token_type: + type: Identifier + identifier: b + trailing_trivia: + - start_position: + bytes: 54 + line: 3 + character: 22 + end_position: + bytes: 55 + line: 3 + character: 23 + token_type: + type: Whitespace + characters: " " + - Call: + AnonymousCall: + TableConstructor: + braces: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 55 + line: 3 + character: 23 + end_position: + bytes: 56 + line: 3 + character: 24 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 56 + line: 3 + character: 24 + end_position: + bytes: 57 + line: 3 + character: 25 + token_type: + type: Whitespace + characters: " " + - leading_trivia: [] + token: + start_position: + bytes: 64 + line: 3 + character: 32 + end_position: + bytes: 65 + line: 3 + character: 33 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: + - start_position: + bytes: 65 + line: 3 + character: 33 + end_position: + bytes: 66 + line: 3 + character: 33 + token_type: + type: Whitespace + characters: "\n" + fields: + pairs: + - End: + NoKey: + String: + leading_trivia: [] + token: + start_position: + bytes: 57 + line: 3 + character: 25 + end_position: + bytes: 63 + line: 3 + character: 31 + token_type: + type: StringLiteral + literal: init + quote_type: Double + trailing_trivia: + - start_position: + bytes: 63 + line: 3 + character: 31 + end_position: + bytes: 64 + line: 3 + character: 32 + token_type: + type: Whitespace + characters: " " + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 70 + line: 5 + character: 1 + end_position: + bytes: 70 + line: 5 + character: 1 + token_type: + type: Eof + trailing_trivia: [] diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/main_after_returns/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/main_after_returns/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..d7ff39c53eb6fbffec6cd5259c867911b71c13d5 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/main_after_returns/ast_to_string.snap @@ -0,0 +1,6 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: "vvs_parser::print(&ast)" +input_file: vvs_parser/tests/vivy_cases/fail/parser/main_after_returns +--- +"a.b { \"init\" }\n" diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/main_after_returns/error_display.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/main_after_returns/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..9dadcef5ce6a82a34056b5a5dd89377aa9053fcb --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/main_after_returns/error_display.snap @@ -0,0 +1,16 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: vvs_parser/tests/vivy_cases/fail/parser/main_after_returns +--- +error[ast]: expected no more assignations after the return token + ┌─ source.lua:3:5 + │ +3 │ "something" = a.b { "init" } + │ ^^^^^^^^^^^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:3:5 + │ +3 │ "something" = a.b { "init" } + │ ^^^^^^^^^^^ diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/main_after_returns/errors.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/main_after_returns/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..233876e129c4cee008c864a9f23c18675f4187b1 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/main_after_returns/errors.snap @@ -0,0 +1,35 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: result.errors() +input_file: vvs_parser/tests/vivy_cases/fail/parser/main_after_returns +--- +- AstError: + token: + start_position: + bytes: 37 + line: 3 + character: 5 + end_position: + bytes: 48 + line: 3 + character: 16 + token_type: + type: StringLiteral + literal: something + quote_type: Double + additional: expected no more assignations after the return token +- AstError: + token: + start_position: + bytes: 37 + line: 3 + character: 5 + end_position: + bytes: 48 + line: 3 + character: 16 + token_type: + type: StringLiteral + literal: something + quote_type: Double + additional: "unexpected token, this needs to be a statement" diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/main_after_returns/source.lua b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/main_after_returns/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..d72b488f6be48637f8b769bc6f31c99a27d0d249 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/main_after_returns/source.lua @@ -0,0 +1,4 @@ +main "init" do + return "init" + "something" = a.b { "init" } +end diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/main_after_returns/tokens.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/main_after_returns/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..ab44c98cd0aaea593eb5caa1fc20d6c7394c1f28 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/main_after_returns/tokens.snap @@ -0,0 +1,327 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: tokens +input_file: vvs_parser/tests/vivy_cases/fail/parser/main_after_returns +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Symbol + symbol: main +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: StringLiteral + literal: init + quote_type: Double +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 15 + line: 2 + character: 1 + end_position: + bytes: 19 + line: 2 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 19 + line: 2 + character: 5 + end_position: + bytes: 25 + line: 2 + character: 11 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 25 + line: 2 + character: 11 + end_position: + bytes: 26 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 26 + line: 2 + character: 12 + end_position: + bytes: 32 + line: 2 + character: 18 + token_type: + type: StringLiteral + literal: init + quote_type: Double +- start_position: + bytes: 32 + line: 2 + character: 18 + end_position: + bytes: 33 + line: 2 + character: 18 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 33 + line: 3 + character: 1 + end_position: + bytes: 37 + line: 3 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 37 + line: 3 + character: 5 + end_position: + bytes: 48 + line: 3 + character: 16 + token_type: + type: StringLiteral + literal: something + quote_type: Double +- start_position: + bytes: 48 + line: 3 + character: 16 + end_position: + bytes: 49 + line: 3 + character: 17 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 49 + line: 3 + character: 17 + end_position: + bytes: 50 + line: 3 + character: 18 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 50 + line: 3 + character: 18 + end_position: + bytes: 51 + line: 3 + character: 19 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 51 + line: 3 + character: 19 + end_position: + bytes: 52 + line: 3 + character: 20 + token_type: + type: Identifier + identifier: a +- start_position: + bytes: 52 + line: 3 + character: 20 + end_position: + bytes: 53 + line: 3 + character: 21 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 53 + line: 3 + character: 21 + end_position: + bytes: 54 + line: 3 + character: 22 + token_type: + type: Identifier + identifier: b +- start_position: + bytes: 54 + line: 3 + character: 22 + end_position: + bytes: 55 + line: 3 + character: 23 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 55 + line: 3 + character: 23 + end_position: + bytes: 56 + line: 3 + character: 24 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 56 + line: 3 + character: 24 + end_position: + bytes: 57 + line: 3 + character: 25 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 57 + line: 3 + character: 25 + end_position: + bytes: 63 + line: 3 + character: 31 + token_type: + type: StringLiteral + literal: init + quote_type: Double +- start_position: + bytes: 63 + line: 3 + character: 31 + end_position: + bytes: 64 + line: 3 + character: 32 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 64 + line: 3 + character: 32 + end_position: + bytes: 65 + line: 3 + character: 33 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 65 + line: 3 + character: 33 + end_position: + bytes: 66 + line: 3 + character: 33 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 66 + line: 4 + character: 1 + end_position: + bytes: 69 + line: 4 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 69 + line: 4 + character: 4 + end_position: + bytes: 70 + line: 4 + character: 4 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 70 + line: 5 + character: 1 + end_position: + bytes: 70 + line: 5 + character: 1 + token_type: + type: Eof diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_1/ast.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..68fa43d1e982816f2d9bc85055a591d860afd670 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_1/ast.snap @@ -0,0 +1,21 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: result.ast() +input_file: vvs_parser/tests/vivy_cases/fail/parser/option_decl_1 +--- +nodes: + stmts: [] +eof: + leading_trivia: [] + token: + start_position: + bytes: 9 + line: 2 + character: 1 + end_position: + bytes: 9 + line: 2 + character: 1 + token_type: + type: Eof + trailing_trivia: [] diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_1/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_1/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..c603e68ae8b3d78b634081221bd40a91263aab4f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_1/ast_to_string.snap @@ -0,0 +1,6 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: "vvs_parser::print(&ast)" +input_file: vvs_parser/tests/vivy_cases/fail/parser/option_decl_1 +--- +"" diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_1/error_display.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_1/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..983823754580b575a18991836b4fbd1b3220ea02 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_1/error_display.snap @@ -0,0 +1,16 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: vvs_parser/tests/vivy_cases/fail/parser/option_decl_1 +--- +error[ast]: invalid option specifier statement + ┌─ source.lua:1:1 + │ +1 │ option a + │ ^^^^^^ + +error[ast]: expected ',' to continue option list or '=' to assign default values to the list + ┌─ source.lua:2:1 + │ +2 │ + │ ^ diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_1/errors.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_1/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..4f6ddb4e9a028e325883b4569eed848752ad7456 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_1/errors.snap @@ -0,0 +1,32 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: result.errors() +input_file: vvs_parser/tests/vivy_cases/fail/parser/option_decl_1 +--- +- AstError: + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: option + additional: invalid option specifier statement +- AstError: + token: + start_position: + bytes: 9 + line: 2 + character: 1 + end_position: + bytes: 9 + line: 2 + character: 1 + token_type: + type: Eof + additional: "expected ',' to continue option list or '=' to assign default values to the list" diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_1/source.lua b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..b90250c6f4a9e1ce67f43474f369adbb98c71dd6 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_1/source.lua @@ -0,0 +1 @@ +option a diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_1/tokens.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..9f7d957ad9d48109feb7a1d5bf6b164b0b8ce467 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_1/tokens.snap @@ -0,0 +1,59 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: tokens +input_file: vvs_parser/tests/vivy_cases/fail/parser/option_decl_1 +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: option +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 8 + line: 1 + character: 9 + token_type: + type: Identifier + identifier: a +- start_position: + bytes: 8 + line: 1 + character: 9 + end_position: + bytes: 9 + line: 1 + character: 9 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 9 + line: 2 + character: 1 + end_position: + bytes: 9 + line: 2 + character: 1 + token_type: + type: Eof diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_2/ast.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..059a13e8d80614a7e00a577437e1a6a9380f9174 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_2/ast.snap @@ -0,0 +1,107 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: result.ast() +input_file: vvs_parser/tests/vivy_cases/fail/parser/option_decl_2 +--- +nodes: + stmts: + - - Assignment: + var_list: + pairs: + - End: + Name: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Identifier + identifier: tata + trailing_trivia: + - start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 21 + line: 1 + character: 21 + token_type: + type: Whitespace + characters: "\n" + - ~ +eof: + leading_trivia: [] + token: + start_position: + bytes: 21 + line: 2 + character: 1 + end_position: + bytes: 21 + line: 2 + character: 1 + token_type: + type: Eof + trailing_trivia: [] diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_2/ast_to_string.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_2/ast_to_string.snap new file mode 100644 index 0000000000000000000000000000000000000000..ee6801e9f16c0f477b9b7cd2e73013f3324f5fbc --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_2/ast_to_string.snap @@ -0,0 +1,6 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: "vvs_parser::print(&ast)" +input_file: vvs_parser/tests/vivy_cases/fail/parser/option_decl_2 +--- +"tata = 1\n" diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_2/error_display.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_2/error_display.snap new file mode 100644 index 0000000000000000000000000000000000000000..8765e4ba769e1f84a2c15ed4880238d2c5ac5219 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_2/error_display.snap @@ -0,0 +1,22 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: "String::from_utf8(output.into_inner()).unwrap()" +input_file: vvs_parser/tests/vivy_cases/fail/parser/option_decl_2 +--- +error[ast]: invalid option specifier statement + ┌─ source.lua:1:1 + │ +1 │ option toto.tata = 1 + │ ^^^^^^ + +error[ast]: expected ',' to continue option list or '=' to assign default values to the list + ┌─ source.lua:1:12 + │ +1 │ option toto.tata = 1 + │ ^ + +error[ast]: unexpected token, this needs to be a statement + ┌─ source.lua:1:12 + │ +1 │ option toto.tata = 1 + │ ^ diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_2/errors.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_2/errors.snap new file mode 100644 index 0000000000000000000000000000000000000000..3ebe248192601c14e8dc9e5fce4cc946398c07f8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_2/errors.snap @@ -0,0 +1,47 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: result.errors() +input_file: vvs_parser/tests/vivy_cases/fail/parser/option_decl_2 +--- +- AstError: + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: option + additional: invalid option specifier statement +- AstError: + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: "." + additional: "expected ',' to continue option list or '=' to assign default values to the list" +- AstError: + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: "." + additional: "unexpected token, this needs to be a statement" diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_2/source.lua b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..eb3a72dca8c25a38d7f83903b47d05eeed0279b1 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_2/source.lua @@ -0,0 +1 @@ +option toto.tata = 1 diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_2/tokens.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..f9281e8190f0846377036a93a5602249e991e55a --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/fail/parser/option_decl_2/tokens.snap @@ -0,0 +1,125 @@ +--- +source: vvs_parser/tests/fail_cases.rs +expression: tokens +input_file: vvs_parser/tests/vivy_cases/fail/parser/option_decl_2 +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: option +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Identifier + identifier: toto +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Identifier + identifier: tata +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 17 + line: 1 + character: 18 + end_position: + bytes: 18 + line: 1 + character: 19 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 18 + line: 1 + character: 19 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Number + text: "1" +- start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 21 + line: 1 + character: 21 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 21 + line: 2 + character: 1 + end_position: + bytes: 21 + line: 2 + character: 1 + token_type: + type: Eof diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/import/ast.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/import/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..c225f36eff95091e670323edc7da1cf8aeb68490 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/import/ast.snap @@ -0,0 +1,62 @@ +--- +source: vvs_parser/tests/pass_cases.rs +assertion_line: 44 +expression: ast.nodes() +input_file: vvs_parser/tests/vivy/pass/import +--- +stmts: + - - Import: + import_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: import + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + name: + leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: StringLiteral + literal: math + quote_type: Double + trailing_trivia: + - start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 14 + token_type: + type: Whitespace + characters: "\n" + - ~ diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/import/source.lua b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/import/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..468fc97f46b605683e4c67a8a63e46d1b757433f --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/import/source.lua @@ -0,0 +1 @@ +import "math" diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/import/tokens.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/import/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..f029aafc12f0ed7790219b33ceab7e88d97e1217 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/import/tokens.snap @@ -0,0 +1,60 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: tokens +input_file: vvs_parser/tests/vivy/pass/import +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: import +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: StringLiteral + literal: math + quote_type: Double +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 14 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 14 + line: 2 + character: 1 + end_position: + bytes: 14 + line: 2 + character: 1 + token_type: + type: Eof diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/job/ast.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/job/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..2138fc2774ab75bc6b13f09d2d5d7b5fc6a17295 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/job/ast.snap @@ -0,0 +1,126 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: ast.nodes() +input_file: vvs_parser/tests/vivy_cases/pass/job +--- +stmts: + - - JobDeclaration: + function_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: job + trailing_trivia: + - start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " + name: + names: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Identifier + identifier: retime + trailing_trivia: [] + colon_name: ~ + body: + parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Whitespace + characters: " " + parameters: + pairs: [] + type_specifiers: [] + block: + stmts: [] + end_token: + leading_trivia: [] + token: + start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 17 + token_type: + type: Whitespace + characters: "\n" + - ~ diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/job/source.lua b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/job/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..34231ae6d00a2995bdae3be7873940e9a634890d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/job/source.lua @@ -0,0 +1 @@ +job retime() end diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/job/tokens.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/job/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..8ee54e754994e7f9f35d2fc2208e050c9743a66d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/job/tokens.snap @@ -0,0 +1,103 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: tokens +input_file: vvs_parser/tests/vivy/pass/job +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: job +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 10 + line: 1 + character: 11 + token_type: + type: Identifier + identifier: retime +- start_position: + bytes: 10 + line: 1 + character: 11 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 16 + line: 1 + character: 17 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 16 + line: 1 + character: 17 + end_position: + bytes: 17 + line: 1 + character: 17 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 17 + line: 2 + character: 1 + end_position: + bytes: 17 + line: 2 + character: 1 + token_type: + type: Eof diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/job_yield/ast.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/job_yield/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..b629273e5e221649e3280526cbe191c6e52d7812 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/job_yield/ast.snap @@ -0,0 +1,963 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: ast.nodes() +input_file: vvs_parser/tests/vivy_cases/pass/job_yield +--- +stmts: + - - JobDeclaration: + function_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: job + trailing_trivia: + - start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " + name: + names: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Identifier + identifier: syl_modulo + trailing_trivia: [] + colon_name: ~ + body: + parameters_parentheses: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 51 + line: 1 + character: 52 + end_position: + bytes: 52 + line: 1 + character: 53 + token_type: + type: Symbol + symbol: ) + trailing_trivia: [] + parameters: + pairs: + - Punctuated: + - name: + leading_trivia: [] + token: + start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Identifier + identifier: every + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 28 + line: 1 + character: 29 + end_position: + bytes: 29 + line: 1 + character: 30 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 29 + line: 1 + character: 30 + end_position: + bytes: 30 + line: 1 + character: 31 + token_type: + type: Whitespace + characters: " " + - Punctuated: + - name: + leading_trivia: [] + token: + start_position: + bytes: 30 + line: 1 + character: 31 + end_position: + bytes: 34 + line: 1 + character: 35 + token_type: + type: Identifier + identifier: disp + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 42 + line: 1 + character: 43 + end_position: + bytes: 43 + line: 1 + character: 44 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 43 + line: 1 + character: 44 + end_position: + bytes: 44 + line: 1 + character: 45 + token_type: + type: Whitespace + characters: " " + - End: + name: + leading_trivia: [] + token: + start_position: + bytes: 44 + line: 1 + character: 45 + end_position: + bytes: 45 + line: 1 + character: 46 + token_type: + type: Identifier + identifier: l + trailing_trivia: [] + type_specifiers: + - punctuation: + leading_trivia: [] + token: + start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Whitespace + characters: " " + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 22 + line: 1 + character: 23 + end_position: + bytes: 28 + line: 1 + character: 29 + token_type: + type: Identifier + identifier: number + trailing_trivia: [] + - punctuation: + leading_trivia: [] + token: + start_position: + bytes: 34 + line: 1 + character: 35 + end_position: + bytes: 35 + line: 1 + character: 36 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 35 + line: 1 + character: 36 + end_position: + bytes: 36 + line: 1 + character: 37 + token_type: + type: Whitespace + characters: " " + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 36 + line: 1 + character: 37 + end_position: + bytes: 42 + line: 1 + character: 43 + token_type: + type: Identifier + identifier: number + trailing_trivia: [] + - punctuation: + leading_trivia: [] + token: + start_position: + bytes: 45 + line: 1 + character: 46 + end_position: + bytes: 46 + line: 1 + character: 47 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 46 + line: 1 + character: 47 + end_position: + bytes: 47 + line: 1 + character: 48 + token_type: + type: Whitespace + characters: " " + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 47 + line: 1 + character: 48 + end_position: + bytes: 51 + line: 1 + character: 52 + token_type: + type: Identifier + identifier: line + trailing_trivia: [] + return_type: + punctuation: + leading_trivia: [] + token: + start_position: + bytes: 52 + line: 1 + character: 53 + end_position: + bytes: 53 + line: 1 + character: 54 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 53 + line: 1 + character: 54 + end_position: + bytes: 54 + line: 1 + character: 55 + token_type: + type: Whitespace + characters: " " + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 54 + line: 1 + character: 55 + end_position: + bytes: 58 + line: 1 + character: 59 + token_type: + type: Identifier + identifier: line + trailing_trivia: + - start_position: + bytes: 58 + line: 1 + character: 59 + end_position: + bytes: 59 + line: 1 + character: 59 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - GenericFor: + for_token: + leading_trivia: + - start_position: + bytes: 59 + line: 2 + character: 1 + end_position: + bytes: 63 + line: 2 + character: 5 + token_type: + type: Whitespace + characters: " " + token: + start_position: + bytes: 63 + line: 2 + character: 5 + end_position: + bytes: 66 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: for + trailing_trivia: + - start_position: + bytes: 66 + line: 2 + character: 8 + end_position: + bytes: 67 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " + names: + pairs: + - Punctuated: + - leading_trivia: [] + token: + start_position: + bytes: 67 + line: 2 + character: 9 + end_position: + bytes: 68 + line: 2 + character: 10 + token_type: + type: Identifier + identifier: i + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 68 + line: 2 + character: 10 + end_position: + bytes: 69 + line: 2 + character: 11 + token_type: + type: Symbol + symbol: "," + trailing_trivia: [] + - End: + leading_trivia: [] + token: + start_position: + bytes: 69 + line: 2 + character: 11 + end_position: + bytes: 70 + line: 2 + character: 12 + token_type: + type: Identifier + identifier: s + trailing_trivia: + - start_position: + bytes: 70 + line: 2 + character: 12 + end_position: + bytes: 71 + line: 2 + character: 13 + token_type: + type: Whitespace + characters: " " + in_token: + leading_trivia: [] + token: + start_position: + bytes: 71 + line: 2 + character: 13 + end_position: + bytes: 73 + line: 2 + character: 15 + token_type: + type: Symbol + symbol: in + trailing_trivia: + - start_position: + bytes: 73 + line: 2 + character: 15 + end_position: + bytes: 74 + line: 2 + character: 16 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 74 + line: 2 + character: 16 + end_position: + bytes: 75 + line: 2 + character: 17 + token_type: + type: Identifier + identifier: l + trailing_trivia: + - start_position: + bytes: 75 + line: 2 + character: 17 + end_position: + bytes: 76 + line: 2 + character: 18 + token_type: + type: Whitespace + characters: " " + do_token: + leading_trivia: [] + token: + start_position: + bytes: 76 + line: 2 + character: 18 + end_position: + bytes: 78 + line: 2 + character: 20 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 78 + line: 2 + character: 20 + end_position: + bytes: 79 + line: 2 + character: 20 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - If: + if_token: + leading_trivia: + - start_position: + bytes: 79 + line: 3 + character: 1 + end_position: + bytes: 87 + line: 3 + character: 9 + token_type: + type: Whitespace + characters: " " + token: + start_position: + bytes: 87 + line: 3 + character: 9 + end_position: + bytes: 89 + line: 3 + character: 11 + token_type: + type: Symbol + symbol: if + trailing_trivia: + - start_position: + bytes: 89 + line: 3 + character: 11 + end_position: + bytes: 90 + line: 3 + character: 12 + token_type: + type: Whitespace + characters: " " + condition: + BinaryOperator: + lhs: + Parentheses: + contained: + tokens: + - leading_trivia: [] + token: + start_position: + bytes: 90 + line: 3 + character: 12 + end_position: + bytes: 91 + line: 3 + character: 13 + token_type: + type: Symbol + symbol: ( + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 100 + line: 3 + character: 22 + end_position: + bytes: 101 + line: 3 + character: 23 + token_type: + type: Symbol + symbol: ) + trailing_trivia: + - start_position: + bytes: 101 + line: 3 + character: 23 + end_position: + bytes: 102 + line: 3 + character: 24 + token_type: + type: Whitespace + characters: " " + expression: + BinaryOperator: + lhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 91 + line: 3 + character: 13 + end_position: + bytes: 92 + line: 3 + character: 14 + token_type: + type: Identifier + identifier: i + trailing_trivia: + - start_position: + bytes: 92 + line: 3 + character: 14 + end_position: + bytes: 93 + line: 3 + character: 15 + token_type: + type: Whitespace + characters: " " + binop: + Percent: + leading_trivia: [] + token: + start_position: + bytes: 93 + line: 3 + character: 15 + end_position: + bytes: 94 + line: 3 + character: 16 + token_type: + type: Symbol + symbol: "%" + trailing_trivia: + - start_position: + bytes: 94 + line: 3 + character: 16 + end_position: + bytes: 95 + line: 3 + character: 17 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 95 + line: 3 + character: 17 + end_position: + bytes: 100 + line: 3 + character: 22 + token_type: + type: Identifier + identifier: every + trailing_trivia: [] + binop: + TwoEqual: + leading_trivia: [] + token: + start_position: + bytes: 102 + line: 3 + character: 24 + end_position: + bytes: 104 + line: 3 + character: 26 + token_type: + type: Symbol + symbol: "==" + trailing_trivia: + - start_position: + bytes: 104 + line: 3 + character: 26 + end_position: + bytes: 105 + line: 3 + character: 27 + token_type: + type: Whitespace + characters: " " + rhs: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 105 + line: 3 + character: 27 + end_position: + bytes: 109 + line: 3 + character: 31 + token_type: + type: Identifier + identifier: disp + trailing_trivia: + - start_position: + bytes: 109 + line: 3 + character: 31 + end_position: + bytes: 110 + line: 3 + character: 32 + token_type: + type: Whitespace + characters: " " + then_token: + leading_trivia: [] + token: + start_position: + bytes: 110 + line: 3 + character: 32 + end_position: + bytes: 114 + line: 3 + character: 36 + token_type: + type: Symbol + symbol: then + trailing_trivia: + - start_position: + bytes: 114 + line: 3 + character: 36 + end_position: + bytes: 115 + line: 3 + character: 36 + token_type: + type: Whitespace + characters: "\n" + block: + stmts: + - - Yield: + token: + leading_trivia: + - start_position: + bytes: 115 + line: 4 + character: 1 + end_position: + bytes: 127 + line: 4 + character: 13 + token_type: + type: Whitespace + characters: " " + token: + start_position: + bytes: 127 + line: 4 + character: 13 + end_position: + bytes: 132 + line: 4 + character: 18 + token_type: + type: Symbol + symbol: yield + trailing_trivia: + - start_position: + bytes: 132 + line: 4 + character: 18 + end_position: + bytes: 133 + line: 4 + character: 19 + token_type: + type: Whitespace + characters: " " + yielded: + pairs: + - End: + Var: + Name: + leading_trivia: [] + token: + start_position: + bytes: 133 + line: 4 + character: 19 + end_position: + bytes: 134 + line: 4 + character: 20 + token_type: + type: Identifier + identifier: s + trailing_trivia: + - start_position: + bytes: 134 + line: 4 + character: 20 + end_position: + bytes: 135 + line: 4 + character: 20 + token_type: + type: Whitespace + characters: "\n" + - ~ + else_if: ~ + else_token: ~ + else: ~ + end_token: + leading_trivia: + - start_position: + bytes: 135 + line: 5 + character: 1 + end_position: + bytes: 143 + line: 5 + character: 9 + token_type: + type: Whitespace + characters: " " + token: + start_position: + bytes: 143 + line: 5 + character: 9 + end_position: + bytes: 146 + line: 5 + character: 12 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 146 + line: 5 + character: 12 + end_position: + bytes: 147 + line: 5 + character: 12 + token_type: + type: Whitespace + characters: "\n" + - ~ + end_token: + leading_trivia: + - start_position: + bytes: 147 + line: 6 + character: 1 + end_position: + bytes: 151 + line: 6 + character: 5 + token_type: + type: Whitespace + characters: " " + token: + start_position: + bytes: 151 + line: 6 + character: 5 + end_position: + bytes: 154 + line: 6 + character: 8 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 154 + line: 6 + character: 8 + end_position: + bytes: 155 + line: 6 + character: 8 + token_type: + type: Whitespace + characters: "\n" + type_specifiers: + - ~ + - ~ + - ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 155 + line: 7 + character: 1 + end_position: + bytes: 158 + line: 7 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 158 + line: 7 + character: 4 + end_position: + bytes: 159 + line: 7 + character: 4 + token_type: + type: Whitespace + characters: "\n" + - ~ diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/job_yield/source.lua b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/job_yield/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..0e319dc51c2c7bfa90423d9458d05375883c75b8 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/job_yield/source.lua @@ -0,0 +1,7 @@ +job syl_modulo(every: number, disp: number, l: line): line + for i,s in l do + if (i % every) == disp then + yield s + end + end +end diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/job_yield/tokens.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/job_yield/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..03ccae978349ddf0d4608a26325d251c1b507227 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/job_yield/tokens.snap @@ -0,0 +1,763 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: tokens +input_file: vvs_parser/tests/vivy_cases/pass/job_yield +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 3 + line: 1 + character: 4 + token_type: + type: Symbol + symbol: job +- start_position: + bytes: 3 + line: 1 + character: 4 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Identifier + identifier: syl_modulo +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Identifier + identifier: every +- start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 22 + line: 1 + character: 23 + end_position: + bytes: 28 + line: 1 + character: 29 + token_type: + type: Identifier + identifier: number +- start_position: + bytes: 28 + line: 1 + character: 29 + end_position: + bytes: 29 + line: 1 + character: 30 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 29 + line: 1 + character: 30 + end_position: + bytes: 30 + line: 1 + character: 31 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 30 + line: 1 + character: 31 + end_position: + bytes: 34 + line: 1 + character: 35 + token_type: + type: Identifier + identifier: disp +- start_position: + bytes: 34 + line: 1 + character: 35 + end_position: + bytes: 35 + line: 1 + character: 36 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 35 + line: 1 + character: 36 + end_position: + bytes: 36 + line: 1 + character: 37 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 36 + line: 1 + character: 37 + end_position: + bytes: 42 + line: 1 + character: 43 + token_type: + type: Identifier + identifier: number +- start_position: + bytes: 42 + line: 1 + character: 43 + end_position: + bytes: 43 + line: 1 + character: 44 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 43 + line: 1 + character: 44 + end_position: + bytes: 44 + line: 1 + character: 45 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 44 + line: 1 + character: 45 + end_position: + bytes: 45 + line: 1 + character: 46 + token_type: + type: Identifier + identifier: l +- start_position: + bytes: 45 + line: 1 + character: 46 + end_position: + bytes: 46 + line: 1 + character: 47 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 46 + line: 1 + character: 47 + end_position: + bytes: 47 + line: 1 + character: 48 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 47 + line: 1 + character: 48 + end_position: + bytes: 51 + line: 1 + character: 52 + token_type: + type: Identifier + identifier: line +- start_position: + bytes: 51 + line: 1 + character: 52 + end_position: + bytes: 52 + line: 1 + character: 53 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 52 + line: 1 + character: 53 + end_position: + bytes: 53 + line: 1 + character: 54 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 53 + line: 1 + character: 54 + end_position: + bytes: 54 + line: 1 + character: 55 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 54 + line: 1 + character: 55 + end_position: + bytes: 58 + line: 1 + character: 59 + token_type: + type: Identifier + identifier: line +- start_position: + bytes: 58 + line: 1 + character: 59 + end_position: + bytes: 59 + line: 1 + character: 59 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 59 + line: 2 + character: 1 + end_position: + bytes: 63 + line: 2 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 63 + line: 2 + character: 5 + end_position: + bytes: 66 + line: 2 + character: 8 + token_type: + type: Symbol + symbol: for +- start_position: + bytes: 66 + line: 2 + character: 8 + end_position: + bytes: 67 + line: 2 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 67 + line: 2 + character: 9 + end_position: + bytes: 68 + line: 2 + character: 10 + token_type: + type: Identifier + identifier: i +- start_position: + bytes: 68 + line: 2 + character: 10 + end_position: + bytes: 69 + line: 2 + character: 11 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 69 + line: 2 + character: 11 + end_position: + bytes: 70 + line: 2 + character: 12 + token_type: + type: Identifier + identifier: s +- start_position: + bytes: 70 + line: 2 + character: 12 + end_position: + bytes: 71 + line: 2 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 71 + line: 2 + character: 13 + end_position: + bytes: 73 + line: 2 + character: 15 + token_type: + type: Symbol + symbol: in +- start_position: + bytes: 73 + line: 2 + character: 15 + end_position: + bytes: 74 + line: 2 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 74 + line: 2 + character: 16 + end_position: + bytes: 75 + line: 2 + character: 17 + token_type: + type: Identifier + identifier: l +- start_position: + bytes: 75 + line: 2 + character: 17 + end_position: + bytes: 76 + line: 2 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 76 + line: 2 + character: 18 + end_position: + bytes: 78 + line: 2 + character: 20 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 78 + line: 2 + character: 20 + end_position: + bytes: 79 + line: 2 + character: 20 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 79 + line: 3 + character: 1 + end_position: + bytes: 87 + line: 3 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 87 + line: 3 + character: 9 + end_position: + bytes: 89 + line: 3 + character: 11 + token_type: + type: Symbol + symbol: if +- start_position: + bytes: 89 + line: 3 + character: 11 + end_position: + bytes: 90 + line: 3 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 90 + line: 3 + character: 12 + end_position: + bytes: 91 + line: 3 + character: 13 + token_type: + type: Symbol + symbol: ( +- start_position: + bytes: 91 + line: 3 + character: 13 + end_position: + bytes: 92 + line: 3 + character: 14 + token_type: + type: Identifier + identifier: i +- start_position: + bytes: 92 + line: 3 + character: 14 + end_position: + bytes: 93 + line: 3 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 93 + line: 3 + character: 15 + end_position: + bytes: 94 + line: 3 + character: 16 + token_type: + type: Symbol + symbol: "%" +- start_position: + bytes: 94 + line: 3 + character: 16 + end_position: + bytes: 95 + line: 3 + character: 17 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 95 + line: 3 + character: 17 + end_position: + bytes: 100 + line: 3 + character: 22 + token_type: + type: Identifier + identifier: every +- start_position: + bytes: 100 + line: 3 + character: 22 + end_position: + bytes: 101 + line: 3 + character: 23 + token_type: + type: Symbol + symbol: ) +- start_position: + bytes: 101 + line: 3 + character: 23 + end_position: + bytes: 102 + line: 3 + character: 24 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 102 + line: 3 + character: 24 + end_position: + bytes: 104 + line: 3 + character: 26 + token_type: + type: Symbol + symbol: "==" +- start_position: + bytes: 104 + line: 3 + character: 26 + end_position: + bytes: 105 + line: 3 + character: 27 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 105 + line: 3 + character: 27 + end_position: + bytes: 109 + line: 3 + character: 31 + token_type: + type: Identifier + identifier: disp +- start_position: + bytes: 109 + line: 3 + character: 31 + end_position: + bytes: 110 + line: 3 + character: 32 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 110 + line: 3 + character: 32 + end_position: + bytes: 114 + line: 3 + character: 36 + token_type: + type: Symbol + symbol: then +- start_position: + bytes: 114 + line: 3 + character: 36 + end_position: + bytes: 115 + line: 3 + character: 36 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 115 + line: 4 + character: 1 + end_position: + bytes: 127 + line: 4 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 127 + line: 4 + character: 13 + end_position: + bytes: 132 + line: 4 + character: 18 + token_type: + type: Symbol + symbol: yield +- start_position: + bytes: 132 + line: 4 + character: 18 + end_position: + bytes: 133 + line: 4 + character: 19 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 133 + line: 4 + character: 19 + end_position: + bytes: 134 + line: 4 + character: 20 + token_type: + type: Identifier + identifier: s +- start_position: + bytes: 134 + line: 4 + character: 20 + end_position: + bytes: 135 + line: 4 + character: 20 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 135 + line: 5 + character: 1 + end_position: + bytes: 143 + line: 5 + character: 9 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 143 + line: 5 + character: 9 + end_position: + bytes: 146 + line: 5 + character: 12 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 146 + line: 5 + character: 12 + end_position: + bytes: 147 + line: 5 + character: 12 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 147 + line: 6 + character: 1 + end_position: + bytes: 151 + line: 6 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 151 + line: 6 + character: 5 + end_position: + bytes: 154 + line: 6 + character: 8 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 154 + line: 6 + character: 8 + end_position: + bytes: 155 + line: 6 + character: 8 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 155 + line: 7 + character: 1 + end_position: + bytes: 158 + line: 7 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 158 + line: 7 + character: 4 + end_position: + bytes: 159 + line: 7 + character: 4 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 159 + line: 8 + character: 1 + end_position: + bytes: 159 + line: 8 + character: 1 + token_type: + type: Eof diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/main_busy/ast.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/main_busy/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..98250ff9289fd101a0c06565bbb3084e1ee85922 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/main_busy/ast.snap @@ -0,0 +1,1245 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: ast.nodes() +input_file: vvs_parser/tests/vivy_cases/pass/main_busy +--- +stmts: + - - Main: + main_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Symbol + symbol: main + trailing_trivia: + - start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " + initial_variable: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: StringLiteral + literal: init + quote_type: Double + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " + begin_token: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: "\n" + assignements: + - variable: + leading_trivia: + - start_position: + bytes: 15 + line: 2 + character: 1 + end_position: + bytes: 19 + line: 2 + character: 5 + token_type: + type: Whitespace + characters: " " + token: + start_position: + bytes: 19 + line: 2 + character: 5 + end_position: + bytes: 27 + line: 2 + character: 13 + token_type: + type: StringLiteral + literal: before + quote_type: Double + trailing_trivia: + - start_position: + bytes: 27 + line: 2 + character: 13 + end_position: + bytes: 30 + line: 2 + character: 16 + token_type: + type: Whitespace + characters: " " + assign_token: + leading_trivia: [] + token: + start_position: + bytes: 30 + line: 2 + character: 16 + end_position: + bytes: 31 + line: 2 + character: 17 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 31 + line: 2 + character: 17 + end_position: + bytes: 32 + line: 2 + character: 18 + token_type: + type: Whitespace + characters: " " + module_name: + leading_trivia: [] + token: + start_position: + bytes: 32 + line: 2 + character: 18 + end_position: + bytes: 38 + line: 2 + character: 24 + token_type: + type: Identifier + identifier: retime + trailing_trivia: [] + dot_token: + leading_trivia: [] + token: + start_position: + bytes: 38 + line: 2 + character: 24 + end_position: + bytes: 39 + line: 2 + character: 25 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + job_name: + leading_trivia: [] + token: + start_position: + bytes: 39 + line: 2 + character: 25 + end_position: + bytes: 44 + line: 2 + character: 30 + token_type: + type: Identifier + identifier: start + trailing_trivia: + - start_position: + bytes: 44 + line: 2 + character: 30 + end_position: + bytes: 47 + line: 2 + character: 33 + token_type: + type: Whitespace + characters: " " + call_list: + begin_token: + leading_trivia: [] + token: + start_position: + bytes: 47 + line: 2 + character: 33 + end_position: + bytes: 48 + line: 2 + character: 34 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 48 + line: 2 + character: 34 + end_position: + bytes: 49 + line: 2 + character: 35 + token_type: + type: Whitespace + characters: " " + items: + pairs: + - End: + Variable: + leading_trivia: [] + token: + start_position: + bytes: 49 + line: 2 + character: 35 + end_position: + bytes: 55 + line: 2 + character: 41 + token_type: + type: StringLiteral + literal: init + quote_type: Double + trailing_trivia: + - start_position: + bytes: 55 + line: 2 + character: 41 + end_position: + bytes: 56 + line: 2 + character: 42 + token_type: + type: Whitespace + characters: " " + end_token: + leading_trivia: [] + token: + start_position: + bytes: 56 + line: 2 + character: 42 + end_position: + bytes: 57 + line: 2 + character: 43 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: + - start_position: + bytes: 57 + line: 2 + character: 43 + end_position: + bytes: 58 + line: 2 + character: 43 + token_type: + type: Whitespace + characters: "\n" + - variable: + leading_trivia: + - start_position: + bytes: 58 + line: 3 + character: 1 + end_position: + bytes: 62 + line: 3 + character: 5 + token_type: + type: Whitespace + characters: " " + token: + start_position: + bytes: 62 + line: 3 + character: 5 + end_position: + bytes: 69 + line: 3 + character: 12 + token_type: + type: StringLiteral + literal: after + quote_type: Double + trailing_trivia: + - start_position: + bytes: 69 + line: 3 + character: 12 + end_position: + bytes: 73 + line: 3 + character: 16 + token_type: + type: Whitespace + characters: " " + assign_token: + leading_trivia: [] + token: + start_position: + bytes: 73 + line: 3 + character: 16 + end_position: + bytes: 74 + line: 3 + character: 17 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 74 + line: 3 + character: 17 + end_position: + bytes: 75 + line: 3 + character: 18 + token_type: + type: Whitespace + characters: " " + module_name: + leading_trivia: [] + token: + start_position: + bytes: 75 + line: 3 + character: 18 + end_position: + bytes: 81 + line: 3 + character: 24 + token_type: + type: Identifier + identifier: retime + trailing_trivia: [] + dot_token: + leading_trivia: [] + token: + start_position: + bytes: 81 + line: 3 + character: 24 + end_position: + bytes: 82 + line: 3 + character: 25 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + job_name: + leading_trivia: [] + token: + start_position: + bytes: 82 + line: 3 + character: 25 + end_position: + bytes: 88 + line: 3 + character: 31 + token_type: + type: Identifier + identifier: finish + trailing_trivia: + - start_position: + bytes: 88 + line: 3 + character: 31 + end_position: + bytes: 90 + line: 3 + character: 33 + token_type: + type: Whitespace + characters: " " + call_list: + begin_token: + leading_trivia: [] + token: + start_position: + bytes: 90 + line: 3 + character: 33 + end_position: + bytes: 91 + line: 3 + character: 34 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 91 + line: 3 + character: 34 + end_position: + bytes: 92 + line: 3 + character: 35 + token_type: + type: Whitespace + characters: " " + items: + pairs: + - End: + Variable: + leading_trivia: [] + token: + start_position: + bytes: 92 + line: 3 + character: 35 + end_position: + bytes: 98 + line: 3 + character: 41 + token_type: + type: StringLiteral + literal: init + quote_type: Double + trailing_trivia: + - start_position: + bytes: 98 + line: 3 + character: 41 + end_position: + bytes: 99 + line: 3 + character: 42 + token_type: + type: Whitespace + characters: " " + end_token: + leading_trivia: [] + token: + start_position: + bytes: 99 + line: 3 + character: 42 + end_position: + bytes: 100 + line: 3 + character: 43 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: + - start_position: + bytes: 100 + line: 3 + character: 43 + end_position: + bytes: 101 + line: 3 + character: 43 + token_type: + type: Whitespace + characters: "\n" + - variable: + leading_trivia: + - start_position: + bytes: 101 + line: 4 + character: 1 + end_position: + bytes: 105 + line: 4 + character: 5 + token_type: + type: Whitespace + characters: " " + token: + start_position: + bytes: 105 + line: 4 + character: 5 + end_position: + bytes: 115 + line: 4 + character: 15 + token_type: + type: StringLiteral + literal: outlined + quote_type: Double + trailing_trivia: + - start_position: + bytes: 115 + line: 4 + character: 15 + end_position: + bytes: 116 + line: 4 + character: 16 + token_type: + type: Whitespace + characters: " " + assign_token: + leading_trivia: [] + token: + start_position: + bytes: 116 + line: 4 + character: 16 + end_position: + bytes: 117 + line: 4 + character: 17 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 117 + line: 4 + character: 17 + end_position: + bytes: 118 + line: 4 + character: 18 + token_type: + type: Whitespace + characters: " " + module_name: + leading_trivia: [] + token: + start_position: + bytes: 118 + line: 4 + character: 18 + end_position: + bytes: 123 + line: 4 + character: 23 + token_type: + type: Identifier + identifier: utils + trailing_trivia: [] + dot_token: + leading_trivia: [] + token: + start_position: + bytes: 123 + line: 4 + character: 23 + end_position: + bytes: 124 + line: 4 + character: 24 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + job_name: + leading_trivia: [] + token: + start_position: + bytes: 124 + line: 4 + character: 24 + end_position: + bytes: 131 + line: 4 + character: 31 + token_type: + type: Identifier + identifier: outline + trailing_trivia: + - start_position: + bytes: 131 + line: 4 + character: 31 + end_position: + bytes: 133 + line: 4 + character: 33 + token_type: + type: Whitespace + characters: " " + call_list: + begin_token: + leading_trivia: [] + token: + start_position: + bytes: 133 + line: 4 + character: 33 + end_position: + bytes: 134 + line: 4 + character: 34 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 134 + line: 4 + character: 34 + end_position: + bytes: 135 + line: 4 + character: 35 + token_type: + type: Whitespace + characters: " " + items: + pairs: + - Punctuated: + - Variable: + leading_trivia: [] + token: + start_position: + bytes: 135 + line: 4 + character: 35 + end_position: + bytes: 143 + line: 4 + character: 43 + token_type: + type: StringLiteral + literal: before + quote_type: Double + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 143 + line: 4 + character: 43 + end_position: + bytes: 144 + line: 4 + character: 44 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 144 + line: 4 + character: 44 + end_position: + bytes: 145 + line: 4 + character: 45 + token_type: + type: Whitespace + characters: " " + - Punctuated: + - Variable: + leading_trivia: [] + token: + start_position: + bytes: 145 + line: 4 + character: 45 + end_position: + bytes: 151 + line: 4 + character: 51 + token_type: + type: StringLiteral + literal: init + quote_type: Double + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 151 + line: 4 + character: 51 + end_position: + bytes: 152 + line: 4 + character: 52 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 152 + line: 4 + character: 52 + end_position: + bytes: 153 + line: 4 + character: 53 + token_type: + type: Whitespace + characters: " " + - End: + Variable: + leading_trivia: [] + token: + start_position: + bytes: 153 + line: 4 + character: 53 + end_position: + bytes: 160 + line: 4 + character: 60 + token_type: + type: StringLiteral + literal: after + quote_type: Double + trailing_trivia: + - start_position: + bytes: 160 + line: 4 + character: 60 + end_position: + bytes: 161 + line: 4 + character: 61 + token_type: + type: Whitespace + characters: " " + end_token: + leading_trivia: [] + token: + start_position: + bytes: 161 + line: 4 + character: 61 + end_position: + bytes: 162 + line: 4 + character: 62 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: + - start_position: + bytes: 162 + line: 4 + character: 62 + end_position: + bytes: 163 + line: 4 + character: 62 + token_type: + type: Whitespace + characters: "\n" + - variable: + leading_trivia: + - start_position: + bytes: 163 + line: 5 + character: 1 + end_position: + bytes: 164 + line: 5 + character: 1 + token_type: + type: Whitespace + characters: "\n" + - start_position: + bytes: 164 + line: 6 + character: 1 + end_position: + bytes: 168 + line: 6 + character: 5 + token_type: + type: Whitespace + characters: " " + - start_position: + bytes: 168 + line: 6 + character: 5 + end_position: + bytes: 198 + line: 6 + character: 35 + token_type: + type: SingleLineComment + comment: " Here we tag some objects..." + - start_position: + bytes: 198 + line: 6 + character: 35 + end_position: + bytes: 199 + line: 6 + character: 35 + token_type: + type: Whitespace + characters: "\n" + - start_position: + bytes: 199 + line: 7 + character: 1 + end_position: + bytes: 203 + line: 7 + character: 5 + token_type: + type: Whitespace + characters: " " + token: + start_position: + bytes: 203 + line: 7 + character: 5 + end_position: + bytes: 211 + line: 7 + character: 13 + token_type: + type: StringLiteral + literal: tagged + quote_type: Double + trailing_trivia: + - start_position: + bytes: 211 + line: 7 + character: 13 + end_position: + bytes: 214 + line: 7 + character: 16 + token_type: + type: Whitespace + characters: " " + assign_token: + leading_trivia: [] + token: + start_position: + bytes: 214 + line: 7 + character: 16 + end_position: + bytes: 215 + line: 7 + character: 17 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 215 + line: 7 + character: 17 + end_position: + bytes: 216 + line: 7 + character: 18 + token_type: + type: Whitespace + characters: " " + module_name: + leading_trivia: [] + token: + start_position: + bytes: 216 + line: 7 + character: 18 + end_position: + bytes: 219 + line: 7 + character: 21 + token_type: + type: Identifier + identifier: tag + trailing_trivia: [] + dot_token: + leading_trivia: [] + token: + start_position: + bytes: 219 + line: 7 + character: 21 + end_position: + bytes: 220 + line: 7 + character: 22 + token_type: + type: Symbol + symbol: "." + trailing_trivia: [] + job_name: + leading_trivia: [] + token: + start_position: + bytes: 220 + line: 7 + character: 22 + end_position: + bytes: 230 + line: 7 + character: 32 + token_type: + type: Identifier + identifier: syl_modulo + trailing_trivia: + - start_position: + bytes: 230 + line: 7 + character: 32 + end_position: + bytes: 231 + line: 7 + character: 33 + token_type: + type: Whitespace + characters: " " + call_list: + begin_token: + leading_trivia: [] + token: + start_position: + bytes: 231 + line: 7 + character: 33 + end_position: + bytes: 232 + line: 7 + character: 34 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 232 + line: 7 + character: 34 + end_position: + bytes: 233 + line: 7 + character: 35 + token_type: + type: Whitespace + characters: " " + items: + pairs: + - Punctuated: + - SetParameter: + parameter: + leading_trivia: [] + token: + start_position: + bytes: 233 + line: 7 + character: 35 + end_position: + bytes: 238 + line: 7 + character: 40 + token_type: + type: Identifier + identifier: every + trailing_trivia: + - start_position: + bytes: 238 + line: 7 + character: 40 + end_position: + bytes: 239 + line: 7 + character: 41 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 239 + line: 7 + character: 41 + end_position: + bytes: 240 + line: 7 + character: 42 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 240 + line: 7 + character: 42 + end_position: + bytes: 241 + line: 7 + character: 43 + token_type: + type: Whitespace + characters: " " + expression: + Number: + leading_trivia: [] + token: + start_position: + bytes: 241 + line: 7 + character: 43 + end_position: + bytes: 242 + line: 7 + character: 44 + token_type: + type: Number + text: "3" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 242 + line: 7 + character: 44 + end_position: + bytes: 243 + line: 7 + character: 45 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 243 + line: 7 + character: 45 + end_position: + bytes: 244 + line: 7 + character: 46 + token_type: + type: Whitespace + characters: " " + - Punctuated: + - SetParameter: + parameter: + leading_trivia: [] + token: + start_position: + bytes: 244 + line: 7 + character: 46 + end_position: + bytes: 248 + line: 7 + character: 50 + token_type: + type: Identifier + identifier: disp + trailing_trivia: + - start_position: + bytes: 248 + line: 7 + character: 50 + end_position: + bytes: 249 + line: 7 + character: 51 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 249 + line: 7 + character: 51 + end_position: + bytes: 250 + line: 7 + character: 52 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 250 + line: 7 + character: 52 + end_position: + bytes: 251 + line: 7 + character: 53 + token_type: + type: Whitespace + characters: " " + expression: + Number: + leading_trivia: [] + token: + start_position: + bytes: 251 + line: 7 + character: 53 + end_position: + bytes: 252 + line: 7 + character: 54 + token_type: + type: Number + text: "1" + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 252 + line: 7 + character: 54 + end_position: + bytes: 253 + line: 7 + character: 55 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 253 + line: 7 + character: 55 + end_position: + bytes: 254 + line: 7 + character: 56 + token_type: + type: Whitespace + characters: " " + - End: + Variable: + leading_trivia: [] + token: + start_position: + bytes: 254 + line: 7 + character: 56 + end_position: + bytes: 264 + line: 7 + character: 66 + token_type: + type: StringLiteral + literal: outlined + quote_type: Double + trailing_trivia: + - start_position: + bytes: 264 + line: 7 + character: 66 + end_position: + bytes: 265 + line: 7 + character: 67 + token_type: + type: Whitespace + characters: " " + end_token: + leading_trivia: [] + token: + start_position: + bytes: 265 + line: 7 + character: 67 + end_position: + bytes: 266 + line: 7 + character: 68 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: + - start_position: + bytes: 266 + line: 7 + character: 68 + end_position: + bytes: 267 + line: 7 + character: 68 + token_type: + type: Whitespace + characters: "\n" + write_stmt: ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 267 + line: 8 + character: 1 + end_position: + bytes: 270 + line: 8 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 270 + line: 8 + character: 4 + end_position: + bytes: 271 + line: 8 + character: 4 + token_type: + type: Whitespace + characters: "\n" + - ~ diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/main_busy/source.lua b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/main_busy/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..94cd169d5946cd586c2944b58cb649ef5cc557ae --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/main_busy/source.lua @@ -0,0 +1,8 @@ +main "init" do + "before" = retime.start { "init" } + "after" = retime.finish { "init" } + "outlined" = utils.outline { "before", "init", "after" } + + -- Here we tag some objects... + "tagged" = tag.syl_modulo { every = 3, disp = 1, "outlined" } +end diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/main_busy/tokens.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/main_busy/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..032339db837420f327bf32b56b70410d63a1015d --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/main_busy/tokens.snap @@ -0,0 +1,1038 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: tokens +input_file: vvs_parser/tests/vivy_cases/pass/main_busy +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Symbol + symbol: main +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: StringLiteral + literal: init + quote_type: Double +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 15 + line: 2 + character: 1 + end_position: + bytes: 19 + line: 2 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 19 + line: 2 + character: 5 + end_position: + bytes: 27 + line: 2 + character: 13 + token_type: + type: StringLiteral + literal: before + quote_type: Double +- start_position: + bytes: 27 + line: 2 + character: 13 + end_position: + bytes: 30 + line: 2 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 30 + line: 2 + character: 16 + end_position: + bytes: 31 + line: 2 + character: 17 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 31 + line: 2 + character: 17 + end_position: + bytes: 32 + line: 2 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 32 + line: 2 + character: 18 + end_position: + bytes: 38 + line: 2 + character: 24 + token_type: + type: Identifier + identifier: retime +- start_position: + bytes: 38 + line: 2 + character: 24 + end_position: + bytes: 39 + line: 2 + character: 25 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 39 + line: 2 + character: 25 + end_position: + bytes: 44 + line: 2 + character: 30 + token_type: + type: Identifier + identifier: start +- start_position: + bytes: 44 + line: 2 + character: 30 + end_position: + bytes: 47 + line: 2 + character: 33 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 47 + line: 2 + character: 33 + end_position: + bytes: 48 + line: 2 + character: 34 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 48 + line: 2 + character: 34 + end_position: + bytes: 49 + line: 2 + character: 35 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 49 + line: 2 + character: 35 + end_position: + bytes: 55 + line: 2 + character: 41 + token_type: + type: StringLiteral + literal: init + quote_type: Double +- start_position: + bytes: 55 + line: 2 + character: 41 + end_position: + bytes: 56 + line: 2 + character: 42 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 56 + line: 2 + character: 42 + end_position: + bytes: 57 + line: 2 + character: 43 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 57 + line: 2 + character: 43 + end_position: + bytes: 58 + line: 2 + character: 43 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 58 + line: 3 + character: 1 + end_position: + bytes: 62 + line: 3 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 62 + line: 3 + character: 5 + end_position: + bytes: 69 + line: 3 + character: 12 + token_type: + type: StringLiteral + literal: after + quote_type: Double +- start_position: + bytes: 69 + line: 3 + character: 12 + end_position: + bytes: 73 + line: 3 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 73 + line: 3 + character: 16 + end_position: + bytes: 74 + line: 3 + character: 17 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 74 + line: 3 + character: 17 + end_position: + bytes: 75 + line: 3 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 75 + line: 3 + character: 18 + end_position: + bytes: 81 + line: 3 + character: 24 + token_type: + type: Identifier + identifier: retime +- start_position: + bytes: 81 + line: 3 + character: 24 + end_position: + bytes: 82 + line: 3 + character: 25 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 82 + line: 3 + character: 25 + end_position: + bytes: 88 + line: 3 + character: 31 + token_type: + type: Identifier + identifier: finish +- start_position: + bytes: 88 + line: 3 + character: 31 + end_position: + bytes: 90 + line: 3 + character: 33 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 90 + line: 3 + character: 33 + end_position: + bytes: 91 + line: 3 + character: 34 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 91 + line: 3 + character: 34 + end_position: + bytes: 92 + line: 3 + character: 35 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 92 + line: 3 + character: 35 + end_position: + bytes: 98 + line: 3 + character: 41 + token_type: + type: StringLiteral + literal: init + quote_type: Double +- start_position: + bytes: 98 + line: 3 + character: 41 + end_position: + bytes: 99 + line: 3 + character: 42 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 99 + line: 3 + character: 42 + end_position: + bytes: 100 + line: 3 + character: 43 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 100 + line: 3 + character: 43 + end_position: + bytes: 101 + line: 3 + character: 43 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 101 + line: 4 + character: 1 + end_position: + bytes: 105 + line: 4 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 105 + line: 4 + character: 5 + end_position: + bytes: 115 + line: 4 + character: 15 + token_type: + type: StringLiteral + literal: outlined + quote_type: Double +- start_position: + bytes: 115 + line: 4 + character: 15 + end_position: + bytes: 116 + line: 4 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 116 + line: 4 + character: 16 + end_position: + bytes: 117 + line: 4 + character: 17 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 117 + line: 4 + character: 17 + end_position: + bytes: 118 + line: 4 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 118 + line: 4 + character: 18 + end_position: + bytes: 123 + line: 4 + character: 23 + token_type: + type: Identifier + identifier: utils +- start_position: + bytes: 123 + line: 4 + character: 23 + end_position: + bytes: 124 + line: 4 + character: 24 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 124 + line: 4 + character: 24 + end_position: + bytes: 131 + line: 4 + character: 31 + token_type: + type: Identifier + identifier: outline +- start_position: + bytes: 131 + line: 4 + character: 31 + end_position: + bytes: 133 + line: 4 + character: 33 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 133 + line: 4 + character: 33 + end_position: + bytes: 134 + line: 4 + character: 34 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 134 + line: 4 + character: 34 + end_position: + bytes: 135 + line: 4 + character: 35 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 135 + line: 4 + character: 35 + end_position: + bytes: 143 + line: 4 + character: 43 + token_type: + type: StringLiteral + literal: before + quote_type: Double +- start_position: + bytes: 143 + line: 4 + character: 43 + end_position: + bytes: 144 + line: 4 + character: 44 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 144 + line: 4 + character: 44 + end_position: + bytes: 145 + line: 4 + character: 45 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 145 + line: 4 + character: 45 + end_position: + bytes: 151 + line: 4 + character: 51 + token_type: + type: StringLiteral + literal: init + quote_type: Double +- start_position: + bytes: 151 + line: 4 + character: 51 + end_position: + bytes: 152 + line: 4 + character: 52 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 152 + line: 4 + character: 52 + end_position: + bytes: 153 + line: 4 + character: 53 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 153 + line: 4 + character: 53 + end_position: + bytes: 160 + line: 4 + character: 60 + token_type: + type: StringLiteral + literal: after + quote_type: Double +- start_position: + bytes: 160 + line: 4 + character: 60 + end_position: + bytes: 161 + line: 4 + character: 61 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 161 + line: 4 + character: 61 + end_position: + bytes: 162 + line: 4 + character: 62 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 162 + line: 4 + character: 62 + end_position: + bytes: 163 + line: 4 + character: 62 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 163 + line: 5 + character: 1 + end_position: + bytes: 164 + line: 5 + character: 1 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 164 + line: 6 + character: 1 + end_position: + bytes: 168 + line: 6 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 168 + line: 6 + character: 5 + end_position: + bytes: 198 + line: 6 + character: 35 + token_type: + type: SingleLineComment + comment: " Here we tag some objects..." +- start_position: + bytes: 198 + line: 6 + character: 35 + end_position: + bytes: 199 + line: 6 + character: 35 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 199 + line: 7 + character: 1 + end_position: + bytes: 203 + line: 7 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 203 + line: 7 + character: 5 + end_position: + bytes: 211 + line: 7 + character: 13 + token_type: + type: StringLiteral + literal: tagged + quote_type: Double +- start_position: + bytes: 211 + line: 7 + character: 13 + end_position: + bytes: 214 + line: 7 + character: 16 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 214 + line: 7 + character: 16 + end_position: + bytes: 215 + line: 7 + character: 17 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 215 + line: 7 + character: 17 + end_position: + bytes: 216 + line: 7 + character: 18 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 216 + line: 7 + character: 18 + end_position: + bytes: 219 + line: 7 + character: 21 + token_type: + type: Identifier + identifier: tag +- start_position: + bytes: 219 + line: 7 + character: 21 + end_position: + bytes: 220 + line: 7 + character: 22 + token_type: + type: Symbol + symbol: "." +- start_position: + bytes: 220 + line: 7 + character: 22 + end_position: + bytes: 230 + line: 7 + character: 32 + token_type: + type: Identifier + identifier: syl_modulo +- start_position: + bytes: 230 + line: 7 + character: 32 + end_position: + bytes: 231 + line: 7 + character: 33 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 231 + line: 7 + character: 33 + end_position: + bytes: 232 + line: 7 + character: 34 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 232 + line: 7 + character: 34 + end_position: + bytes: 233 + line: 7 + character: 35 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 233 + line: 7 + character: 35 + end_position: + bytes: 238 + line: 7 + character: 40 + token_type: + type: Identifier + identifier: every +- start_position: + bytes: 238 + line: 7 + character: 40 + end_position: + bytes: 239 + line: 7 + character: 41 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 239 + line: 7 + character: 41 + end_position: + bytes: 240 + line: 7 + character: 42 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 240 + line: 7 + character: 42 + end_position: + bytes: 241 + line: 7 + character: 43 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 241 + line: 7 + character: 43 + end_position: + bytes: 242 + line: 7 + character: 44 + token_type: + type: Number + text: "3" +- start_position: + bytes: 242 + line: 7 + character: 44 + end_position: + bytes: 243 + line: 7 + character: 45 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 243 + line: 7 + character: 45 + end_position: + bytes: 244 + line: 7 + character: 46 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 244 + line: 7 + character: 46 + end_position: + bytes: 248 + line: 7 + character: 50 + token_type: + type: Identifier + identifier: disp +- start_position: + bytes: 248 + line: 7 + character: 50 + end_position: + bytes: 249 + line: 7 + character: 51 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 249 + line: 7 + character: 51 + end_position: + bytes: 250 + line: 7 + character: 52 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 250 + line: 7 + character: 52 + end_position: + bytes: 251 + line: 7 + character: 53 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 251 + line: 7 + character: 53 + end_position: + bytes: 252 + line: 7 + character: 54 + token_type: + type: Number + text: "1" +- start_position: + bytes: 252 + line: 7 + character: 54 + end_position: + bytes: 253 + line: 7 + character: 55 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 253 + line: 7 + character: 55 + end_position: + bytes: 254 + line: 7 + character: 56 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 254 + line: 7 + character: 56 + end_position: + bytes: 264 + line: 7 + character: 66 + token_type: + type: StringLiteral + literal: outlined + quote_type: Double +- start_position: + bytes: 264 + line: 7 + character: 66 + end_position: + bytes: 265 + line: 7 + character: 67 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 265 + line: 7 + character: 67 + end_position: + bytes: 266 + line: 7 + character: 68 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 266 + line: 7 + character: 68 + end_position: + bytes: 267 + line: 7 + character: 68 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 267 + line: 8 + character: 1 + end_position: + bytes: 270 + line: 8 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 270 + line: 8 + character: 4 + end_position: + bytes: 271 + line: 8 + character: 4 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 271 + line: 9 + character: 1 + end_position: + bytes: 271 + line: 9 + character: 1 + token_type: + type: Eof diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/main_empty/ast.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/main_empty/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..8ad1f4c89d67f12c1b3e0ceef57a2683b3893008 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/main_empty/ast.snap @@ -0,0 +1,115 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: ast.nodes() +input_file: vvs_parser/tests/vivy_cases/pass/main_empty +--- +stmts: + - - Main: + main_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Symbol + symbol: main + trailing_trivia: + - start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " + initial_variable: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: StringLiteral + literal: init + quote_type: Double + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " + begin_token: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: "\n" + assignements: [] + write_stmt: ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 15 + line: 2 + character: 1 + end_position: + bytes: 18 + line: 2 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 18 + line: 2 + character: 4 + end_position: + bytes: 19 + line: 2 + character: 4 + token_type: + type: Whitespace + characters: "\n" + - ~ diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/main_empty/source.lua b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/main_empty/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..8701206cab7f8eaf66a4c3b1d687c8a72804adf4 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/main_empty/source.lua @@ -0,0 +1,2 @@ +main "init" do +end diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/main_empty/tokens.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/main_empty/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..e5d60f280a2c9818ddb001cd43d177e5dfa66c69 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/main_empty/tokens.snap @@ -0,0 +1,104 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: tokens +input_file: vvs_parser/tests/vivy_cases/pass/main_empty +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Symbol + symbol: main +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: StringLiteral + literal: init + quote_type: Double +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 15 + line: 2 + character: 1 + end_position: + bytes: 18 + line: 2 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 18 + line: 2 + character: 4 + end_position: + bytes: 19 + line: 2 + character: 4 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 19 + line: 3 + character: 1 + end_position: + bytes: 19 + line: 3 + character: 1 + token_type: + type: Eof diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/main_returns/ast.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/main_returns/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..064c435c28c88b3d5dca3c51a08328fe02b2f556 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/main_returns/ast.snap @@ -0,0 +1,183 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: ast.nodes() +input_file: vvs_parser/tests/vivy_cases/pass/main_returns +--- +stmts: + - - Main: + main_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Symbol + symbol: main + trailing_trivia: + - start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " + initial_variable: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: StringLiteral + literal: init + quote_type: Double + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " + begin_token: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: "\n" + assignements: [] + write_stmt: + write_token: + leading_trivia: + - start_position: + bytes: 15 + line: 2 + character: 1 + end_position: + bytes: 19 + line: 2 + character: 5 + token_type: + type: Whitespace + characters: " " + token: + start_position: + bytes: 19 + line: 2 + character: 5 + end_position: + bytes: 25 + line: 2 + character: 11 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 25 + line: 2 + character: 11 + end_position: + bytes: 26 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: " " + begin_token: ~ + variable_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 26 + line: 2 + character: 12 + end_position: + bytes: 32 + line: 2 + character: 18 + token_type: + type: StringLiteral + literal: init + quote_type: Double + trailing_trivia: + - start_position: + bytes: 32 + line: 2 + character: 18 + end_position: + bytes: 33 + line: 2 + character: 18 + token_type: + type: Whitespace + characters: "\n" + end_token: ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 33 + line: 3 + character: 1 + end_position: + bytes: 36 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 36 + line: 3 + character: 4 + end_position: + bytes: 37 + line: 3 + character: 4 + token_type: + type: Whitespace + characters: "\n" + - ~ diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/main_returns/source.lua b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/main_returns/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..75ac778dd702e2b7d2aac070a439e3a65a46bae6 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/main_returns/source.lua @@ -0,0 +1,3 @@ +main "init" do + return "init" +end diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/main_returns/tokens.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/main_returns/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..57984b669a7786ec7cfd7a7d08f17bf48672d3da --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/main_returns/tokens.snap @@ -0,0 +1,160 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: tokens +input_file: vvs_parser/tests/vivy_cases/pass/main_returns +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Symbol + symbol: main +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: StringLiteral + literal: init + quote_type: Double +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 15 + line: 2 + character: 1 + end_position: + bytes: 19 + line: 2 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 19 + line: 2 + character: 5 + end_position: + bytes: 25 + line: 2 + character: 11 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 25 + line: 2 + character: 11 + end_position: + bytes: 26 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 26 + line: 2 + character: 12 + end_position: + bytes: 32 + line: 2 + character: 18 + token_type: + type: StringLiteral + literal: init + quote_type: Double +- start_position: + bytes: 32 + line: 2 + character: 18 + end_position: + bytes: 33 + line: 2 + character: 18 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 33 + line: 3 + character: 1 + end_position: + bytes: 36 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 36 + line: 3 + character: 4 + end_position: + bytes: 37 + line: 3 + character: 4 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 37 + line: 4 + character: 1 + end_position: + bytes: 37 + line: 4 + character: 1 + token_type: + type: Eof diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/option_decl_1/ast.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/option_decl_1/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..885a4e5595ae516eee89700515d3dc1f46a696cf --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/option_decl_1/ast.snap @@ -0,0 +1,160 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: ast.nodes() +input_file: vvs_parser/tests/vivy_cases/pass/option_decl_1 +--- +stmts: + - - OptionDecl: + option_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: option + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Identifier + identifier: titi + trailing_trivia: [] + type_specifiers: + - punctuation: + leading_trivia: [] + token: + start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: ":" + trailing_trivia: + - start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Whitespace + characters: " " + type_info: + Basic: + leading_trivia: [] + token: + start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Identifier + identifier: number + trailing_trivia: + - start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 22 + line: 1 + character: 23 + end_position: + bytes: 23 + line: 1 + character: 24 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 23 + line: 1 + character: 24 + end_position: + bytes: 24 + line: 1 + character: 24 + token_type: + type: Whitespace + characters: "\n" + - ~ diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/option_decl_1/source.lua b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/option_decl_1/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..1da84c8f702ec3c541621fc47eafde25625a88ff --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/option_decl_1/source.lua @@ -0,0 +1 @@ +option titi: number = 1 diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/option_decl_1/tokens.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/option_decl_1/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..5831befa3b1fa0307ad8b2db87d785e7405b0ff4 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/option_decl_1/tokens.snap @@ -0,0 +1,136 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: tokens +input_file: vvs_parser/tests/vivy_cases/pass/option_decl_1 +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: option +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Identifier + identifier: titi +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Symbol + symbol: ":" +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 19 + line: 1 + character: 20 + token_type: + type: Identifier + identifier: number +- start_position: + bytes: 19 + line: 1 + character: 20 + end_position: + bytes: 20 + line: 1 + character: 21 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 20 + line: 1 + character: 21 + end_position: + bytes: 21 + line: 1 + character: 22 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 21 + line: 1 + character: 22 + end_position: + bytes: 22 + line: 1 + character: 23 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 22 + line: 1 + character: 23 + end_position: + bytes: 23 + line: 1 + character: 24 + token_type: + type: Number + text: "1" +- start_position: + bytes: 23 + line: 1 + character: 24 + end_position: + bytes: 24 + line: 1 + character: 24 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 24 + line: 2 + character: 1 + end_position: + bytes: 24 + line: 2 + character: 1 + token_type: + type: Eof diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/option_decl_2/ast.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/option_decl_2/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..a985e625bee6e253654f260e59183f3351bfa76b --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/option_decl_2/ast.snap @@ -0,0 +1,117 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: ast.nodes() +input_file: vvs_parser/tests/vivy_cases/pass/option_decl_3 +--- +stmts: + - - OptionDecl: + option_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: option + trailing_trivia: + - start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " + name_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Identifier + identifier: titi + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " + equal_token: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: "=" + trailing_trivia: + - start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: " " + expr_list: + pairs: + - End: + Number: + leading_trivia: [] + token: + start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Number + text: "1" + trailing_trivia: + - start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: "\n" + - ~ diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/option_decl_2/source.lua b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/option_decl_2/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..8264a0bccec332f6abe130fe246909e38960ac91 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/option_decl_2/source.lua @@ -0,0 +1 @@ +option titi = 1 diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/option_decl_2/tokens.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/option_decl_2/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..507c559d8cb830158d475c1c833deaba5878d4ae --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/option_decl_2/tokens.snap @@ -0,0 +1,103 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: tokens +input_file: vvs_parser/tests/vivy_cases/pass/option_decl_3 +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 6 + line: 1 + character: 7 + token_type: + type: Symbol + symbol: option +- start_position: + bytes: 6 + line: 1 + character: 7 + end_position: + bytes: 7 + line: 1 + character: 8 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 7 + line: 1 + character: 8 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: Identifier + identifier: titi +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 13 + line: 1 + character: 14 + token_type: + type: Symbol + symbol: "=" +- start_position: + bytes: 13 + line: 1 + character: 14 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 16 + token_type: + type: Number + text: "1" +- start_position: + bytes: 15 + line: 1 + character: 16 + end_position: + bytes: 16 + line: 1 + character: 16 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 16 + line: 2 + character: 1 + end_position: + bytes: 16 + line: 2 + character: 1 + token_type: + type: Eof diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/write_multiple/ast.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/write_multiple/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..3ba9b7eab615d3e781c29f943ae76a81d7acd44c --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/write_multiple/ast.snap @@ -0,0 +1,274 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: ast.nodes() +input_file: vvs_parser/tests/vivy_cases/pass/write_multiple +--- +stmts: + - - Main: + main_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Symbol + symbol: main + trailing_trivia: + - start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " + initial_variable: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: StringLiteral + literal: init + quote_type: Double + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " + begin_token: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: "\n" + assignements: [] + write_stmt: + write_token: + leading_trivia: + - start_position: + bytes: 15 + line: 2 + character: 1 + end_position: + bytes: 19 + line: 2 + character: 5 + token_type: + type: Whitespace + characters: " " + token: + start_position: + bytes: 19 + line: 2 + character: 5 + end_position: + bytes: 25 + line: 2 + character: 11 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 25 + line: 2 + character: 11 + end_position: + bytes: 26 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: " " + begin_token: + leading_trivia: [] + token: + start_position: + bytes: 26 + line: 2 + character: 12 + end_position: + bytes: 27 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: "{" + trailing_trivia: + - start_position: + bytes: 27 + line: 2 + character: 13 + end_position: + bytes: 28 + line: 2 + character: 14 + token_type: + type: Whitespace + characters: " " + variable_list: + pairs: + - Punctuated: + - leading_trivia: [] + token: + start_position: + bytes: 28 + line: 2 + character: 14 + end_position: + bytes: 34 + line: 2 + character: 20 + token_type: + type: StringLiteral + literal: init + quote_type: Double + trailing_trivia: [] + - leading_trivia: [] + token: + start_position: + bytes: 34 + line: 2 + character: 20 + end_position: + bytes: 35 + line: 2 + character: 21 + token_type: + type: Symbol + symbol: "," + trailing_trivia: + - start_position: + bytes: 35 + line: 2 + character: 21 + end_position: + bytes: 36 + line: 2 + character: 22 + token_type: + type: Whitespace + characters: " " + - End: + leading_trivia: [] + token: + start_position: + bytes: 36 + line: 2 + character: 22 + end_position: + bytes: 42 + line: 2 + character: 28 + token_type: + type: StringLiteral + literal: last + quote_type: Double + trailing_trivia: + - start_position: + bytes: 42 + line: 2 + character: 28 + end_position: + bytes: 43 + line: 2 + character: 29 + token_type: + type: Whitespace + characters: " " + end_token: + leading_trivia: [] + token: + start_position: + bytes: 43 + line: 2 + character: 29 + end_position: + bytes: 44 + line: 2 + character: 30 + token_type: + type: Symbol + symbol: "}" + trailing_trivia: + - start_position: + bytes: 44 + line: 2 + character: 30 + end_position: + bytes: 45 + line: 2 + character: 30 + token_type: + type: Whitespace + characters: "\n" + end_token: + leading_trivia: [] + token: + start_position: + bytes: 45 + line: 3 + character: 1 + end_position: + bytes: 48 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 48 + line: 3 + character: 4 + end_position: + bytes: 49 + line: 3 + character: 4 + token_type: + type: Whitespace + characters: "\n" + - ~ diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/write_multiple/source.lua b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/write_multiple/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..2cd2ac93373df91e63550a24d619ab76eaf3e6f0 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/write_multiple/source.lua @@ -0,0 +1,3 @@ +main "init" do + return { "init", "last" } +end diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/write_multiple/tokens.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/write_multiple/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..311abb0a31ad681739a318750808f662ff3b2c58 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/write_multiple/tokens.snap @@ -0,0 +1,238 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: tokens +input_file: vvs_parser/tests/vivy_cases/pass/write_multiple +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Symbol + symbol: main +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: StringLiteral + literal: init + quote_type: Double +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 15 + line: 2 + character: 1 + end_position: + bytes: 19 + line: 2 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 19 + line: 2 + character: 5 + end_position: + bytes: 25 + line: 2 + character: 11 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 25 + line: 2 + character: 11 + end_position: + bytes: 26 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 26 + line: 2 + character: 12 + end_position: + bytes: 27 + line: 2 + character: 13 + token_type: + type: Symbol + symbol: "{" +- start_position: + bytes: 27 + line: 2 + character: 13 + end_position: + bytes: 28 + line: 2 + character: 14 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 28 + line: 2 + character: 14 + end_position: + bytes: 34 + line: 2 + character: 20 + token_type: + type: StringLiteral + literal: init + quote_type: Double +- start_position: + bytes: 34 + line: 2 + character: 20 + end_position: + bytes: 35 + line: 2 + character: 21 + token_type: + type: Symbol + symbol: "," +- start_position: + bytes: 35 + line: 2 + character: 21 + end_position: + bytes: 36 + line: 2 + character: 22 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 36 + line: 2 + character: 22 + end_position: + bytes: 42 + line: 2 + character: 28 + token_type: + type: StringLiteral + literal: last + quote_type: Double +- start_position: + bytes: 42 + line: 2 + character: 28 + end_position: + bytes: 43 + line: 2 + character: 29 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 43 + line: 2 + character: 29 + end_position: + bytes: 44 + line: 2 + character: 30 + token_type: + type: Symbol + symbol: "}" +- start_position: + bytes: 44 + line: 2 + character: 30 + end_position: + bytes: 45 + line: 2 + character: 30 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 45 + line: 3 + character: 1 + end_position: + bytes: 48 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 48 + line: 3 + character: 4 + end_position: + bytes: 49 + line: 3 + character: 4 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 49 + line: 4 + character: 1 + end_position: + bytes: 49 + line: 4 + character: 1 + token_type: + type: Eof diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/write_single/ast.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/write_single/ast.snap new file mode 100644 index 0000000000000000000000000000000000000000..4fb5aafd97fa8ab6c7c8825260c40cfc0abcf467 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/write_single/ast.snap @@ -0,0 +1,183 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: ast.nodes() +input_file: vvs_parser/tests/vivy_cases/pass/write_single +--- +stmts: + - - Main: + main_token: + leading_trivia: [] + token: + start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Symbol + symbol: main + trailing_trivia: + - start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " + initial_variable: + leading_trivia: [] + token: + start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: StringLiteral + literal: init + quote_type: Double + trailing_trivia: + - start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " + begin_token: + leading_trivia: [] + token: + start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: do + trailing_trivia: + - start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: "\n" + assignements: [] + write_stmt: + write_token: + leading_trivia: + - start_position: + bytes: 15 + line: 2 + character: 1 + end_position: + bytes: 19 + line: 2 + character: 5 + token_type: + type: Whitespace + characters: " " + token: + start_position: + bytes: 19 + line: 2 + character: 5 + end_position: + bytes: 25 + line: 2 + character: 11 + token_type: + type: Symbol + symbol: return + trailing_trivia: + - start_position: + bytes: 25 + line: 2 + character: 11 + end_position: + bytes: 26 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: " " + begin_token: ~ + variable_list: + pairs: + - End: + leading_trivia: [] + token: + start_position: + bytes: 26 + line: 2 + character: 12 + end_position: + bytes: 32 + line: 2 + character: 18 + token_type: + type: StringLiteral + literal: init + quote_type: Double + trailing_trivia: + - start_position: + bytes: 32 + line: 2 + character: 18 + end_position: + bytes: 33 + line: 2 + character: 18 + token_type: + type: Whitespace + characters: "\n" + end_token: ~ + end_token: + leading_trivia: [] + token: + start_position: + bytes: 33 + line: 3 + character: 1 + end_position: + bytes: 36 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end + trailing_trivia: + - start_position: + bytes: 36 + line: 3 + character: 4 + end_position: + bytes: 37 + line: 3 + character: 4 + token_type: + type: Whitespace + characters: "\n" + - ~ diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/write_single/source.lua b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/write_single/source.lua new file mode 100644 index 0000000000000000000000000000000000000000..75ac778dd702e2b7d2aac070a439e3a65a46bae6 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/write_single/source.lua @@ -0,0 +1,3 @@ +main "init" do + return "init" +end diff --git a/src/Rust/vvs_parser/src/tests/vivy_cases/pass/write_single/tokens.snap b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/write_single/tokens.snap new file mode 100644 index 0000000000000000000000000000000000000000..a41eb1eda57e3a1e0e771e5ae37292346361b605 --- /dev/null +++ b/src/Rust/vvs_parser/src/tests/vivy_cases/pass/write_single/tokens.snap @@ -0,0 +1,160 @@ +--- +source: vvs_parser/tests/pass_cases.rs +expression: tokens +input_file: vvs_parser/tests/vivy_cases/pass/write_single +--- +- start_position: + bytes: 0 + line: 1 + character: 1 + end_position: + bytes: 4 + line: 1 + character: 5 + token_type: + type: Symbol + symbol: main +- start_position: + bytes: 4 + line: 1 + character: 5 + end_position: + bytes: 5 + line: 1 + character: 6 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 5 + line: 1 + character: 6 + end_position: + bytes: 11 + line: 1 + character: 12 + token_type: + type: StringLiteral + literal: init + quote_type: Double +- start_position: + bytes: 11 + line: 1 + character: 12 + end_position: + bytes: 12 + line: 1 + character: 13 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 12 + line: 1 + character: 13 + end_position: + bytes: 14 + line: 1 + character: 15 + token_type: + type: Symbol + symbol: do +- start_position: + bytes: 14 + line: 1 + character: 15 + end_position: + bytes: 15 + line: 1 + character: 15 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 15 + line: 2 + character: 1 + end_position: + bytes: 19 + line: 2 + character: 5 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 19 + line: 2 + character: 5 + end_position: + bytes: 25 + line: 2 + character: 11 + token_type: + type: Symbol + symbol: return +- start_position: + bytes: 25 + line: 2 + character: 11 + end_position: + bytes: 26 + line: 2 + character: 12 + token_type: + type: Whitespace + characters: " " +- start_position: + bytes: 26 + line: 2 + character: 12 + end_position: + bytes: 32 + line: 2 + character: 18 + token_type: + type: StringLiteral + literal: init + quote_type: Double +- start_position: + bytes: 32 + line: 2 + character: 18 + end_position: + bytes: 33 + line: 2 + character: 18 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 33 + line: 3 + character: 1 + end_position: + bytes: 36 + line: 3 + character: 4 + token_type: + type: Symbol + symbol: end +- start_position: + bytes: 36 + line: 3 + character: 4 + end_position: + bytes: 37 + line: 3 + character: 4 + token_type: + type: Whitespace + characters: "\n" +- start_position: + bytes: 37 + line: 4 + character: 1 + end_position: + bytes: 37 + line: 4 + character: 1 + token_type: + type: Eof diff --git a/src/Rust/vvs_parser/src/tokenizer/lexer.rs b/src/Rust/vvs_parser/src/tokenizer/lexer.rs new file mode 100644 index 0000000000000000000000000000000000000000..7ce1b9b5677b38ba19e0a4eb1b23cf90a26ddd03 --- /dev/null +++ b/src/Rust/vvs_parser/src/tokenizer/lexer.rs @@ -0,0 +1,764 @@ +//! Build the tokens. Don't need for outter world to know the lexer. + +use crate::{ + tokenizer::{ + Position, StringLiteralQuoteType, Symbol, Token, TokenReference, TokenType, TokenizerError, TokenizerErrorType, + }, + ShortString, +}; +use serde::{Deserialize, Serialize}; + +/// A lexer, which will produce a stream of tokens from a source string. +/// If you just want to create an [`Ast`](crate::ast::Ast) from a string, you want to use +/// [`parse`](crate::parse) instead. +pub struct Lexer { + pub(crate) source: LexerSource, + sent_eof: bool, + + next_token: Option<LexerResult<TokenReference>>, + peek_token: Option<LexerResult<TokenReference>>, +} + +impl Lexer { + /// Creates a new Lexer from the given source string. + pub fn new(source: &str) -> Self { + let mut lexer = Self::new_lazy(source); + lexer.next_token = lexer.process_first_with_trivia(); + lexer.peek_token = lexer.process_next_with_trivia(); + lexer + } + + /// Creates a new Lexer from the given source string, but does not process + /// the first token. + pub fn new_lazy(source: &str) -> Self { + Self { source: LexerSource::new(source), sent_eof: false, next_token: None, peek_token: None } + } + + /// Returns the current token. + pub fn current(&self) -> Option<&LexerResult<TokenReference>> { + self.next_token.as_ref() + } + + /// Returns the next token. + pub fn peek(&self) -> Option<&LexerResult<TokenReference>> { + self.peek_token.as_ref() + } + + /// Consumes the current token and returns the next token. + pub fn consume(&mut self) -> Option<LexerResult<TokenReference>> { + let next = self.next_token.take()?; + self.next_token = self.peek_token.take(); + self.peek_token = self.process_next_with_trivia(); + Some(next) + } + + /// Returns a vector of all tokens left in the source string. + pub fn collect(self) -> LexerResult<Vec<Token>> { + let mut tokens = Vec::new(); + let mut lexer = self; + let mut errors = Vec::new(); + + while let Some(token_reference) = lexer.consume() { + let mut token_reference = match token_reference { + LexerResult::Ok(token_reference) => token_reference, + LexerResult::Recovered(token_reference, mut new_errors) => { + errors.append(&mut new_errors); + token_reference + } + LexerResult::Fatal(mut new_errors) => { + errors.append(&mut new_errors); + continue; + } + }; + tokens.append(&mut token_reference.leading_trivia); + tokens.push(token_reference.token); + tokens.append(&mut token_reference.trailing_trivia); + } + + LexerResult::new(tokens, errors) + } + + fn create(&self, start_position: Position, token_type: TokenType) -> Option<LexerResult<Token>> { + Some(LexerResult::Ok(Token { token_type, start_position, end_position: self.source.position() })) + } + + fn create_recovered( + &self, + start_position: Position, + token_type: TokenType, + errors: Vec<TokenizerError>, + ) -> Option<LexerResult<Token>> { + Some(LexerResult::new(Token { token_type, start_position, end_position: self.source.position() }, errors)) + } + + fn process_next_with_trivia(&mut self) -> Option<LexerResult<TokenReference>> { + let mut leading_trivia = Vec::new(); + let mut errors: Option<Vec<TokenizerError>> = None; + + let nontrivial_token = loop { + match self.process_next()? { + LexerResult::Ok(token) if token.token_type().is_trivia() => leading_trivia.push(token), + LexerResult::Ok(token) => break token, + LexerResult::Fatal(error) => return Some(LexerResult::Fatal(error)), + LexerResult::Recovered(token, mut new_errors) => { + match errors.as_mut() { + Some(errors) => errors.append(&mut new_errors), + None => errors = Some(new_errors), + } + if token.token_type().is_trivia() { + leading_trivia.push(token); + } else { + break token; + } + } + } + }; + + let trailing_trivia = self.collect_trailing_trivia(); + let token = TokenReference { token: nontrivial_token, leading_trivia, trailing_trivia }; + match errors { + Some(errors) => Some(LexerResult::Recovered(token, errors)), + None => Some(LexerResult::Ok(token)), + } + } + + fn process_first_with_trivia(&mut self) -> Option<LexerResult<TokenReference>> { + if self.source.current() == Some('#') && self.source.peek() == Some('!') { + let start_position = self.source.position(); + let mut line = "#!".to_string(); + + self.source.next(); + self.source.next(); + + while let Some(next) = self.source.current() { + if next == '\n' { + break; + } + self.source.next(); + line.push(next); + } + + let end_position = self.source.position(); + let shebang = Token { token_type: TokenType::Shebang { line: line.into() }, start_position, end_position }; + + // rewrite todo: handle LexerResult better here + if let Some(LexerResult::Ok(mut token_reference)) = self.process_next_with_trivia() { + token_reference.leading_trivia.insert(0, shebang); + return Some(LexerResult::Ok(token_reference)); + } + } + + self.process_next_with_trivia() + } + + fn collect_trailing_trivia(&mut self) -> Vec<Token> { + let mut trailing_trivia = Vec::new(); + + loop { + let sent_eof = self.sent_eof; + let start_position = self.source.lexer_position; + + match self.process_next() { + Some(LexerResult::Ok(token)) if token.token_type().is_trivia() => { + // Take all trivia up to and including the newline character. If we see a newline character + // we should break once we have taken it in. + let should_break = if let TokenType::Whitespace { ref characters } = token.token_type() { + // Use contains in order to tolerate \r\n line endings and mixed whitespace tokens + characters.contains('\n') + } else { + false + }; + trailing_trivia.push(token); + if should_break { + break; + } + } + + _ => { + self.source.lexer_position = start_position; + self.sent_eof = sent_eof; + break; + } + } + } + + trailing_trivia + } + + /// Processes and returns the next token in the source string, ignoring trivia. + pub fn process_next(&mut self) -> Option<LexerResult<Token>> { + let start_position = self.source.position(); + let Some(next) = self.source.next() else { + if self.sent_eof { + return None; + } else { + self.sent_eof = true; + return self.create(start_position, TokenType::Eof); + } + }; + + macro_rules! consume { + ($first: literal, $second: literal) => { + self.source.consume_two($first, $second) + }; + ($first: literal) => { + self.source.consume($first) + }; + } + macro_rules! create { + ($symbol: ident) => { + self.create(start_position, TokenType::Symbol { symbol: Symbol::$symbol }) + }; + } + + match next { + // Identifiers + initial if is_identifier_start(initial) => { + let mut identifier = String::new(); + identifier.push(initial); + + while let Some(next) = self.source.current() { + if is_identifier_start(next) || next.is_ascii_digit() { + identifier.push(self.source.next().expect("peeked, but no next")); + } else { + break; + } + } + + let token_type = if let Some(symbol) = Symbol::from_str(&identifier) { + TokenType::Symbol { symbol } + } else { + TokenType::Identifier { identifier: ShortString::from(identifier) } + }; + self.create(start_position, token_type) + } + + // Spaces + initial @ (' ' | '\t' | '\r') => { + let mut whitespace = String::new(); + whitespace.push(initial); + + // Handle end_position appropriately: for a newline, we increment the bytes, but + // do not increment line/char + let mut end_position = Position { + bytes: start_position.bytes() + initial.len_utf8(), + line: start_position.line, + character: start_position.character + 1, + }; + + while let Some(next) = self.source.current() { + if next == ' ' || next == '\t' { + end_position.bytes += next.len_utf8(); + end_position.character += 1; + whitespace.push(self.source.next().expect("peeked, but no next")); + continue; + } + + if next == '\n' { + end_position.bytes += next.len_utf8(); + whitespace.push(self.source.next().expect("peeked, but no next")); + } else if next == '\r' && self.source.peek() == Some('\n') { + let carriage_return = self.source.next().expect("peeked, but no next"); + let new_line = self.source.next().expect("peeked, but no next"); + end_position.bytes += carriage_return.len_utf8() + new_line.len_utf8(); + end_position.character += 1; + whitespace.push(carriage_return); + whitespace.push(new_line); + } + break; + } + + Some(LexerResult::Ok(Token { + token_type: TokenType::Whitespace { characters: ShortString::from(whitespace.as_str()) }, + start_position, + end_position, + })) + } + + // Integers + '0' if matches!(self.source.current(), Some('x' | 'X')) => { + let hex_character = self.source.next().unwrap(); + self.read_hex_number(hex_character, start_position) + } + '0' if matches!(self.source.current(), Some('b' | 'B')) => { + let binary_character = self.source.next().unwrap(); + self.read_binary_number(binary_character, start_position) + } + initial @ '0' => self.read_number(start_position, initial.to_string()), + initial @ ('1'..='9') => self.read_number(start_position, initial.to_string()), + + // Strings + quote @ ('"' | '\'') => { + let (string, recovered) = self.read_string(quote); + let errors = recovered.then(|| TokenizerError { + error: TokenizerErrorType::UnclosedString, + range: (start_position, self.source.position()), + }); + self.create_recovered(start_position, string, errors.into_iter().collect()) + } + + // Complicated things + '[' if matches!(self.source.current(), Some('[' | '=')) => { + let start_lexer_position = self.source.lexer_position; + match self.read_multi_line_body() { + MultiLineBodyResult::Ok { blocks, body } => self.create( + start_position, + TokenType::StringLiteral { + literal: body.into(), + multi_line_depth: blocks, + quote_type: StringLiteralQuoteType::Brackets, + }, + ), + MultiLineBodyResult::Unclosed { blocks, body } => self.create_recovered( + start_position, + TokenType::StringLiteral { + literal: body.into(), + multi_line_depth: blocks, + quote_type: StringLiteralQuoteType::Brackets, + }, + vec![TokenizerError { + error: TokenizerErrorType::UnclosedString, + range: (start_position, self.source.position()), + }], + ), + MultiLineBodyResult::NotMultiLine { .. } => { + // Reset back, parse the one `[`, and let the rest be parsed again + self.source.lexer_position = start_lexer_position; + create!(LeftBracket) + } + } + } + + // Consume three + '/' if consume!('/', '=') => create!(DoubleSlashEqual), + '.' if consume!('.', '=') => create!(TwoDotsEqual), + + // Consume two + '/' if consume!('/') => create!(DoubleSlash), + '/' if consume!('=') => create!(SlashEqual), + ':' if consume!(':') => create!(TwoColons), + '+' if consume!('=') => create!(PlusEqual), + '*' if consume!('=') => create!(StarEqual), + '%' if consume!('=') => create!(PercentEqual), + '^' if consume!('=') => create!(CaretEqual), + '=' if consume!('=') => create!(TwoEqual), + '~' if consume!('>') => create!(DoubleGreaterThan), + '~' if consume!('=') => create!(TildeEqual), + '<' if consume!('~') => create!(DoubleLesserThan), + '<' if consume!('=') => create!(LessThanEqual), + '>' if consume!('=') => create!(GreaterThanEqual), + '.' if consume!('.') => create!(TwoDots), + '-' if consume!('=') => create!(MinusEqual), + '-' if consume!('>') => create!(ThinArrow), + '-' if consume!('-') => { + let (token, recovered) = self.read_comment(); + let errors = recovered.then(|| TokenizerError { + error: TokenizerErrorType::UnclosedComment, + range: (start_position, self.source.position()), + }); + self.create_recovered(start_position, token, errors.into_iter().collect()) + } + '.' if matches!(self.source.current(), Some('0'..='9')) => { + self.read_number(start_position, ".".to_string()) + } + + // Consume one + ':' => create!(Colon), + '+' => create!(Plus), + '*' => create!(Star), + '%' => create!(Percent), + '^' => create!(Caret), + '=' => create!(Equal), + '~' => create!(Tilde), + '<' => create!(LessThan), + '>' => create!(GreaterThan), + '(' => create!(LeftParen), + ')' => create!(RightParen), + ']' => create!(RightBracket), + ';' => create!(Semicolon), + '&' => create!(Ampersand), + '|' => create!(Pipe), + '?' => create!(QuestionMark), + '#' => create!(Hash), + ',' => create!(Comma), + '[' => create!(LeftBracket), + '}' => create!(RightBrace), + '/' => create!(Slash), + '.' => create!(Dot), + '-' => create!(Minus), + '{' => create!(LeftBrace), + + '\n' => Some(LexerResult::Ok(Token { + token_type: TokenType::Whitespace { characters: ShortString::from("\n") }, + start_position, + end_position: Position { bytes: start_position.bytes() + 1, ..start_position }, + })), + + // Oupsy + unknown_char => Some(LexerResult::Fatal(vec![TokenizerError { + error: TokenizerErrorType::UnexpectedToken(unknown_char), + range: (start_position, self.source.position()), + }])), + } + } + + fn read_number(&mut self, start_position: Position, mut number: String) -> Option<LexerResult<Token>> { + let mut hit_decimal = false; + while let Some(next) = self.source.current() { + if next.is_ascii_digit() || matches!(next, '_') { + number.push(self.source.next().expect("peeked, but no next")); + } else if matches!(next, '.') && hit_decimal { + return Some(self.eat_invalid_number(start_position, number)); + } else if matches!(next, '.') { + hit_decimal = true; + number.push(self.source.next().expect("peeked, but no next")); + } else if matches!(next, 'e' | 'E') { + return self.read_exponent_part(start_position, number); + } else { + break; + } + } + self.create(start_position, TokenType::Number { text: ShortString::from(number) }) + } + + fn eat_invalid_number(&mut self, start_position: Position, mut number: String) -> LexerResult<Token> { + loop { + if matches!(self.source.current(), Some(token) if token.is_ascii_whitespace()) + || self.source.current().is_none() + { + return LexerResult::new( + Token { + token_type: TokenType::Number { text: number.into() }, + start_position, + end_position: self.source.position(), + }, + vec![TokenizerError { + error: TokenizerErrorType::InvalidNumber, + range: (start_position, self.source.position()), + }], + ); + } + + number.push(self.source.next().expect("peeked, but no next")); + } + } + + // Starts from the exponent marker (like 'e') + fn read_exponent_part(&mut self, start_position: Position, mut number: String) -> Option<LexerResult<Token>> { + number.push(self.source.next().expect("peeked, but no next")); + + let next = self.source.current(); + if matches!(next, Some('+') | Some('-')) { + number.push(self.source.next().expect("peeked, but no next")); + } + + if !matches!(self.source.current(), Some('0'..='9')) { + return Some(self.eat_invalid_number(start_position, number)); + } + + while let Some(next) = self.source.current() { + if !next.is_ascii_digit() && !matches!(next, '_') { + break; + } + number.push(self.source.next().expect("peeked, but no next")); + } + + self.create(start_position, TokenType::Number { text: ShortString::from(number) }) + } + + fn read_hex_number(&mut self, hex_character: char, start_position: Position) -> Option<LexerResult<Token>> { + let mut number = String::from_iter(['0', hex_character]); + let mut hit_decimal = false; + + while let Some(next) = self.source.current() { + match next { + '0'..='9' | 'a'..='f' | 'A'..='F' | '_' => { + number.push(self.source.next().expect("peeked, but no next")) + } + + 'p' | 'P' if number.len() == 2 => return Some(self.eat_invalid_number(start_position, number)), + 'p' | 'P' => return self.read_exponent_part(start_position, number), + '.' if hit_decimal => return Some(self.eat_invalid_number(start_position, number)), + + '.' => { + hit_decimal = true; + number.push(self.source.next().expect("peeked, but no next")); + } + + _ => break, + } + } + + if number.len() == 2 { + return Some(self.eat_invalid_number(start_position, number)); + } + + self.create(start_position, TokenType::Number { text: ShortString::from(number) }) + } + + fn read_binary_number(&mut self, binary_character: char, start_position: Position) -> Option<LexerResult<Token>> { + let mut number = String::from_iter(['0', binary_character]); + + while matches!(self.source.current(), Some('0' | '1' | '_')) { + number.push(self.source.next().expect("peeked, but no next")) + } + + if number.len() == 2 { + return Some(self.eat_invalid_number(start_position, number)); + } + + self.create(start_position, TokenType::Number { text: ShortString::from(number) }) + } + + // (string, had to be recovered?) + fn read_string(&mut self, quote: char) -> (TokenType, bool) { + let quote_type = match quote { + '"' => StringLiteralQuoteType::Double, + '\'' => StringLiteralQuoteType::Single, + _ => unreachable!(), + }; + + let mut literal = String::new(); + let mut escape = false; + let mut z_escaped = false; + + loop { + let Some(next) = self.source.next() else { + let token = TokenType::StringLiteral { literal: literal.into(), multi_line_depth: 0, quote_type }; + return (token, true); + }; + + match (escape, next) { + (true, 'z') => { + escape = false; + z_escaped = true; + literal.push('z'); + } + + (true, ..) => { + escape = false; + z_escaped = true; // support for '\' followed by a new line + literal.push(next); + } + + (false, '\\') => { + escape = true; + literal.push('\\'); + } + + (false, '\n' | '\r') if z_escaped => { + z_escaped = false; + literal.push(next); + } + + (false, '\n' | '\r') => { + let token = TokenType::StringLiteral { literal: literal.into(), multi_line_depth: 0, quote_type }; + return (token, true); + } + + (false, ..) if next == quote => { + let token = TokenType::StringLiteral { literal: literal.into(), multi_line_depth: 0, quote_type }; + return (token, false); + } + + (false, ..) => literal.push(next), + } + } + } + + // (comment, had to be recovered?) + fn read_comment(&mut self) -> (TokenType, bool) { + let mut comment = String::new(); + + if self.source.consume('[') { + match self.read_multi_line_body() { + MultiLineBodyResult::Ok { blocks, body } | MultiLineBodyResult::Unclosed { blocks, body } => { + return (TokenType::MultiLineComment { blocks, comment: body.into() }, false); + } + + MultiLineBodyResult::NotMultiLine { blocks } => { + comment.push('['); + (0..blocks).for_each(|_| comment.push('=')); + } + } + } + + let mut position_before_new_line = self.source.lexer_position; + + while let Some(next) = self.source.next() { + if next == '\n' { + break; + } + comment.push(next); + position_before_new_line = self.source.lexer_position; + } + + self.source.lexer_position = position_before_new_line; + (TokenType::SingleLineComment { comment: comment.into() }, false) + } + + fn read_multi_line_body(&mut self) -> MultiLineBodyResult { + let mut blocks = 0; + while self.source.consume('=') { + blocks += 1; + } + + if !self.source.consume('[') { + return MultiLineBodyResult::NotMultiLine { blocks }; + } + + let mut body = String::new(); + 'read_comment_char: loop { + let Some(next) = self.source.next() else { + return MultiLineBodyResult::Unclosed { blocks, body }; + }; + + if next == ']' { + let mut equal_signs = 0; + while equal_signs < blocks { + if !self.source.consume('=') { + body.push(']'); + (0..equal_signs).for_each(|_| body.push('=')); + continue 'read_comment_char; + } + equal_signs += 1; + } + + if self.source.consume(']') { + break; + } + + body.push(']'); + (0..equal_signs).for_each(|_| body.push('=')); + + continue; + } + + body.push(next); + } + + MultiLineBodyResult::Ok { blocks, body } + } +} + +fn is_identifier_start(character: char) -> bool { + matches!(character, 'a'..='z' | 'A'..='Z' | '_') +} + +pub(crate) struct LexerSource { + source: Vec<char>, + lexer_position: LexerPosition, +} + +impl LexerSource { + fn new(source: &str) -> Self { + Self { source: source.chars().collect(), lexer_position: LexerPosition::new() } + } + + pub(crate) fn current(&self) -> Option<char> { + self.source.get(self.lexer_position.index).copied() + } + + pub(crate) fn next(&mut self) -> Option<char> { + let next = self.current()?; + if next == '\n' { + self.lexer_position.position.line += 1; + self.lexer_position.position.character = 1; + } else { + self.lexer_position.position.character += 1; + } + self.lexer_position.position.bytes += next.len_utf8(); + self.lexer_position.index += 1; + Some(next) + } + + pub(crate) fn peek(&self) -> Option<char> { + self.source.get(self.lexer_position.index + 1).copied() + } + + pub(crate) fn consume(&mut self, character: char) -> bool { + if self.current() == Some(character) { + self.next(); + return true; + } + false + } + + pub(crate) fn consume_two(&mut self, one: char, two: char) -> bool { + if self.current() == Some(one) && self.peek() == Some(two) { + self.next(); + self.next(); + return true; + } + false + } + + pub(crate) fn position(&self) -> Position { + self.lexer_position.position + } +} + +#[derive(Clone, Copy)] +struct LexerPosition { + position: Position, + index: usize, +} + +impl LexerPosition { + fn new() -> Self { + Self { position: Position { line: 1, character: 1, bytes: 0 }, index: 0 } + } +} + +/// The result of a lexer operation. +#[derive(Debug, Deserialize, Serialize)] +pub enum LexerResult<T> { + /// The lexer operation was successful. + Ok(T), + + /// The lexer operation was unsuccessful, and could not be recovered. + Fatal(Vec<TokenizerError>), + + /// The lexer operation was unsuccessful, but some result can be extracted. + Recovered(T, Vec<TokenizerError>), +} + +impl<T: std::fmt::Debug> LexerResult<T> { + fn new(value: T, errors: Vec<TokenizerError>) -> Self { + if errors.is_empty() { + Self::Ok(value) + } else { + Self::Recovered(value, errors) + } + } + + /// Unwraps the result, panicking if it is not [`LexerResult::Ok`]. + pub fn unwrap(self) -> T { + match self { + Self::Ok(value) => value, + _ => panic!("expected ok, got {self:#?}"), + } + } + + /// Unwraps the errors, panicking if it is [`LexerResult::Ok`]. + pub fn unwrap_errors(self) -> Vec<TokenizerError> { + match self { + Self::Fatal(errors) | Self::Recovered(_, errors) => errors, + _ => panic!("expected fatal error, got {self:#?}"), + } + } + + /// Returns the errors, if there was any. + pub fn errors(self) -> Vec<TokenizerError> { + match self { + Self::Recovered(_, errors) => errors, + _ => Vec::new(), + } + } +} + +enum MultiLineBodyResult { + Ok { blocks: usize, body: String }, + NotMultiLine { blocks: usize }, + Unclosed { blocks: usize, body: String }, +} diff --git a/src/Rust/vvs_parser/src/tokenizer/mod.rs b/src/Rust/vvs_parser/src/tokenizer/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..e21238a7c4dd171caa135b4c6deb93fb953b0017 --- /dev/null +++ b/src/Rust/vvs_parser/src/tokenizer/mod.rs @@ -0,0 +1,8 @@ +//! Used for tokenizing, the process of converting the code to individual tokens. Useful for +//! getting symbols and manually tokenizing without going using an AST. + +mod lexer; +mod structs; + +pub(crate) use lexer::*; +pub use structs::*; diff --git a/src/Rust/vvs_parser/src/tokenizer/structs.rs b/src/Rust/vvs_parser/src/tokenizer/structs.rs new file mode 100644 index 0000000000000000000000000000000000000000..717e145fb380afd477cf8c7c93a50af22992c86a --- /dev/null +++ b/src/Rust/vvs_parser/src/tokenizer/structs.rs @@ -0,0 +1,719 @@ +use crate::{ + tokenizer::{Lexer, LexerResult}, + visitors::{Visit, VisitMut, Visitor, VisitorMut}, + ShortString, +}; +use derive_more::{Deref, Display}; +use serde::{Deserialize, Serialize}; +use std::{cmp::Ordering, fmt}; + +macro_rules! symbol { + { + $(#[$symbol_meta:meta])* + pub enum Symbol { + $( + $(#[$meta:meta])* + $name:ident => $string:literal, + )+ + } + } => { + paste::paste! { + $(#[$symbol_meta])* + #[derive(Display)] + pub enum Symbol { + $( + $(#[$meta])* + #[serde(rename = $string)] + #[display("{}", $string)] + $name, + )+ + } + + impl Symbol { + /// Given just the symbol text (no whitespace), returns the associated symbol, if + /// it exists. If you want a TokenReference instead, consider [TokenReference::symbol]. + #[allow(clippy::should_implement_trait)] + pub fn from_str(symbol: &str) -> Option<Self> { + match symbol { + $($string => { Some(Self::$name) },)+ + _ => None, + } + } + } + + } + }; +} + +symbol! { + #[non_exhaustive] + #[allow(missing_docs)] + #[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)] + /// A literal symbol, used for both words important to syntax (like while) and operators (like +) + pub enum Symbol { + And => "and", + Break => "break", + Do => "do", + Else => "else", + ElseIf => "elseif", + ElIf => "elif", + End => "end", + False => "false", + For => "for", + Function => "function", + If => "if", + In => "in", + Local => "local", + Nil => "nil", + Not => "not", + Or => "or", + Repeat => "repeat", + Return => "return", + Then => "then", + True => "true", + Until => "until", + While => "while", + Import => "import", + Job => "job", + Option => "option", + Main => "main", + Yield => "yield", + + PlusEqual => "+=", + MinusEqual => "-=", + StarEqual => "*=", + SlashEqual => "/=", + DoubleSlashEqual => "//=", + PercentEqual => "%=", + CaretEqual => "^=", + TwoDotsEqual => "..=", + + Ampersand => "&", + ThinArrow => "->", + TwoColons => "::", + Caret => "^", + Colon => ":", + Comma => ",", + Dot => ".", + TwoDots => "..", + Equal => "=", + TwoEqual => "==", + GreaterThan => ">", + GreaterThanEqual => ">=", + Hash => "#", + LeftBrace => "{", + LeftBracket => "[", + LeftParen => "(", + LessThan => "<", + LessThanEqual => "<=", + Minus => "-", + Percent => "%", + Pipe => "|", + Plus => "+", + QuestionMark => "?", + RightBrace => "}", + RightBracket => "]", + RightParen => ")", + Semicolon => ";", + Slash => "/", + DoubleSlash => "//", + Star => "*", + Tilde => "~", + TildeEqual => "~=", + DoubleGreaterThan => "~>", + DoubleLesserThan => "<~", + } +} + +/// The possible errors that can happen while tokenizing. +#[derive(Clone, Debug, PartialEq, Eq, Display, Deserialize, Serialize)] +pub enum TokenizerErrorType { + /// An unclosed multi-line comment was found + #[display("unclosed comment")] + UnclosedComment, + + /// An unclosed string was found + #[display("unclosed string")] + UnclosedString, + + /// An invalid number was found + #[display("invalid number")] + InvalidNumber, + + /// An unexpected token was found + #[display("unexpected character {_0}")] + UnexpectedToken(char), + + /// Symbol passed is not valid + /// Returned from [`TokenReference::symbol`] + #[display("invalid symbol {_0}")] + InvalidSymbol(String), +} + +/// Used by serde +fn is_usize_zero(input: &usize) -> bool { + *input == 0 +} + +/// The type of tokens in parsed code +#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)] +#[serde(tag = "type")] +#[non_exhaustive] +pub enum TokenType { + /// End of file, should always be the very last token + Eof, + + /// An identifier, such as `foo` + Identifier { + /// The identifier itself + identifier: ShortString, + }, + + /// A multi line comment in the format of `--[[ comment ]]` + MultiLineComment { + /// Number of equals signs, if any, for the multi line comment + /// For example, `--[=[` would have a `blocks` value of `1` + blocks: usize, + + /// The comment itself, ignoring opening and closing tags + comment: ShortString, + }, + + /// A literal number, such as `3.3` + Number { + /// The text representing the number, includes details such as `0x` + text: ShortString, + }, + + /// A shebang line + Shebang { + /// The shebang line itself + line: ShortString, + }, + + /// A single line comment, such as `-- comment` + SingleLineComment { + /// The comment, ignoring initial `--` + comment: ShortString, + }, + + /// A literal string, such as "Hello, world" + StringLiteral { + /// The literal itself, ignoring quotation marks + literal: ShortString, + + #[serde(skip_serializing_if = "is_usize_zero")] + /// Number of equals signs used for a multi line string, if it is one + /// For example, `[=[string]=]` would have a `multi_line_depth` value of 1 + /// `[[string]]` would have a `multi_line_depth` value of 0 + /// A string such as `"string"` would have also have a `multi_line_depth` value of 0 + multi_line_depth: usize, + + /// The type of quotation mark used to make the string + quote_type: StringLiteralQuoteType, + }, + + /// A [`Symbol`], such as `local` or `+` + Symbol { + /// The symbol itself + symbol: Symbol, + }, + + /// Whitespace, such as tabs or new lines + Whitespace { + /// Characters consisting of the whitespace + characters: ShortString, + }, +} + +impl TokenType { + /// Returns whether a token can be practically ignored in most cases + /// Comments and whitespace will return `true`, everything else will return `false` + pub fn is_trivia(&self) -> bool { + use TokenType::*; + matches!(self, Shebang { .. } | SingleLineComment { .. } | MultiLineComment { .. } | Whitespace { .. }) + } + + /// Returns the kind of the token type. + /// + /// ```rust + /// use vvs_parser::prelude::ast::*; + /// + /// assert_eq!( + /// TokenType::Identifier { + /// identifier: ShortString::new("hello") + /// }.kind(), + /// TokenKind::Identifier, + /// ); + /// ``` + pub fn kind(&self) -> TokenKind { + match self { + TokenType::Eof => TokenKind::Eof, + TokenType::Identifier { .. } => TokenKind::Identifier, + TokenType::MultiLineComment { .. } => TokenKind::MultiLineComment, + TokenType::Number { .. } => TokenKind::Number, + TokenType::Shebang { .. } => TokenKind::Shebang, + TokenType::SingleLineComment { .. } => TokenKind::SingleLineComment, + TokenType::StringLiteral { .. } => TokenKind::StringLiteral, + TokenType::Symbol { .. } => TokenKind::Symbol, + TokenType::Whitespace { .. } => TokenKind::Whitespace, + } + } + + /// Returns a whitespace `TokenType` consisting of spaces + pub fn spaces(spaces: usize) -> Self { + TokenType::Whitespace { characters: " ".repeat(spaces).into() } + } + + /// Returns a whitespace `TokenType` consisting of tabs + pub fn tabs(tabs: usize) -> Self { + TokenType::Whitespace { characters: "\t".repeat(tabs).into() } + } + + /// Try to convert the token into a string slice. If it's not possible returns [None]. In the + /// [TokenType::StringLiteral] case, we try to unquote the string. + pub fn to_str(&self) -> Option<&str> { + use StringLiteralQuoteType::*; + match self { + TokenType::Identifier { identifier } => Some(identifier), + TokenType::StringLiteral { literal, quote_type: Double, .. } => Some(literal.trim_matches('\"').trim()), + TokenType::StringLiteral { literal, quote_type: Single, .. } => Some(literal.trim_matches('\'').trim()), + TokenType::StringLiteral { literal, quote_type: Brackets, multi_line_depth } => { + todo!("use {multi_line_depth} to get ride of the [==[ or the [[ or the [=[ in {literal}") + } + _ => None, + } + } + + /// Same as [TokenType::to_str] but panics instead of returning [None]. + pub fn as_str(&self) -> &str { + self.to_str().unwrap() + } +} + +impl fmt::Display for TokenType { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match self { + TokenType::Eof => Ok(()), + TokenType::Number { text } => text.fmt(formatter), + TokenType::Identifier { identifier } => identifier.fmt(formatter), + TokenType::MultiLineComment { blocks, comment } => { + write!(formatter, "--[{0}[{1}]{0}]", "=".repeat(*blocks), comment) + } + TokenType::Shebang { line } => line.fmt(formatter), + TokenType::SingleLineComment { comment } => write!(formatter, "--{comment}"), + TokenType::StringLiteral { literal, multi_line_depth, quote_type } => { + if *quote_type == StringLiteralQuoteType::Brackets { + write!(formatter, "[{0}[{1}]{0}]", "=".repeat(*multi_line_depth), literal) + } else { + write!(formatter, "{0}{1}{0}", quote_type.to_string(), literal) + } + } + TokenType::Symbol { symbol } => symbol.fmt(formatter), + TokenType::Whitespace { characters } => characters.fmt(formatter), + } + } +} + +/// The kind of token. Contains no additional data. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[non_exhaustive] +pub enum TokenKind { + /// End of file, should always be the very last token + Eof, + + /// An identifier, such as `foo` + Identifier, + + /// A multi line comment in the format of `--[[ comment ]]` + MultiLineComment, + + /// A literal number, such as `3.3` + Number, + + /// The shebang line + Shebang, + + /// A single line comment, such as `-- comment` + SingleLineComment, + + /// A literal string, such as "Hello, world" + StringLiteral, + + /// A [`Symbol`], such as `local` or `+` + Symbol, + + /// Whitespace, such as tabs or new lines + Whitespace, +} + +/// A token such consisting of its [`Position`] and a [`TokenType`] +#[derive(Clone, Debug, Eq, PartialEq, Display, Deserialize, Serialize)] +#[display("{token_type}")] +pub struct Token { + pub(crate) start_position: Position, + pub(crate) end_position: Position, + pub(crate) token_type: TokenType, +} + +impl Token { + /// Creates a token with a zero position + pub const fn new(token_type: TokenType) -> Token { + Token { start_position: Position::new(), end_position: Position::new(), token_type } + } + + /// The position a token begins at + pub fn start_position(&self) -> Position { + self.start_position + } + + /// The position a token ends at + pub fn end_position(&self) -> Position { + self.end_position + } + + /// The type of token as well as the data needed to represent it + /// If you don't need any other information, use [`token_kind`](Token::token_kind) instead. + pub fn token_type(&self) -> &TokenType { + &self.token_type + } + + /// The kind of token with no additional data. + /// If you need any information such as idenitfier names, use [`token_type`](Token::token_type) instead. + pub fn token_kind(&self) -> TokenKind { + self.token_type().kind() + } +} + +impl Ord for Token { + fn cmp(&self, other: &Self) -> Ordering { + self.start_position().cmp(&other.start_position()) + } +} + +impl PartialOrd for Token { + fn partial_cmp(&self, other: &Self) -> Option<Ordering> { + Some(self.cmp(other)) + } +} + +impl Visit for Token { + fn visit<V: Visitor>(&self, visitor: &mut V) { + visitor.visit_token(self); + match self.token_kind() { + TokenKind::Eof => {} + TokenKind::Identifier => visitor.visit_identifier(self), + TokenKind::MultiLineComment => visitor.visit_multi_line_comment(self), + TokenKind::Number => visitor.visit_number(self), + TokenKind::Shebang => {} + TokenKind::SingleLineComment => visitor.visit_single_line_comment(self), + TokenKind::StringLiteral => visitor.visit_string_literal(self), + TokenKind::Symbol => visitor.visit_symbol(self), + TokenKind::Whitespace => visitor.visit_whitespace(self), + } + } +} + +impl VisitMut for Token { + fn visit_mut<V: VisitorMut>(self, visitor: &mut V) -> Self { + let token = visitor.visit_token(self); + match token.token_kind() { + TokenKind::Eof => token, + TokenKind::Identifier => visitor.visit_identifier(token), + TokenKind::MultiLineComment => visitor.visit_multi_line_comment(token), + TokenKind::Number => visitor.visit_number(token), + TokenKind::Shebang => token, + TokenKind::SingleLineComment => visitor.visit_single_line_comment(token), + TokenKind::StringLiteral => visitor.visit_string_literal(token), + TokenKind::Symbol => visitor.visit_symbol(token), + TokenKind::Whitespace => visitor.visit_whitespace(token), + } + } +} + +/// A reference to a token used by Ast's. +/// Dereferences to a [`Token`] +#[derive(Clone, Debug, Deref, Deserialize, Serialize)] +pub struct TokenReference { + pub(crate) leading_trivia: Vec<Token>, + #[deref] + pub(crate) token: Token, + pub(crate) trailing_trivia: Vec<Token>, +} + +impl TokenReference { + /// Creates a TokenReference from leading/trailing trivia as well as the leading token + pub const fn new(leading_trivia: Vec<Token>, token: Token, trailing_trivia: Vec<Token>) -> Self { + Self { leading_trivia, token, trailing_trivia } + } + + /// Returns a symbol with the leading and trailing whitespace + /// Only whitespace is supported + /// ```rust + /// # use vvs_parser::prelude::{ast::*, *}; + /// # fn main() -> Result<(), Box<TokenizerErrorType>> { + /// let symbol = TokenReference::symbol("\nreturn ")?; + /// assert_eq!(symbol.leading_trivia().next().unwrap().to_string(), "\n"); + /// assert_eq!(symbol.token().token_type(), &TokenType::Symbol { symbol: Symbol::Return }); + /// assert_eq!(symbol.trailing_trivia().next().unwrap().to_string(), " "); + /// assert!(TokenReference::symbol("isnt whitespace").is_err()); + /// assert!(TokenReference::symbol(" notasymbol ").is_err()); + /// # Ok(()) + /// # } + /// ``` + pub fn symbol(text: &str) -> Result<Self, TokenizerErrorType> { + let mut lexer = Lexer::new_lazy(text); + let mut leading_trivia = Vec::new(); + let symbol; + loop { + match lexer.process_next().expect("we shouldn't have hit eof") { + LexerResult::Ok(token @ Token { token_type: TokenType::Whitespace { .. }, .. }) => { + leading_trivia.push(token) + } + LexerResult::Ok(token @ Token { token_type: TokenType::Symbol { .. }, .. }) => { + symbol = token; + break; + } + LexerResult::Ok(Token { token_type: TokenType::Eof, .. }) => { + return Err(TokenizerErrorType::InvalidSymbol(text.to_owned())) + } + LexerResult::Ok(token) => { + return Err(TokenizerErrorType::UnexpectedToken(token.to_string().chars().next().unwrap())) + } + LexerResult::Fatal(mut errors) | LexerResult::Recovered(_, mut errors) => { + return Err(errors.remove(0).error); + } + } + } + + let mut trailing_trivia = Vec::new(); + loop { + match lexer.process_next().expect("we shouldn't have hit eof") { + LexerResult::Ok(token @ Token { token_type: TokenType::Whitespace { .. }, .. }) => { + trailing_trivia.push(token); + } + LexerResult::Ok(Token { token_type: TokenType::Eof, .. }) => break, + LexerResult::Ok(token) => { + return Err(TokenizerErrorType::UnexpectedToken(token.to_string().chars().next().unwrap())); + } + LexerResult::Fatal(mut errors) | LexerResult::Recovered(_, mut errors) => { + return Err(errors.remove(0).error); + } + } + } + + Ok(TokenReference { leading_trivia, token: symbol, trailing_trivia }) + } + + pub(crate) fn basic_symbol(text: &str) -> Self { + TokenReference::symbol(text).unwrap() + } + + /// Returns the inner token. + pub fn token(&self) -> &Token { + &self.token + } + + /// Returns the leading trivia + pub fn leading_trivia(&self) -> impl Iterator<Item = &Token> { + self.leading_trivia.iter() + } + + /// Returns the trailing trivia + pub fn trailing_trivia(&self) -> impl Iterator<Item = &Token> { + self.trailing_trivia.iter() + } + + /// Creates a clone of the current TokenReference with the new inner token, preserving trivia. + pub fn with_token(&self, token: Token) -> Self { + Self { token, leading_trivia: self.leading_trivia.clone(), trailing_trivia: self.trailing_trivia.clone() } + } + + /// Checks if the token is the given symbol + pub fn is_symbol(&self, symbol: Symbol) -> bool { + self.token.token_type() == &TokenType::Symbol { symbol } + } + + /// Checks if the token is in the given symbol set + pub fn in_symbols(&self, symbols: &[Symbol]) -> bool { + symbols.iter().any(|&symbol| self.is_symbol(symbol)) + } + + /// Checks if the token is of the given kind + pub fn is_kind(&self, kind: TokenKind) -> bool { + self.token.token_kind() == kind + } +} + +impl std::borrow::Borrow<Token> for &TokenReference { + fn borrow(&self) -> &Token { + self + } +} + +impl fmt::Display for TokenReference { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + for trivia in &self.leading_trivia { + trivia.fmt(formatter)?; + } + self.token.fmt(formatter)?; + for trivia in &self.trailing_trivia { + trivia.fmt(formatter)?; + } + Ok(()) + } +} + +impl From<&TokenReference> for TokenReference { + fn from(value: &TokenReference) -> Self { + value.clone() + } +} + +impl PartialEq<Self> for TokenReference { + fn eq(&self, other: &Self) -> bool { + (**self).eq(other) + && self.leading_trivia == other.leading_trivia + && self.trailing_trivia == other.trailing_trivia + } +} + +impl Eq for TokenReference {} + +impl Ord for TokenReference { + fn cmp(&self, other: &Self) -> Ordering { + (**self).cmp(&**other) + } +} + +impl PartialOrd for TokenReference { + fn partial_cmp(&self, other: &Self) -> Option<Ordering> { + Some(self.cmp(other)) + } +} + +impl Visit for TokenReference { + fn visit<V: Visitor>(&self, visitor: &mut V) { + visitor.visit_token(self); + if matches!(self.token().token_kind(), TokenKind::Eof) { + visitor.visit_eof(self); + } + self.leading_trivia.visit(visitor); + self.token.visit(visitor); + self.trailing_trivia.visit(visitor); + } +} + +impl VisitMut for TokenReference { + fn visit_mut<V: VisitorMut>(self, visitor: &mut V) -> Self { + let mut token_reference = visitor.visit_token_reference(self); + if matches!(token_reference.token().token_kind(), TokenKind::Eof) { + token_reference = visitor.visit_eof(token_reference); + } + token_reference.leading_trivia = token_reference.leading_trivia.visit_mut(visitor); + token_reference.token = token_reference.token.visit_mut(visitor); + token_reference.trailing_trivia = token_reference.trailing_trivia.visit_mut(visitor); + token_reference + } +} + +/// Used to represent exact positions of tokens in code +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Deserialize, Serialize)] +pub struct Position { + pub(crate) bytes: usize, + pub(crate) line: usize, + pub(crate) character: usize, +} + +impl Position { + /// Create a new default position. Can be called in const context. + pub const fn new() -> Self { + Self { bytes: 0, line: 0, character: 0 } + } + + /// How many bytes, ignoring lines, it would take to find this position + pub fn bytes(self) -> usize { + self.bytes + } + + /// Index of the character on the line for this position + pub fn character(self) -> usize { + self.character + } + + /// Line the position lies on + pub fn line(self) -> usize { + self.line + } +} + +impl Ord for Position { + fn cmp(&self, other: &Self) -> Ordering { + self.bytes.cmp(&other.bytes) + } +} + +impl PartialOrd for Position { + fn partial_cmp(&self, other: &Self) -> Option<Ordering> { + Some(self.cmp(other)) + } +} + +/// The types of quotes used in a Lua string +#[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize, Serialize)] +#[non_exhaustive] +pub enum StringLiteralQuoteType { + /// Strings formatted \[\[with brackets\]\] + Brackets, + + /// Strings formatted "with double quotes" + Double, + + /// Strings formatted 'with single quotes' + Single, +} + +impl fmt::Display for StringLiteralQuoteType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + // Brackets cannot be properly displayed, as not only do they have + // variable depth (`=`), but also they don't open the same as + // they end, meaning this can't really be used for display purposes. + StringLiteralQuoteType::Brackets => Err(fmt::Error), + StringLiteralQuoteType::Double => write!(f, "\""), + StringLiteralQuoteType::Single => write!(f, "'"), + } + } +} + +/// Information about an error that occurs while tokenizing +#[derive(Clone, Debug, PartialEq, Eq, Display, Deserialize, Serialize)] +#[display("{error} ({}:{} to {}:{})", + range.0.line, range.0.character, range.1.line, range.1.character +)] +pub struct TokenizerError { + /// The type of error + pub(crate) error: TokenizerErrorType, + + /// The range of the token that caused the error + pub(crate) range: (Position, Position), +} + +impl TokenizerError { + /// The type of error + pub fn error(&self) -> &TokenizerErrorType { + &self.error + } + + /// The position of the first token that caused the error + pub fn position(&self) -> Position { + self.range.0 + } + + /// The range of the token that caused the error + pub fn range(&self) -> (Position, Position) { + self.range + } +} + +impl std::error::Error for TokenizerError {} diff --git a/src/Rust/vvs_parser/src/traits.rs b/src/Rust/vvs_parser/src/traits.rs new file mode 100644 index 0000000000000000000000000000000000000000..6567e0e1519460294863d18b34c6bce32aa0c70e --- /dev/null +++ b/src/Rust/vvs_parser/src/traits.rs @@ -0,0 +1,85 @@ +#![allow(dead_code)] + +//! Usefull traits for the vivy parser crate. + +use std::borrow::Cow; + +/// Extensions for the [Result] enum. +pub trait ResultExtension<T, E> { + /// Inspect the value part of the result and transform it with a callback. + fn inspect_mut(self, cb: impl FnOnce(&mut T)) -> Self; + + /// Inspect the error part of the result and transform it with a callback. + fn inspect_err_mut(self, cb: impl FnOnce(&mut E)) -> Self; +} + +impl<T, E> ResultExtension<T, E> for Result<T, E> { + fn inspect_err_mut(mut self, cb: impl FnOnce(&mut E)) -> Self { + if let Err(error) = &mut self { + cb(error); + } + self + } + + fn inspect_mut(mut self, cb: impl FnOnce(&mut T)) -> Self { + if let Ok(value) = &mut self { + cb(value); + } + self + } +} + +/// Extensions for the [Vec] struct. +pub trait VecExtension<T> { + /// Push an item at the end of the vector and returns the result. + fn join(self, value: T) -> Self; + + /// Returns the without the elements as selected by the callback. + fn without(self, cb: impl FnMut(&T) -> bool) -> Self; +} + +impl<T> VecExtension<T> for Vec<T> { + fn join(mut self, value: T) -> Self { + self.push(value); + self + } + + fn without(mut self, cb: impl FnMut(&T) -> bool) -> Self { + self.retain(cb); + self + } +} + +impl<T> VecExtension<T> for std::collections::VecDeque<T> { + fn join(mut self, value: T) -> Self { + self.push_back(value); + self + } + + fn without(mut self, cb: impl FnMut(&T) -> bool) -> Self { + self.retain(cb); + self + } +} + +/// Like [Default], but we get a reference to a static instead. +pub trait DefaultRef { + fn default_ref() -> &'static Self; +} + +/// A string that can be lazy. +pub trait MaybeLazyString { + fn to_str(self) -> Cow<'static, str>; +} + +impl MaybeLazyString for &'static str { + fn to_str(self) -> Cow<'static, str> { + Cow::Borrowed(self) + } +} + +impl<F: FnOnce() -> String> MaybeLazyString for F { + fn to_str(self) -> Cow<'static, str> { + Cow::Owned(self()) + } +} diff --git a/src/Rust/vvs_parser/src/util.rs b/src/Rust/vvs_parser/src/util.rs new file mode 100644 index 0000000000000000000000000000000000000000..cb6059f6a142794ce18d775d9b6bd969a94e495c --- /dev/null +++ b/src/Rust/vvs_parser/src/util.rs @@ -0,0 +1,111 @@ +use crate::{ast::Punctuated, tokenizer::TokenReference}; +use std::{ + borrow::Borrow, + fmt::{Display, Write}, +}; + +// Check if the vector is empty or full of None's +#[allow(clippy::ptr_arg)] +pub fn empty_optional_vector<T>(vec: &Vec<Option<T>>) -> bool { + vec.iter().all(Option::is_none) +} + +pub fn display_option<T: Display, O: Borrow<Option<T>>>(option: O) -> String { + match option.borrow() { + Some(x) => x.to_string(), + None => "".to_string(), + } +} + +pub fn display_optional_punctuated<T: Display>(pair: &(T, Option<TokenReference>)) -> String { + format!("{}{}", pair.0, display_option(&pair.1)) +} + +pub fn display_optional_punctuated_vec<T: Display>(vec: &[(T, Option<TokenReference>)]) -> String { + let mut string = String::new(); + for pair in vec { + string.push_str(&display_optional_punctuated(pair)); + } + string +} + +pub fn join_vec<T: Display, V: AsRef<[T]>>(vec: V) -> String { + let mut string = String::new(); + for item in vec.as_ref() { + string.push_str(&item.to_string()); + } + string +} + +pub fn join_type_specifiers<I: IntoIterator<Item = Option<T2>>, T1: Display, T2: Display>( + parameters: &Punctuated<T1>, + type_specifiers: I, +) -> String { + let mut string = String::new(); + + for (parameter, type_specifier) in parameters + .pairs() + .zip(type_specifiers.into_iter().chain(std::iter::repeat_with(|| None))) + { + let _ = write!( + string, + "{}{}{}", + parameter.value(), + display_option(type_specifier), + display_option(parameter.punctuation()) + ); + } + + string +} + +pub fn join_iterators< + I1: IntoIterator<Item = Option<T2>>, + I2: IntoIterator<Item = Option<T3>>, + T1: Display, + T2: Display, + T3: Display, +>( + parameters: &Punctuated<T1>, + first_iterator: I1, + second_iterator: I2, +) -> String { + let mut string = String::new(); + + for ((name, item1), item2) in parameters + .pairs() + .zip(first_iterator.into_iter()) + .zip(second_iterator.into_iter()) + { + let _ = write!( + string, + "{}{}{}{}", + name.value(), + display_option(item1), + display_option(item2), + display_option(name.punctuation()) + ); + } + + string +} + +#[doc(hidden)] +#[macro_export] +macro_rules! has_version { + ($lua_state:expr,) => { + true + }; + + ($lua_version:expr, $($version:ident,)+) => {{ + paste::paste! { + let mut version_passes = false; + $( + if $lua_version.[<has_ $version>]() { + version_passes = true; + } + )+ + version_passes + }} + }; +} diff --git a/src/Rust/vvs_parser/src/visitors.rs b/src/Rust/vvs_parser/src/visitors.rs new file mode 100644 index 0000000000000000000000000000000000000000..45a88c68047d74dfb748cb282b0d8d576b5fdc88 --- /dev/null +++ b/src/Rust/vvs_parser/src/visitors.rs @@ -0,0 +1,227 @@ +//! Used to create visitors that recurse through [`Ast`](ast::Ast) nodes. + +use crate::{ + ast::*, + private::Sealed, + tokenizer::{Token, TokenReference}, +}; + +macro_rules! create_visitor { + (ast: { + $($visit_name:ident => $ast_type:ident,)+ + }, token: { + $($visit_token:ident,)+ + }) => { + /// A trait that implements functions to listen for specific nodes/tokens. + /// Unlike [`VisitorMut`], nodes/tokens passed are immutable. + pub trait Visitor { + /// Visit the nodes of an [`Ast`](crate::ast::Ast) + fn visit_ast(&mut self, ast: &Ast) where Self: Sized { + ast.nodes().visit(self); + ast.eof().visit(self); + } + + paste::item! { + $( + #[allow(missing_docs)] + fn $visit_name(&mut self, _node: &$ast_type) { } + #[allow(missing_docs)] + fn [<$visit_name _end>](&mut self, _node: &$ast_type) { } + )+ + } + + $( + #[allow(missing_docs)] + fn $visit_token(&mut self, _token: &Token) { } + )+ + } + + /// A trait that implements functions to listen for specific nodes/tokens. + /// Unlike [`Visitor`], nodes/tokens passed are mutable. + pub trait VisitorMut { + /// Visit the nodes of an [`Ast`](crate::ast::Ast) + fn visit_ast(&mut self, ast: Ast) -> Ast where Self: Sized { + // TODO: Visit tokens? + let eof = ast.eof().to_owned(); + let nodes = ast.nodes.visit_mut(self); + + Ast { + nodes, + // Everything gets cloned with this visitor, so there's no original tokens + eof: self.visit_eof(eof), + } + } + + paste::item! { $( + #[allow(missing_docs)] + fn $visit_name(&mut self, node: $ast_type) -> $ast_type { + node + } + + #[allow(missing_docs)] + fn [<$visit_name _end>](&mut self, node: $ast_type) -> $ast_type { + node + } + )+ } + + $( + #[allow(missing_docs)] + fn $visit_token(&mut self, token: Token) -> Token { + token + } + )+ + } + }; +} + +#[doc(hidden)] +pub trait Visit: Sealed { + fn visit<V: Visitor>(&self, visitor: &mut V); +} + +#[doc(hidden)] +pub trait VisitMut: Sealed +where + Self: Sized, +{ + fn visit_mut<V: VisitorMut>(self, visitor: &mut V) -> Self; +} + +impl<T: Visit> Visit for &T { + fn visit<V: Visitor>(&self, visitor: &mut V) { + (**self).visit(visitor); + } +} + +impl<T: Visit> Visit for &mut T { + fn visit<V: Visitor>(&self, visitor: &mut V) { + (**self).visit(visitor); + } +} + +impl<T: Visit> Visit for Vec<T> { + fn visit<V: Visitor>(&self, visitor: &mut V) { + for item in self { + item.visit(visitor); + } + } +} + +impl<T: VisitMut> VisitMut for Vec<T> { + fn visit_mut<V: VisitorMut>(self, visitor: &mut V) -> Self { + self.into_iter().map(|item| item.visit_mut(visitor)).collect() + } +} + +impl<T: Visit> Visit for Option<T> { + fn visit<V: Visitor>(&self, visitor: &mut V) { + if let Some(item) = self { + item.visit(visitor); + } + } +} + +impl<T: VisitMut> VisitMut for Option<T> { + fn visit_mut<V: VisitorMut>(self, visitor: &mut V) -> Self { + self.map(|item| item.visit_mut(visitor)) + } +} + +impl<A: Visit, B: Visit> Visit for (A, B) { + fn visit<V: Visitor>(&self, visitor: &mut V) { + self.0.visit(visitor); + self.1.visit(visitor); + } +} + +impl<A: VisitMut, B: VisitMut> VisitMut for (A, B) { + fn visit_mut<V: VisitorMut>(self, visitor: &mut V) -> Self { + (self.0.visit_mut(visitor), self.1.visit_mut(visitor)) + } +} + +impl<T: Visit> Visit for Box<T> { + fn visit<V: Visitor>(&self, visitor: &mut V) { + (**self).visit(visitor); + } +} + +impl<T: VisitMut> VisitMut for Box<T> { + fn visit_mut<V: VisitorMut>(self, visitor: &mut V) -> Self { + Box::new((*self).visit_mut(visitor)) + } +} + +create_visitor!(ast: { + visit_anonymous_call => FunctionArgs, + visit_assignment => Assignment, + visit_block => Block, + visit_call => Call, + visit_contained_span => ContainedSpan, + visit_do => Do, + visit_else_if => ElseIf, + visit_eof => TokenReference, + visit_expression => Expression, + visit_field => Field, + visit_function_args => FunctionArgs, + visit_function_body => FunctionBody, + visit_function_call => FunctionCall, + visit_function_declaration => FunctionDeclaration, + visit_function_name => FunctionName, + visit_generic_for => GenericFor, + visit_if => If, + visit_index => Index, + visit_local_assignment => LocalAssignment, + visit_local_function => LocalFunction, + visit_last_stmt => LastStmt, + visit_method_call => MethodCall, + visit_numeric_for => NumericFor, + visit_parameter => Parameter, + visit_prefix => Prefix, + visit_return => Return, + visit_repeat => Repeat, + visit_stmt => Stmt, + visit_suffix => Suffix, + visit_table_constructor => TableConstructor, + visit_token_reference => TokenReference, + visit_un_op => UnOp, + visit_var => Var, + visit_var_expression => VarExpression, + visit_while => While, + visit_compound_assignment => CompoundAssignment, + visit_compound_op => CompoundOp, + visit_else_if_expression => ElseIfExpression, + visit_if_expression => IfExpression, + + // Types + visit_type_argument => TypeArgument, + visit_type_assertion => TypeAssertion, + visit_type_declaration => TypeDeclaration, + visit_type_field => TypeField, + visit_type_field_key => TypeFieldKey, + visit_type_info => TypeInfo, + visit_type_specifier => TypeSpecifier, + + // Lua >=5.2 + visit_attribute => Attribute, + + // Vivy + visit_main => Main, + visit_write => Write, + visit_yield => Yield, + visit_import => Import, + visit_call_list => CallList, + visit_option_decl => OptionDecl, + visit_call_list_item => CallListItem, + visit_main_assignement => MainAssignement, +}, token: { + visit_identifier, + visit_multi_line_comment, + visit_number, + visit_single_line_comment, + visit_string_literal, + visit_symbol, + visit_token, + visit_whitespace, + visit_interpolated_string_segment, +}); diff --git a/src/Rust/vvs_parser/src/vivy/error_report.rs b/src/Rust/vvs_parser/src/vivy/error_report.rs new file mode 100644 index 0000000000000000000000000000000000000000..1ddc23d0fc5f9211caf6e8c611fc8ba206ecbe8b --- /dev/null +++ b/src/Rust/vvs_parser/src/vivy/error_report.rs @@ -0,0 +1,126 @@ +use crate::Error; +use codespan_reporting::{ + diagnostic::{Diagnostic, Label}, + files::SimpleFiles, + term::{Chars, DisplayStyle}, +}; +use derive_more::Display; +use hashbrown::HashMap; +use std::{mem, str}; +use termcolor::ColorChoice; + +/// Utility to report error to the user. +pub struct ErrorReport<'a> { + /// The list of parsed files. + files: SimpleFiles<&'a str, &'a str>, + + /// We cache the ID, so that we can call the [ErrorReport::add_error] and + /// [ErrorReport::add_warning] multiple times on the same file. + id_cache: HashMap<&'a str, usize>, + + /// The list of [Error], can be errors or warnings depending on their [ErrorReportType]. + messages: HashMap<usize, Vec<(ErrorReportType, Error)>>, +} + +#[derive(Clone, Copy, PartialEq, Eq, Display)] +enum ErrorReportType { + #[display("error")] + Error, + + #[display("warning")] + Warning, +} + +impl<'a> ErrorReport<'a> { + /// Create a new error report. + pub fn new() -> Self { + Default::default() + } + + fn add<I, T>(&mut self, name: &'a str, src: &'a str, ty: ErrorReportType, iter: I) -> &mut Self + where + I: IntoIterator<Item = T>, + T: Into<Error>, + { + let file_id = self.id_cache.entry(name).or_insert_with(|| self.files.add(name, src)); + self.messages + .entry(*file_id) + .or_default() + .extend(iter.into_iter().map(|error| (ty, error.into()))); + self + } + + /// Add errors to the report. + pub fn add_errors<I, T>(&mut self, name: &'a str, source: &'a str, errors: I) -> &mut Self + where + I: IntoIterator<Item = T>, + T: Into<Error>, + { + self.add(name, source, ErrorReportType::Error, errors) + } + + /// Add warnings to the report. + pub fn add_warnings<I, T>(&mut self, name: &'a str, source: &'a str, errors: I) -> &mut Self + where + I: IntoIterator<Item = T>, + T: Into<Error>, + { + self.add(name, source, ErrorReportType::Warning, errors) + } + + /// Report all the stored errors. Returns true if the report contained any error. Return false + /// if the report was empty or contained only warnings. Note that this operation will empty the + /// report struct. + pub fn report(&mut self) -> bool { + if self.messages.is_empty() { + return false; + } + + let Self { files, messages, .. } = mem::take(self); + let mut output = termcolor::StandardStream::stdout(ColorChoice::Auto); + let config = codespan_reporting::term::Config { + display_style: DisplayStyle::Rich, + chars: Chars::box_drawing(), + ..Default::default() + }; + + messages.into_iter().fold(false, |acc, (file_id, messages)| { + messages.iter().fold(false, |acc, (report_type, message)| { + let diagnostic = match report_type { + ErrorReportType::Error => Diagnostic::error(), + ErrorReportType::Warning => Diagnostic::warning(), + } + .with_message(message.error_message()) + .with_code(message.error_code()) + .with_labels(vec![Label::primary(file_id, message.byte_range())]); + + codespan_reporting::term::emit(&mut output, &config, &files, &diagnostic).is_err() + || (*report_type == ErrorReportType::Error || acc) + }) || acc + }) + } + + /// Report all stored errors and warnings, but don't say if any error was actually reported. + /// Like [ErrorReport::report], this operation will empty the report. + pub fn report_and_ignore(&mut self) { + self.report(); + } +} + +impl ErrorReport<'_> { + /// Reports a single error + pub fn error(name: &'_ str, source: &'_ str, error: impl Into<Error>) { + ErrorReport::new().add_errors(name, source, [error.into()]).report(); + } + + /// Reports a single warning + pub fn warning(name: &'_ str, source: &'_ str, warning: impl Into<Error>) { + ErrorReport::new().add_warnings(name, source, [warning.into()]).report(); + } +} + +impl<'a> Default for ErrorReport<'a> { + fn default() -> Self { + Self { files: SimpleFiles::new(), messages: Default::default(), id_cache: Default::default() } + } +} diff --git a/src/Rust/vvs_parser/src/vivy/frontend_pipeline.rs b/src/Rust/vvs_parser/src/vivy/frontend_pipeline.rs new file mode 100644 index 0000000000000000000000000000000000000000..53bc5d77bf182921be794636546e8a6e68e3b9b3 --- /dev/null +++ b/src/Rust/vvs_parser/src/vivy/frontend_pipeline.rs @@ -0,0 +1,327 @@ +//! Contains the main code for the compiler. The compiler parses and do checks on the code, do some +//! optimisations and then returns the [ast::Ast] if no errors where found. + +use crate::{ + ast::*, + tokenizer::TokenReference, + traits::VecExtension as _, + vivy::{ + error_report::ErrorReport, + library::Library, + passes::*, + search_path::{SearchPath, DEFAULT_SEARCH_PATH}, + symbol_table::SymbolTable, + *, + }, + ShortString, +}; +use derive_more::Display; +use hashbrown::{HashMap, HashSet}; +use std::{borrow::Cow, cell::RefCell, fmt, fs, mem, path::Path, rc::Rc}; + +/// Process a program. +pub struct FrontendPipeline<'a> { + /// Options from a possibly passed file to the compiler. + options: Option<Rc<OptionTable>>, + + /// The content of the program / main module. + program: Cow<'a, str>, + + /// List of imported modules. + imports: HashMap<ShortString, Rc<(Ast, Cow<'static, str>)>>, + + /// List of imported symbol tables. + symbols: Vec<Rc<SymbolTable<'a, TypeInfo>>>, + + /// The search path. + search: &'a SearchPath, + + /// Is the current module being compiled the main module? + is_main: bool, + + /// The include path, upper in the vector is the modules importing the ones down in the vector. + process_path: Vec<ShortString>, + + /// The library of available types. + library: Rc<RefCell<Library>>, + + /// List of user defined passes. Will be run in order after we are done with our own passes. + passes: &'a [&'a dyn UserFrontendPass], +} + +/// Record of all the options defined, unused, setted in the program. +pub struct OptionsRecord { + /// List of all unused declared options. + unused_options: Vec<(ShortString, ShortString)>, + + /// All setted options. + setted_options: Vec<(ShortString, ShortString, Expression)>, + + /// All declared options. + declared_options: Vec<(ShortString, ShortString, Expression)>, +} + +impl fmt::Display for OptionsRecord { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let Self { setted_options, .. } = self; + match setted_options.iter().map(|(a, b, _)| a.len() + b.len()).max() { + None | Some(0) => Ok(()), + Some(len) => setted_options.iter().try_for_each(|(module, name, expression)| { + writeln!(f, "{module}.{name: >len$} {expression}", len = len - module.len()) + }), + } + } +} + +/// Result of the front-end. Don't show that directly to the user, will show [FrontendOutput]. +struct CompilerResult { + /// The [Ast] of the main program's module. + ast: Ast, + + /// List of all imported modules' [Ast] + imports: HashMap<ShortString, Rc<(Ast, Cow<'static, str>)>>, + + /// The main program. + main: MainProgram, + + /// Record of all options in the program. + options: OptionsRecord, + + /// All the defined types. + library: Rc<RefCell<Library>>, +} + +/// The result of the frontend. +pub struct FrontendOutput { + /// The [Ast] of the main program's module. + pub ast: Ast, + + /// List of all imported modules' [Ast] + pub imports: HashMap<ShortString, Ast>, + + /// The main program. + pub main: MainProgram, + + /// Record of all options in the program. + pub options: OptionsRecord, + + /// All the defined types. + pub library: Library, +} + +impl From<CompilerResult> for FrontendOutput { + fn from(value: CompilerResult) -> Self { + let CompilerResult { ast, imports, main, options, library } = value; + let library = RefCell::into_inner(Rc::into_inner(library).expect("unique owner")); + let imports = HashMap::from_iter( + imports + .into_iter() + .map(|(module, ptr)| (module, Rc::into_inner(ptr).expect("unique owner").0)), + ); + Self { ast, main, options, imports, library } + } +} + +impl fmt::Display for FrontendOutput { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let Self { imports, main, options, library, .. } = self; + write!(f, "imported modules: ")?; + imports.keys().try_for_each(|module| write!(f, "{module} "))?; + writeln!(f)?; + + writeln!(f, "{options}")?; + writeln!(f, "{library}")?; + writeln!(f, "{main:#?}") + } +} + +/// Tells if the frontend failed or not. +#[derive(Debug, Display, Clone, Copy)] +#[display("frontend error")] +pub struct FrontendError; + +impl std::error::Error for FrontendError {} + +impl From<()> for FrontendError { + fn from(_: ()) -> Self { + Self {} + } +} + +#[derive(Default)] +struct ImportAllResult { + declared_options: Vec<(ShortString, ShortString, Expression)>, + unused: Vec<(ShortString, ShortString)>, +} + +impl FromIterator<ImportAllResult> for ImportAllResult { + fn from_iter<T: IntoIterator<Item = ImportAllResult>>(iter: T) -> Self { + let mut iter = iter.into_iter(); + let Some(ret) = iter.next() else { + return Default::default(); + }; + iter.fold(ret, |mut ret, item| { + let Self { mut declared_options, unused } = item; + ret.declared_options.append(&mut declared_options); + ret.unused.retain(|option| unused.contains(option)); + ret + }) + } +} + +impl<'a> FrontendPipeline<'a> { + /// Create a new pipeline to parse, to check and do black magic. + pub fn new(SourceCode { name, code }: &'a SourceCode) -> Self { + Self { + program: Cow::Borrowed(code.as_ref()), + options: None, + imports: Default::default(), + symbols: vec![], + is_main: true, + search: &DEFAULT_SEARCH_PATH, + process_path: vec![ShortString::new(name.as_ref())], + library: Rc::new(RefCell::new(Library::default())), + passes: &[], + } + } + + /// Add passes to do for each module at the end of mendatory passes. + pub fn passes(self, passes: &'a [&'a dyn UserFrontendPass]) -> Self { + Self { passes, ..self } + } + + /// Get the name of the module we are compiling here. We should always have a name, if we parse + /// the stdin we still have a name for the module: stdin... + pub fn name(&self) -> &ShortString { + self.process_path.last().expect("module name") + } + + /// Set the option file to use for this instance of the program. + pub fn options(self, options: Option<impl AsRef<Path>>) -> Result<Self, FrontendError> { + let Some(options) = options else { return Ok(self) }; + let options = options.as_ref(); + + let name = options + .file_name() + .ok_or_else(|| log::error!("expected a file with an actual name"))? + .to_str() + .ok_or_else(|| log::error!("expected files with utf8 names"))?; + + let code = fs::read_to_string(options) + .map_err(|err| log::error!("failed to read option file '{}': {err}", options.display()))?; + + Ok(crate::ast::OptionTableResult::parse_fallible(&code) + .into_result() + .map(|options| Self { options: Some(Rc::new(options)), ..self }) + .map_err(|errors| ErrorReport::new().add_errors(name, &code, errors).report_and_ignore())?) + } + + /// Set the [SearchPath] to use for this instance of the program. + pub fn search(self, search: &'a SearchPath) -> Self { + Self { search, ..self } + } + + /// Import all modules from the given list and add them to the current pipeline. + fn import_all(&mut self, import_list: Vec<TokenReference>) -> Result<ImportAllResult, FrontendError> { + Iterator::collect(import_list.into_iter().map(|import| { + let name = import.token_type().as_str(); + if self.imports.contains_key(name) { + return Ok(ImportAllResult::default()); + } else if self.process_path.iter().any(|path| path.as_str() == name) { + ErrorReport::error( + self.name(), + &self.program, + AstError::from_parts(import.clone(), "recursive indlude of module"), + ); + return Err(FrontendError); + } + + let program = self.search.resolve(name).ok_or_else(|| { + ErrorReport::error( + self.name(), + &self.program, + AstError::from_parts(import.clone(), "failed to find the module to import"), + ) + })?; + + let CompilerResult { + ast, imports, options: OptionsRecord { unused_options, declared_options, .. }, .. + } = FrontendPipeline { + process_path: self.process_path.clone().join(ShortString::new(name)), + imports: mem::take(&mut self.imports), // Will be replaced. + program: match program { + Cow::Borrowed(program) => Cow::Borrowed(program), + Cow::Owned(ref program) => Cow::Borrowed(program.as_str()), + }, + options: self.options.clone(), + symbols: self.symbols.clone(), + library: self.library.clone(), + is_main: false, + ..*self + } + .process()?; + + debug_assert!({ + let prev = HashSet::<&ShortString>::from_iter(self.imports.keys()); + let news = HashSet::<&ShortString>::from_iter(imports.keys()); + (prev.len() <= news.len()) && (prev.intersection(&news).count() == prev.len()) + }); + let _ = mem::replace(&mut self.imports, imports); // Replace with a more complete import list. + self.imports.insert(ShortString::new(name), Rc::new((ast, program))); + + Ok(ImportAllResult { declared_options, unused: unused_options }) + })) + } + + /// Process the pipeline. Some returned values may be hidden from the user, or things + /// transformed a but more for the main result, but here we keep them. + fn process(mut self) -> Result<CompilerResult, FrontendError> { + let ast = AstResult::parse_fallible(&self.program).into_result().map_err(|err| { + let _ = ErrorReport::new().add_errors(self.name(), &self.program, err).report(); + })?; + + let (ast, StmtCheckerResult { decl_opts, setd_opts, main, imported }) = + StmtChecker::new(ast, (self.name().as_str(), self.program.as_ref())) + .is_main(self.is_main) + .process()?; + let ImportAllResult { mut declared_options, unused } = self.import_all(imported)?; + + declared_options.extend( + decl_opts + .into_iter() + .map(|(name, value)| (self.name().clone(), name, value.into())), + ); + + let symbols = SymbolTable::new(&ast, self.options.as_deref()) + .import(self.symbols.iter().map(Rc::as_ref)) + .take(); + + let loc = (self.name().as_str(), self.program.as_ref()); + let (ast, _) = TypeCollector::new(ast, loc, &mut self.library.borrow_mut()).process()?; + let (ast, _) = TypeChecker::new(ast, loc, &self.library.borrow(), symbols.sub_scope()).process()?; + let (ast, OptsTransformResult { unused }) = match self.options.clone() { + None => (ast, Default::default()), + Some(options) => { + let (ast, results) = OptsTransform::new(ast, loc, &options).process()?; + (ast, OptsTransformResult { unused: results.unused.without(|opt| unused.contains(opt)) }) + } + }; + + Ok(CompilerResult { + ast: self.passes.iter().try_fold(ast, |prog, pass| { + log::debug!("apply pass {} on module {}", pass.name(), self.name()); + pass.process(prog, self.name(), self.program.as_ref()) + })?, + imports: self.imports, + options: OptionsRecord { declared_options, setted_options: setd_opts, unused_options: unused }, + library: self.library.clone(), + main: main.unwrap_or_default(), + }) + } + + /// Process the pipeline. Returns the [Ast] or an error. Note that if an error occured, they + /// will be printed out to the terminal. + pub fn run(self) -> Result<FrontendOutput, FrontendError> { + self.process().map(Into::into) + } +} diff --git a/src/Rust/vvs_parser/src/vivy/library.rs b/src/Rust/vvs_parser/src/vivy/library.rs new file mode 100644 index 0000000000000000000000000000000000000000..95d15e5fda3e38fd8201408661bce30db20f1e4e --- /dev/null +++ b/src/Rust/vvs_parser/src/vivy/library.rs @@ -0,0 +1,333 @@ +//! Store informations about methods and fields for types. + +use crate::{ast::TypeInfo, ShortString}; +use derive_more::{Display, IntoIterator, IsVariant}; +use hashbrown::HashMap; +use std::{fmt, sync::LazyLock}; + +/// Tells whether a field is mutable or constant. +#[derive(PartialEq, Eq, Clone, Copy, Debug, IsVariant)] +pub enum FieldMutability { + /// The field can be mutated by a user. + Mutable, + + /// The field can't be mutated by a user and can represent an internal variant of the variable. + Constant, +} + +/// Informations about a field of a [TypeRecord]. +#[derive(PartialEq, Clone, Copy)] +pub struct TypeRecordField<'a>(pub FieldMutability, pub &'a TypeInfo); + +/// Informations about a method of a [TypeRecord]. +#[derive(PartialEq, Clone, Copy)] +pub struct TypeRecordMethod<'a>(pub &'a [TypeInfo], pub &'a TypeInfo, pub bool); + +impl TypeRecordMethod<'_> { + /// Tells whether the method is really a method or just a free function. + pub fn is_method(&self) -> bool { + let TypeRecordMethod(_, _, is_method) = self; + *is_method + } +} + +/// A record stores informations about a type, the fields and the methods. +#[derive(Clone)] +pub struct TypeRecord { + type_info: TypeInfo, + is_std: bool, + fields: HashMap<ShortString, (FieldMutability, TypeInfo)>, + methods: HashMap<ShortString, (Vec<TypeInfo>, TypeInfo)>, +} + +static STANDARD_RECORDS: LazyLock<Vec<TypeRecord>> = LazyLock::new(|| { + macro_rules! records { + ($( struct $ty: ident $struct: tt impl $methods: tt )*) => { Vec::from_iter([$(records!(@ $ty $struct $methods)),*]) }; + (@ $type: ident $fields: tt { $($(fn $method: ident ($($arg: ident),*) -> $ret: ident;)+)? }) => { + std::mem::take(records!(@ TypeRecord::new_std(TypeInfo::$type().clone()), $fields) + $(.with_methods([ + $((ShortString::new(stringify!($method)), vec![$(TypeInfo::$arg().clone()),*], TypeInfo::$ret().clone())),* + ]))? + ) + }; + (@ $a: expr, const $f: ident : $fty: ident ) => { $a.with_field(stringify!($f).into(), FieldMutability::Constant, TypeInfo::$fty().clone()) }; + (@ $a: expr, mut $f: ident : $fty: ident ) => { $a.with_field(stringify!($f).into(), FieldMutability::Mutable, TypeInfo::$fty().clone()) }; + (@ $acc: expr, {}) => { $acc }; + (@ $acc: expr, { $v: tt $f: ident : $fty: ident $(, $vs: tt $fs: ident : $ftys: ident)* $(,)? }) => { + records!(@ records!(@ $acc, $v $f: $fty), { $($vs $fs: $ftys),* }) + }; + } + + records! { + struct number {} impl { + fn is_nan() -> number; + fn is_zero() -> number; + fn is_true() -> number; + fn is_false() -> number; + fn floor() -> number; + fn ceil() -> number; + } + + struct string {} impl { + fn new() -> string; + fn put(char) -> string; + fn append(string) -> string; + + fn len() -> number; + fn get(number) -> char; + + fn is_lowercase() -> number; + fn is_uppercase() -> number; + fn to_lowercase() -> string; + fn to_uppercase() -> string; + } + + struct char {} impl { + fn is_lowercase() -> number; + fn is_uppercase() -> number; + fn to_lowercase() -> char; + fn to_uppercase() -> char; + } + + struct table {} impl { + fn new() -> table; + fn len() -> number; + fn get(any) -> any; + fn set(any, any) -> nil; + } + + struct any {} impl { + fn new() -> any; + + fn to_string() -> string; + fn to_number() -> number; + fn to_table() -> table; + } + + struct line { + const index: number, // Index of the line in the original document. + mut start: number, // Start time of the line. + mut end: number, // End time of the line. + } impl { + fn len() -> number; + fn syllabe(number) -> syllabe; + fn syllabes() -> syllabes; + } + + struct lines {} impl { + fn len() -> number; + fn line(number) -> line; + fn syllabes() -> syllabes; + } + + struct syllabes {} impl { + fn len() -> number; + fn syllabe(number) -> syllabe; + } + + struct syllabe { + const index: number, // Index in the parent line. + mut start: number, // Start time of the syllabe. + mut end: number, // End time of the syllabe. + } impl { + fn len() -> number; + fn text() -> string; + fn get(number) -> char; + } + } +}); + +impl TypeRecord { + /// Create a new type record. + pub fn new(type_info: TypeInfo) -> Self { + Self { type_info, is_std: false, ..Default::default() } + } + + /// Create a new standard type record. + fn new_std(type_info: TypeInfo) -> Self { + Self { type_info, is_std: true, ..Default::default() } + } + + /// Add or override a field in the record. + pub fn with_field(&mut self, field: ShortString, mutability: FieldMutability, type_info: TypeInfo) -> &mut Self { + self.fields.insert(field, (mutability, type_info)); + self + } + + /// Add or override a method in the record. + pub fn with_method(&mut self, method: ShortString, arguments: Vec<TypeInfo>, returns: TypeInfo) -> &mut Self { + self.methods.insert(method, (arguments, returns)); + self + } + + /// Add or override fields in the record. + pub fn with_fields( + &mut self, + iter: impl IntoIterator<Item = (ShortString, FieldMutability, TypeInfo)>, + ) -> &mut Self { + iter.into_iter().fold(self, |s, (k, m, t)| s.with_field(k, m, t)) + } + + /// Add or override methods in the record. + pub fn with_methods( + &mut self, + iter: impl IntoIterator<Item = (ShortString, Vec<TypeInfo>, TypeInfo)>, + ) -> &mut Self { + iter.into_iter().fold(self, |s, (k, m, t)| s.with_method(k, m, t)) + } + + /// Get the fields of instances of this type. + pub fn fields(&self) -> impl Iterator<Item = (&ShortString, TypeRecordField)> { + self.fields + .iter() + .map(|(field, (mutability, type_info))| (field, TypeRecordField(*mutability, type_info))) + } + + /// Get the methods of instances of this type. + pub fn methods(&self) -> impl Iterator<Item = (&ShortString, TypeRecordMethod)> { + self.methods.iter().map(|(method, (args, returns))| { + (method, TypeRecordMethod(args, returns, args.first().map(|_| todo!()).unwrap_or_default())) + }) + } + + /// Get a field's informations if it exists, otherwise get [None]. + pub fn field(&self, field: impl AsRef<str>) -> Option<TypeRecordField> { + self.fields + .get(field.as_ref()) + .map(|(mutability, type_info)| TypeRecordField(*mutability, type_info)) + } + + /// Get a method's informations if it exists, otherwise get [None]. + pub fn method(&self, method: impl AsRef<str>) -> Option<TypeRecordMethod> { + self.methods + .get(method.as_ref()) + .map(|(args, returns)| TypeRecordMethod(args, returns, args.first().map(|_| todo!()).unwrap_or_default())) + } + + /// Get the [TypeInfo] of this record. + pub fn type_info(&self) -> &TypeInfo { + &self.type_info + } +} + +impl Default for TypeRecord { + fn default() -> Self { + Self { is_std: true, type_info: Default::default(), fields: Default::default(), methods: Default::default() } + } +} + +impl fmt::Display for TypeRecord { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let this = self.type_info(); + let std_comment = match self.is_std { + true => "--[[ std! ]]", + false => "", + }; + writeln!(f, "struct {std_comment} {this} {{")?; + self.fields() + .try_for_each(|(name, TypeRecordField(mutability, type_info))| { + let mutability = (mutability == FieldMutability::Mutable) + .then_some("mut ") + .unwrap_or_default(); + writeln!(f, "\t{mutability} {name}: {type_info},") + })?; + writeln!(f, "}}")?; + + self.methods() + .try_for_each(|(name, func @ TypeRecordMethod(args, ret, ..))| { + write!(f, "function {this}:{name}(")?; + if func.is_method() && !args.is_empty() { + write!(f, "{this},")?; + } else if func.is_method() { + write!(f, "{this}")?; + } + args.iter().enumerate().try_for_each(|(idx, arg)| match idx { + 0 => write!(f, "{arg}"), + _ => write!(f, ", {arg}"), + })?; + writeln!(f, ") -> {ret};") + }) + } +} + +/// Stores all the knowned [TypeRecord] for a program. Can differentiate between standard type +/// records and users' type records. +#[derive(IntoIterator)] +pub struct Library(Vec<TypeRecord>); + +impl Library { + /// Create a new library. + pub fn new() -> Self { + Self::from_iter(STANDARD_RECORDS.iter()) + } + + /// Iterate throu the records. + pub fn iter(&self) -> impl Iterator<Item = &TypeRecord> { + self.0.iter() + } + + /// Iterate throu the records in a mutable way. Not that you can only mutate non-standard + /// types' record. + pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut TypeRecord> { + self.0.iter_mut().filter(|TypeRecord { is_std, .. }| !*is_std) + } + + /// Tells wether a specific record for a type name is present or not. + pub fn has(&self, name: impl AsRef<str>) -> bool { + self.get(name).is_some() + } + + /// Get the record for a type name, if not present returns a newly created record. + pub fn get(&self, name: impl AsRef<str>) -> Option<&TypeRecord> { + self.iter().find(|TypeRecord { type_info, .. }| match type_info { + TypeInfo::Basic(type_info) => type_info.token_type().as_str() == name.as_ref(), + _ => false, + }) + } + + /// Get the record for a type name in a mutable way, if not present returns [None]. If the + /// record is from standard type, also returns [None]. + pub fn get_mut(&mut self, name: impl AsRef<str>) -> Option<&mut TypeRecord> { + self.iter_mut().find(|TypeRecord { type_info, .. }| match type_info { + TypeInfo::Basic(type_info) => type_info.token_type().as_str() == name.as_ref(), + _ => false, + }) + } + + /// Set a type record for a type. If the record is already present, replace it. If the already + /// present record is of a standard type, it won't be replaced. + pub fn put(&mut self, record: TypeRecord) { + let find = |(idx, TypeRecord { type_info, is_std, .. }): (_, &_)| { + (*type_info == record.type_info).then_some((idx, *is_std)) + }; + match self.0.iter().enumerate().find_map(find) { + Some((_, true)) => {} + Some((idx, false)) => self.0[idx] = record, + None => self.0.push(record), + } + } +} + +impl FromIterator<TypeRecord> for Library { + fn from_iter<T: IntoIterator<Item = TypeRecord>>(iter: T) -> Self { + Self(iter.into_iter().collect()) + } +} + +impl<'a> FromIterator<&'a TypeRecord> for Library { + fn from_iter<T: IntoIterator<Item = &'a TypeRecord>>(iter: T) -> Self { + Self(iter.into_iter().cloned().collect()) + } +} + +impl Default for Library { + fn default() -> Self { + Self::new() + } +} + +impl fmt::Display for Library { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.iter().try_for_each(|record| write!(f, "{record}")) + } +} diff --git a/src/Rust/vvs_parser/src/vivy/main_program.rs b/src/Rust/vvs_parser/src/vivy/main_program.rs new file mode 100644 index 0000000000000000000000000000000000000000..54ddd0901346a4683025dc7cf8e70dd3740526be --- /dev/null +++ b/src/Rust/vvs_parser/src/vivy/main_program.rs @@ -0,0 +1,120 @@ +//! Main program and utilities to be able to complete the work. + +use crate::{ast::Expression, ShortString}; +use derive_more::{IntoIterator, IsVariant}; + +/// The main program to execute in the parsed script. +#[derive(Default, Debug)] +pub struct MainProgram { + /// The initial variable name of the read ASS file. + pub initial: ShortString, + + /// Steps to do, in order, to make the program progress. + pub steps: Vec<MainProgramStep>, + + /// The variables to write at the end of the program. + pub returns: MainProgramReturns, +} + +impl MainProgram { + /// Set the initial variable name. + pub fn with_initial(self, initial: ShortString) -> Self { + Self { initial, ..self } + } + + /// Set the steps for the main program. + pub fn with_steps(self, steps: Vec<MainProgramStep>) -> Self { + Self { steps, ..self } + } + + /// Set the returned variables + pub fn with_returns(self, returns: impl IntoIterator<Item = ShortString>) -> Self { + Self { returns: returns.into_iter().collect(), ..self } + } +} + +/// The returned variables from the main program. +#[derive(Debug, Default, IntoIterator)] +pub struct MainProgramReturns { + #[into_iterator(owned)] + variables: Vec<ShortString>, +} + +impl FromIterator<ShortString> for MainProgramReturns { + fn from_iter<T: IntoIterator<Item = ShortString>>(iter: T) -> Self { + Self { variables: iter.into_iter().collect() } + } +} + +/// A step to do for the main program. +#[derive(Debug)] +pub struct MainProgramStep { + /// The name of the assignated variable. + destination: ShortString, + + /// The name of the job with its source module, in this order: `(module, job)`. + job: (ShortString, ShortString), + + /// The arguments to pass to the job, the variables to read (and possibly rearange), and the + /// parameters to set. + call_list: Vec<MainProgramCallListItem>, +} + +impl MainProgramStep { + /// Create a new program step. + pub fn new( + destination: ShortString, + job: (ShortString, ShortString), + call_list: impl IntoIterator<Item = MainProgramCallListItem>, + ) -> Self { + Self { destination, job, call_list: call_list.into_iter().collect() } + } + + /// Get the name of the variable to write the result of the job into. + pub fn destination(&self) -> &ShortString { + &self.destination + } + + /// Get the name of the source module where to find the job we are trying to call. + pub fn module(&self) -> &ShortString { + &self.job.0 + } + + /// Get the name of the job we are trying to call. + pub fn job(&self) -> &ShortString { + &self.job.1 + } + + /// Get the arguments of the job. + pub fn call_list_items(&self) -> impl Iterator<Item = &MainProgramCallListItem> { + self.call_list.iter() + } +} + +/// An item to pass to a job when we call it. +#[derive(Debug, IsVariant)] +pub enum MainProgramCallListItem { + /// We add a variable to process. + Variable(ShortString), + + /// We set a parameter for the job. + Parameter(ShortString, Expression), +} + +impl MainProgramCallListItem { + /// Treat the call list item as a variable if possible. + pub fn as_variable(&self) -> Option<&ShortString> { + match self { + MainProgramCallListItem::Variable(variable) => Some(variable), + _ => None, + } + } + + /// Treat the call list item as a parameter setting if possible. + pub fn as_parameter(&self) -> Option<(&ShortString, &Expression)> { + match self { + MainProgramCallListItem::Parameter(argument, value) => Some((argument, value)), + _ => None, + } + } +} diff --git a/src/Rust/vvs_parser/src/vivy/mod.rs b/src/Rust/vvs_parser/src/vivy/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..e28ae6ec611852cbc4a5fc6e4569a2e9ed28ecf0 --- /dev/null +++ b/src/Rust/vvs_parser/src/vivy/mod.rs @@ -0,0 +1,45 @@ +//! Vivy specific logic + +mod error_report; +mod frontend_pipeline; +mod library; +mod main_program; +mod passes; +mod search_path; +mod symbol_table; + +use std::{borrow::Cow, fs, io, path::Path}; + +pub use self::{error_report::ErrorReport, frontend_pipeline::*, main_program::*, passes::UserFrontendPass}; + +/// The representation of a source file. +pub struct SourceCode { + name: Cow<'static, str>, + code: Cow<'static, str>, +} + +impl SourceCode { + /// Create a new source file from a file. + pub fn from_path(path: impl AsRef<Path>) -> io::Result<Self> { + Ok(Self { + name: Cow::Owned( + path.as_ref() + .file_name() + .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "path doesn't have a file name"))? + .to_string_lossy() + .to_string(), + ), + code: Cow::Owned(fs::read_to_string(path.as_ref())?), + }) + } + + /// Create a new source file from memory. + pub fn from_memory(code: Cow<'static, str>) -> Self { + Self { name: Cow::Borrowed("--"), code } + } + + /// Get the name of the source file. + pub fn name(&self) -> &str { + &self.name + } +} diff --git a/src/Rust/vvs_parser/src/vivy/passes/mod.rs b/src/Rust/vvs_parser/src/vivy/passes/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..6c6f8e65044f33f3832a102c727ceadebf32045d --- /dev/null +++ b/src/Rust/vvs_parser/src/vivy/passes/mod.rs @@ -0,0 +1,141 @@ +//! Passes to verify and transform the Vivy Script code written by an user. + +mod opts_transform; +mod stmt_checker; +mod type_checker; +mod type_collector; + +pub use self::{opts_transform::*, stmt_checker::*, type_checker::*, type_collector::*}; + +/// Macro used to declare a pass, can be a transform pass or a visit pass (for the role). +/// ```ignore +/// declare_pass! { +/// transform::OptsTransform +/// aux_infos { options: toml::Table } +/// opt_infos { verbose: u8 } +/// results { replaced_count: usize, unused_options: Vec<String> } +/// }; +/// impl VisitorMut for OptsTransform {} +/// ``` +#[macro_export] +macro_rules! declare_pass { + ( + $(#[$meta: meta])* + $role: ident :: $name: ident : $lifetime: lifetime { + $($field_attr: ident : $field_ty: ty),* $(,)? + } + + $(aux_infos { $($info_attr: ident : $info_ty: ty),+$(,)? })? + $(opt_infos { $($opts_attr: ident : $opts_ty: ty),+$(,)? })? + $(results { $($res_attr: ident : $res_ty: ty),+$(,)? })? + ) => { + $(#[$meta])* + pub struct $name <$lifetime> { + program: Option<$crate::ast::Ast>, + name: &$lifetime str, + source: &$lifetime str, + report: $crate::vivy::error_report::ErrorReport<$lifetime>, + $( $field_attr: $field_ty,)* + $($($info_attr: $info_ty),+,)? + $($($opts_attr: Option<$opts_ty>),+,)? + $($($res_attr: $res_ty),+,)? + } + + paste::paste! { + #[doc = "The resut structure for the [" $name "] pass."] + #[derive(Default)] + pub struct [< $name Result >] { + $($(pub $res_attr: $res_ty),+)? + } + } + + impl <$lifetime> $name <$lifetime> { + paste::paste! { + #[doc = "Create a new [" $name "] pass."] + pub fn new( + program: $crate::ast::Ast, + (name, source): (&$lifetime str, &$lifetime str) + $($(, $info_attr: $info_ty)+)? + ) -> Self { + Self { + program: Some(program), name, source, + report: $crate::vivy::error_report::ErrorReport::new(), + $($($info_attr),+,)? + $( $field_attr: Default::default(),)* + $($($opts_attr: None),+,)? + $($($res_attr: Default::default()),+,)? + } + } + + /// Add a new ast error to the error list. + #[allow(dead_code)] + fn error(&mut self, token: impl Into<$crate::tokenizer::TokenReference>, error: impl Into<std::borrow::Cow<'static, str>>) { + self.report.add_errors( + self.name, + self.source, + [$crate::Error::AstError($crate::ast::AstError::from_parts(token.into(), error))] + ); + } + + /// Add a new ast warning to the error list. + #[allow(dead_code)] + fn warning(&mut self, token: impl Into<$crate::tokenizer::TokenReference>, error: impl Into<std::borrow::Cow<'static, str>>) { + self.report.add_warnings( + self.name, + self.source, + [$crate::Error::AstError($crate::ast::AstError::from_parts(token.into(), error))] + ); + } + + $($( + #[doc = "Set the optional information '" $opts_attr "' for the [" $name "] pass."] + #[allow(clippy::wrong_self_convention)] + pub fn $opts_attr(self, $opts_attr: $opts_ty) -> Self { + Self { $opts_attr: Some($opts_attr), ..self } + } + )+)? + + #[doc = "Apply the [" $name "] pass and get the resulting [vvs_parser::ast::Ast] or the list of the errors."] + pub fn process(mut self) -> Result<($crate::ast::Ast, [< $name Result >]), ()> { + let ast = self.program.take().unwrap(); + let ast = $crate::declare_pass!(@apply_on_ast $role (self, ast)); + match self.report.report() { + true => Err(()), + false => Ok((ast, [< $name Result >] { + $($($res_attr: self.$res_attr),+)? + })), + } + } + } + } + }; + + (@apply_on_ast transform ($self: ident, $ast: expr)) => {{ + use $crate::visitors::VisitorMut; + $self.visit_ast($ast) + }}; + + (@apply_on_ast visit ($self: ident, $ast: expr)) => {{ + use $crate::visitors::Visitor; + $self.visit_ast(&$ast); + $ast + }}; +} + +/// Trait used to provide a way for users to create their own passes +pub trait UserFrontendPass { + /// Get the name of the pass. For logging purposes. + fn name(&self) -> &'static str; + + /// Get the description of the pass. For logging purposes. + fn description(&self) -> &'static str; + + /// Do the work on a specific module. The order in which the modules are passed is not + /// guarented. It is better to not store state with interior mutability. + fn process( + &self, + program: crate::ast::Ast, + name: &str, + source: &str, + ) -> Result<crate::ast::Ast, crate::vivy::FrontendError>; +} diff --git a/src/Rust/vvs_parser/src/vivy/passes/opts_transform.rs b/src/Rust/vvs_parser/src/vivy/passes/opts_transform.rs new file mode 100644 index 0000000000000000000000000000000000000000..6c60caf8b37f6b40b1aa3d9b881199b8f9ca5e8e --- /dev/null +++ b/src/Rust/vvs_parser/src/vivy/passes/opts_transform.rs @@ -0,0 +1,49 @@ +use crate::{ast::*, node::Node, tokenizer::*, ShortString}; + +crate::declare_pass! { + /// The option optimization is here to substitute the options with the values chosen by the + /// user. + #[allow(dead_code)] + transform::OptsTransform: 'a {} + + aux_infos { options: &'a OptionTable } + results { unused: Vec<(ShortString, ShortString)> } +} + +impl crate::visitors::VisitorMut for OptsTransform<'_> { + fn visit_expression_end(&mut self, expression: Expression) -> Expression { + match expression { + Expression::Var(Var::Expression(var)) => self.process_var_expression(var), + expression => expression, + } + } +} + +impl OptsTransform<'_> { + fn process_var_expression(&mut self, var: Box<VarExpression>) -> Expression { + let module = match var.prefix() { + Prefix::Name(TokenReference { + token: Token { token_type: TokenType::Identifier { identifier }, .. }, + .. + }) if self.options.has_section(identifier) => identifier.clone(), + _ => return Expression::Var(Var::Expression(var)), + }; + + match var.suffixes().next() { + Some(Suffix::Index(Index::Dot { + name: TokenReference { token: Token { token_type: TokenType::Identifier { ref identifier }, .. }, .. }, + .. + })) if var.suffixes().count() == 1 => self.options.get(&module, identifier).cloned().unwrap_or_else(|| { + self.error(var.tokens().next().unwrap(), format!("failed to find option `{module}.{identifier}`")); + Expression::Symbol(TokenReference::basic_symbol("nil")) + }), + + Some(Suffix::Index(name)) => { + self.error(name.tokens().next().unwrap(), "expected a reference to an option, e.g. `module.option`"); + Expression::Symbol(TokenReference::basic_symbol("nil")) + } + + _ => Expression::Var(Var::Expression(var.clone())), + } + } +} diff --git a/src/Rust/vvs_parser/src/vivy/passes/stmt_checker.rs b/src/Rust/vvs_parser/src/vivy/passes/stmt_checker.rs new file mode 100644 index 0000000000000000000000000000000000000000..7dbb413a4eeb258749e0d7fb77d369e8a6f546f3 --- /dev/null +++ b/src/Rust/vvs_parser/src/vivy/passes/stmt_checker.rs @@ -0,0 +1,259 @@ +use crate::{ + ast::{Punctuated, TypeInfo, *}, + node::Node, + tokenizer::{Token, TokenKind, TokenReference, TokenType}, + visitors::Visit, + vivy::main_program::{MainProgram, MainProgramCallListItem, MainProgramStep}, + ShortString, +}; + +crate::declare_pass! { + /// The statement checker is here to verify that statements are not used in incorrect positions. + visit::StmtChecker: 'a { + in_job: bool, + } + + opt_infos { is_main: bool } + results { + imported: Vec<TokenReference>, + setd_opts: Vec<(ShortString, ShortString, Expression)>, + decl_opts: Vec<(ShortString, OptionDefaultValue)>, + main: Option<MainProgram>, + } +} + +impl crate::visitors::Visitor for StmtChecker<'_> { + fn visit_ast(&mut self, ast: &Ast) { + ast.nodes().stmts().for_each(|stmt| match stmt { + Stmt::Import(import) => self.check_import(import), + Stmt::Main(main) => self.check_main(main), + Stmt::Assignment(assignment) => self.check_option_set(assignment), + Stmt::OptionDecl(declaration) => self.check_option_decl(declaration), + + stmt @ Stmt::FunctionDeclaration(_) | stmt @ Stmt::LocalFunction(_) => stmt.visit(self), + stmt @ Stmt::JobDeclaration(_) => { + self.in_job = true; + stmt.visit(self); + self.in_job = false; + } + + Stmt::TypeDeclaration(_) => unimplemented!("custom types are tbd"), + + stmt => self.error(stmt.tokens().next().unwrap(), "unexpected statement"), + }); + if !ast.eof().is_kind(TokenKind::Eof) { + self.error(ast.eof(), "expected eof token here"); + } + self.warn_on_reimport(); + } + + fn visit_yield(&mut self, yields: &Yield) { + if !self.in_job { + self.error(yields.token(), "the yield statement can only be used from inside a job") + } + } + + fn visit_import(&mut self, node: &Import) { + self.error(node.import_token(), "the 'import' statement is only valid in top-level position") + } + + fn visit_option_decl(&mut self, node: &OptionDecl) { + self.error(node.option_token(), "the 'option' statement is only valid in top-level position") + } + + fn visit_write(&mut self, node: &Write) { + self.error(node.write_token(), "the 'write' statement is only valid in the main statement") + } + + fn visit_main(&mut self, node: &Main) { + self.error(node.main_token(), "the 'main' statement is only valid in top-level position") + } +} + +impl StmtChecker<'_> { + fn warn_on_reimport(&mut self) { + let mut vec: Vec<_> = self + .imported + .iter() + .map(|token| ShortString::new(token.token_type().as_str())) + .collect(); + vec.sort(); + + enum State { + Empty, + Import(ShortString), + AlreadyWarned(ShortString), + } + + let mut state = State::Empty; + for current in vec { + match state { + // Double import. + State::Import(last) if last == current => { + state = State::AlreadyWarned(current); + let token = self + .imported + .iter() + .find(|import| import.token_type().as_str() == last.as_str()) + .unwrap() + .clone(); + self.warning(token, "already imported"); + } + + // Multi-import, but already warned. + State::AlreadyWarned(ref last) if *last == current => {} + + // Current changed. + State::AlreadyWarned(_) | State::Import(_) | State::Empty => state = State::Import(current), + } + } + } + + fn check_option_decl(&mut self, declaration: &OptionDecl) { + declaration.declarations().for_each(|(n, ty, v)| match n.token_type() { + TokenType::Identifier { identifier } if self.decl_opts.iter().any(|(opt, _)| opt == identifier) => { + self.error(n, "redefinition of option"); + } + TokenType::Identifier { identifier } => self.decl_opts.push(( + identifier.clone(), + OptionDefaultValue { expression: v.clone(), type_info: ty.map(|ty| ty.type_info().clone()) }, + )), + token => unreachable!("expected an identifier! {token:?}"), + }) + } + + fn check_import(&mut self, import: &Import) { + assert!(import.name().is_kind(TokenKind::StringLiteral), "import name token should be a string literal"); + self.imported.push(import.name().clone()); + } + + fn check_option_set(&mut self, assignation: &Assignment) { + if !self.is_main.unwrap_or_default() { + return self.error( + assignation.tokens().next().expect("assignation"), + "options can be set only from the main script file", + ); + } + + let handle = |v: &Var| match v { + Var::Expression(expression) => { + let module = match expression.prefix() { + Prefix::Name(TokenReference { + token: Token { token_type: TokenType::Identifier { identifier }, .. }, + .. + }) => identifier.clone(), + prefix => { + let token = prefix.tokens().next().unwrap(); + self.error(token, "invalid module name, expected an identifier"); + return None; + } + }; + + let error_token = match expression.suffixes().next() { + Some(Suffix::Index(Index::Dot { + name: + TokenReference { token: Token { token_type: TokenType::Identifier { identifier }, .. }, .. }, + .. + })) if expression.suffixes().count() == 1 => return Some((module, identifier.clone())), + Some(suffix) => suffix.tokens().next().unwrap().clone(), + None => expression.tokens().next().unwrap().clone(), + }; + self.error(error_token, "expected a reference to an option by its name, e.g. `module.option`"); + None + } + + Var::Name(name) => match name.token_type() { + TokenType::Identifier { identifier } => Some((ShortString::new(self.name), identifier.clone())), + _ => unreachable!(), + }, + }; + + let options = Vec::from_iter(assignation.variables().iter().flat_map(handle)) + .into_iter() + .zip(assignation.expressions().into_iter().cloned()) + .map(|((module, name), val)| (module, name, val)); + self.setd_opts.extend(options); + } + + fn check_main(&mut self, main: &Main) { + if !self.is_main.unwrap_or_default() { + return self.error(main.main_token(), "the main statement must always be in the main script file"); + } else if self.main.is_some() { + return self.error(main.main_token(), "multiple main found"); + } + + let mut declared_variables = vec![main.initial_variable().clone()]; + let mut program_steps = Vec::with_capacity(main.assignements().len()); + for step in main.assignements() { + let call_list = step.call_list_items().flat_map(|item| match item { + CallListItem::Variable(var) => declared_variables + .contains(var) + .then(|| MainProgramCallListItem::Variable(var.token_type().as_str().into())) + .ok_or_else(|| self.error(var, "use of undeclared variable")), + + CallListItem::SetParameter { parameter, expression, .. } => { + let parameter = parameter.token_type().as_str(); + log::error!("check if the job has the parameter {parameter}"); + Ok(MainProgramCallListItem::Parameter(ShortString::new(parameter), expression.clone())) + } + }); + + if !declared_variables.contains(step.destination()) { + self.error(step.destination(), "redefined variable"); + continue; + } + + let (module, job) = step.called_job_identifiers(); + log::error!("check if the module and the job are correct…"); + + program_steps.push(MainProgramStep::new( + step.destination().token_type().as_str().into(), + (module.clone(), job.clone()), + call_list, + )); + declared_variables.push(step.destination().clone()); + } + + let written_variables = main + .returns() + .map(|write| write.variables()) + .into_iter() + .flat_map(Punctuated::iter); + let written_variables = written_variables.flat_map(|written| { + declared_variables + .contains(written) + .then(|| ShortString::new(written.token_type().as_str())) + .ok_or_else(|| self.error(written, "try to write a variable that was not declared")) + }); + + self.main = Some( + MainProgram::default() + .with_initial(ShortString::new(main.initial_variable().token_type().as_str())) + .with_steps(program_steps) + .with_returns(written_variables), + ); + } +} + +pub struct OptionDefaultValue { + expression: Expression, + type_info: Option<TypeInfo>, +} + +impl From<OptionDefaultValue> for Expression { + fn from(value: OptionDefaultValue) -> Self { + value.expression + } +} + +impl OptionDefaultValue { + /// Get the default value for the option. + pub fn expression(&self) -> &Expression { + &self.expression + } + + /// Get the type info if specified + pub fn type_info(&self) -> Option<&TypeInfo> { + self.type_info.as_ref() + } +} diff --git a/src/Rust/vvs_parser/src/vivy/passes/type_checker.rs b/src/Rust/vvs_parser/src/vivy/passes/type_checker.rs new file mode 100644 index 0000000000000000000000000000000000000000..712253f5417f5617ee3684b2ef2418dcaa666607 --- /dev/null +++ b/src/Rust/vvs_parser/src/vivy/passes/type_checker.rs @@ -0,0 +1,551 @@ +use crate::{ + ast::*, + node::Node, + tokenizer::*, + traits::DefaultRef, + vivy::{library::*, symbol_table::SymbolTable}, +}; + +crate::declare_pass! { + /// The type checker is here to verify type corectness of the program and infer types, etc. To + /// check the types we will need to do custom things... + visit::TypeChecker: 'a {} + + aux_infos { + library: &'a Library, + symbol_table: SymbolTable<'a, TypeInfo>, + } +} + +impl crate::visitors::Visitor for TypeChecker<'_> { + fn visit_ast(&mut self, ast: &Ast) { + for error in Vec::from_iter(ast.nodes().stmts().flat_map(|stmt| match stmt { + Stmt::JobDeclaration(decl) => self.type_compute().callable(decl.body(), true).err(), + Stmt::FunctionDeclaration(decl) => self.type_compute().callable(decl.body(), false).err(), + Stmt::LocalFunction(decl) => self.type_compute().callable(decl.body(), false).err(), + Stmt::Assignment(assignments) => self.type_compute().assignments(assignments).map(|_| ()).err(), + Stmt::OptionDecl(_) | Stmt::Import(_) => None, // NOOP / Types already registered... + Stmt::TypeDeclaration(_) => unimplemented!("custom types are tbd"), + _ => unreachable!("already checked that they are not here"), + })) { + self.report + .add_errors(self.name, self.source, [crate::Error::AstError(*error)]); + } + if !ast.eof().is_kind(TokenKind::Eof) { + self.error(ast.eof(), "expected eof token here"); + } + } +} + +impl TypeChecker<'_> { + fn type_compute(&self) -> TypeCompute { + TypeCompute::new(self.library, self.symbol_table.sub_scope()) + } +} + +/// The thing that will actually compute types and returns errors in case of problems. +struct TypeCompute<'a> { + library: &'a Library, + symbols: SymbolTable<'a, TypeInfo>, + in_loop: bool, + in_job: bool, + returns: &'a TypeInfo, +} + +type TypeComputeError = Box<AstError>; +type TypeComputeResult<'a> = Result<(TypeInfo, SymbolTable<'a, TypeInfo>), TypeComputeError>; + +macro_rules! box_error { + ($token: expr, $format: literal $(,)?) => { Box::new(AstError::from_parts($token.into(), format!($format ))) }; + ($token: expr, $format: literal, $($args: expr),+ $(,)?) => { Box::new(AstError::from_parts($token.into(), format!($format, $($args),+))) }; +} + +fn unsupported<T>(token: &TokenReference, whats: &str) -> Result<T, TypeComputeError> { + Err(box_error!(token, "{whats} are not supported for now")) +} + +impl<'a> TypeCompute<'a> { + fn new(library: &'a Library, symbols: SymbolTable<'a, TypeInfo>) -> Self { + Self { library, symbols, returns: TypeInfo::default_ref(), in_loop: false, in_job: false } + } + + fn sub(&'a self) -> Self { + Self { symbols: self.symbols.sub_scope(), ..*self } + } + + fn set(mut self, symbol: &TokenReference, ty: TypeInfo) -> Result<Self, TypeComputeError> { + self.symbols.set(symbol.token_type().as_str(), ty).map_err(|var| { + box_error!(symbol, "{var} was already defined at the root level of the program and is thus a constant") + })?; + Ok(self) + } + + fn in_loop(self) -> Self { + Self { in_loop: true, ..self } + } + + fn assignments(self, assignments: &'a Assignment) -> TypeComputeResult<'a> { + let mut assignments = assignments.variables().iter().zip(assignments.expressions()); + assignments.try_for_each(|(dest, expr)| self.sub().assignation(dest, expr))?; + Ok((TypeInfo::default(), self.symbols)) + } + + fn check_method_call( + self, + record: &TypeRecord, + method: &MethodCall, + caller: &TokenReference, + token: &TokenReference, + ) -> Result<TypeInfo, TypeComputeError> { + let method_name = method.name().token_type().as_str(); + let (arguments, returns) = match record + .method(method_name) + .ok_or_else(|| box_error!(token, "undefined method '{caller}:{method_name}'"))? + { + TypeRecordMethod([this, args @ ..], ret, true) if this == record.type_info() => (args, ret), + TypeRecordMethod(args, ret, false) => (args, ret), + TypeRecordMethod([this, ..], _, true) => { + return Err(box_error!(token, "try to call '{this}:{method_name}' on expression of type '{caller}'")) + } + TypeRecordMethod(.., true) => unreachable!(), + }; + self.check_func_args(arguments, returns, method.args(), token) + } + + fn check_func_args( + self, + arguments: &[TypeInfo], + returns: &TypeInfo, + func_args: &FunctionArgs, + token: &TokenReference, + ) -> Result<TypeInfo, TypeComputeError> { + match func_args { + FunctionArgs::String(_) => match arguments.first() { + Some(type_info) if arguments.len() == 1 && type_info == TypeInfo::string() => Ok(returns.clone()), + Some(type_info) if arguments.len() == 1 => Err(box_error!( + token, + "try to pass a string argument to a function that a variable of type {type_info}" + )), + Some(_) => { + Err(box_error!(token, "try to pass an argument to a function that takes {}", arguments.len())) + } + None => Err(box_error!(token, "try to pass an argument to a function that takes none",)), + }, + + FunctionArgs::TableConstructor(_) if arguments.len() != 1 => Err(box_error!( + token, + "try to pass a table as argument to a function that takes {} arguments", + arguments.len() + )), + FunctionArgs::TableConstructor(args) => { + debug_assert_eq!(arguments.len(), 1); + todo!("find a way to correctly parse expected types..."); + // We can pass a table because we expect a table, or because we pass named + // arguments... + } + + FunctionArgs::Parentheses { arguments: args, .. } => { + if args.len() != arguments.len() { + let (arg_len, func_len) = (args.len(), arguments.len()); + return Err(box_error!( + token, + "try to pass {arg_len} arguments to a function that takes {func_len}" + )); + } + let mut arguments = args.iter().enumerate().zip(arguments.iter()); + match arguments.find_map(|((idx, arg), type_info)| { + self.sub() + .expression_as_type(type_info, arg) + .is_err() + .then(|| (idx, arg.tokens().next().unwrap(), type_info)) + }) { + Some((n, tok, ty)) => Err(box_error!(tok, "expected argument n°{n} to be of type {ty}")), + None => Ok(returns.clone()), + } + } + } + } + + fn expression(self, expression: &'a Expression) -> TypeComputeResult<'a> { + match expression { + Expression::Parentheses { expression, .. } => self.expression(expression), + Expression::FunctionCall(call) => self.suffixes(call.prefix(), call.suffixes()), + + Expression::Number(_) => Ok((TypeInfo::number().clone(), self.symbols)), + Expression::String(_) => Ok((TypeInfo::string().clone(), self.symbols)), + Expression::TypeAssertion { .. } => Ok((TypeInfo::default(), self.symbols)), + + Expression::Var(Var::Expression(var)) => self.suffixes(var.prefix(), var.suffixes()), + Expression::Var(Var::Name(token)) => { + let ty = self + .symbols + .get(token.token_type().as_str()) + .ok_or_else(|| box_error!(token, "undefined variable"))?; + Ok((ty.clone(), self.symbols)) + } + + Expression::Symbol(token) => match token.token_type() { + TokenType::Symbol { symbol: Symbol::Nil } => Ok((TypeInfo::default(), self.symbols)), + TokenType::Symbol { symbol: Symbol::False | Symbol::True } => { + Ok((TypeInfo::number().clone(), self.symbols)) + } + _ => unreachable!(), + }, + + Expression::UnaryOperator { unop, expression } => { + use {TypeInfo::*, UnOp::*}; + let (ty, symbols) = self.expression(expression)?; + let is_container = + matches!(ty, Array { .. } | Basic(_) | Optional { .. } | Table { .. } | Tuple { .. }); + match unop { + Minus(_) | Not(_) | Tilde(_) if ty == *TypeInfo::number() => Ok((ty, symbols)), + Hash(_) if is_container => Ok((TypeInfo::number().clone(), symbols)), + _ => { + Err(box_error!(unop.token(), "can't apply this unary operator to an expression of type '{ty}'")) + } + } + } + + Expression::BinaryOperator { lhs, binop, rhs } => { + use BinOp::*; + let ty = self.sub().expression(lhs)?.0; + self.sub().expression_as_type(&ty, rhs)?; + match binop { + TwoEqual(_) | TildeEqual(_) => Ok((TypeInfo::number().clone(), self.symbols)), + TwoDots(_) if ty == *TypeInfo::string() => Ok((TypeInfo::number().clone(), self.symbols)), + + GreaterThan(_) | GreaterThanEqual(_) | LessThan(_) | LessThanEqual(_) | DoubleGreaterThan(_) + | DoubleLesserThan(_) | Caret(_) | Pipe(_) | Ampersand(_) | Tilde(_) | Percent(_) | Star(_) + | Slash(_) | DoubleSlash(_) | Minus(_) | Plus(_) | And(_) | Or(_) + if ty == *TypeInfo::number() => + { + Ok((ty, self.symbols)) + } + + _ => Err(box_error!( + binop.token(), + "can't apply this binary operator to an expression of type '{ty}'", + )), + } + } + + Expression::IfExpression(_) => todo!(), + Expression::TableConstructor(_) => todo!(), + + Expression::Function(_) => unsupported(expression.tokens().next().unwrap(), "lambdas"), + } + } + + fn suffixes(self, prefix: &'a Prefix, suffixes: impl Iterator<Item = &'a Suffix> + 'a) -> TypeComputeResult<'a> { + let prefix = match prefix { + Prefix::Expression(expression) => self.sub().expression(expression)?.0, + Prefix::Name(token) => self + .symbols + .get(token.token_type().as_str()) + .cloned() + .ok_or_else(|| box_error!(token, "try to reference an undefined variable or function"))?, + }; + + let ty = suffixes.into_iter().try_fold(prefix, |prefix, suffix| match prefix { + TypeInfo::Callback { arguments, return_type, .. } => match suffix { + Suffix::Call(Call::AnonymousCall(call)) => { + let arguments = + Vec::from_iter(arguments.into_iter().map(|TypeArgument { type_info, .. }| type_info)); + self.sub() + .check_func_args(&arguments, &return_type, call, suffix.tokens().next().unwrap()) + } + suffix => unreachable!("{suffix:?}"), + }, + + TypeInfo::Array { type_info, .. } => match suffix { + Suffix::Index(Index::Dot { name, .. }) => match name.token_type().as_str() { + "first" | "last" => Ok(*type_info), + field => Err(box_error!(name, "unknown field '{field}' for array")), + }, + Suffix::Index(Index::Brackets { expression, .. }) => self + .sub() + .expression_as_type(TypeInfo::number(), expression) + .map(|_| *type_info), + _ => unreachable!(), + }, + + TypeInfo::Basic(type_name) => { + let suffix_token = suffix.tokens().next().unwrap(); + let record = self + .library + .get(type_name.token_type().as_str()) + .ok_or_else(|| box_error!(suffix_token, "try to use undefined type '{type_name}'"))?; + match suffix { + Suffix::Call(Call::MethodCall(method)) => { + self.sub().check_method_call(record, method, &type_name, suffix_token) + } + Suffix::Index(Index::Dot { name, .. }) => { + let TypeRecordField(_, field) = record + .field(name.token_type().as_str()) + .ok_or_else(|| box_error!(suffix_token, "undefined field for type '{type_name}'"))?; + Ok(field.clone()) + } + Suffix::Index(Index::Brackets { expression, .. }) => todo!("{expression}"), + suffix => unreachable!("{suffix}"), + } + } + + TypeInfo::Tuple { types, .. } => { + let index = match suffix { + Suffix::Index(Index::Dot { name: token, .. }) + | Suffix::Index(Index::Brackets { expression: Expression::Number(token), .. }) => token, + _ => unreachable!(), + }; + let handle = |str: &str| { + str.parse::<usize>().map_err(|err| { + box_error!(index, "index into a tuple must be a known integer at compilation time: {err}",) + }) + }; + let ty = types.iter().nth(match index.token_type() { + TokenType::Identifier { identifier } => match identifier.as_str() { + "zero" | "first" => 0, + "one" | "second" => 1, + "two" => 2, + idx => return Err(box_error!(index, "unknown tuple index: '{idx}'")), + }, + TokenType::Number { text } => handle(text.as_str())?, + idx @ TokenType::StringLiteral { .. } => handle(idx.as_str())?, + _ => todo!(), + }); + ty.cloned() + .ok_or_else(|| box_error!(index, "out of range in tuple: ({types})")) + } + + TypeInfo::Table { fields, .. } => { + let field = match suffix { + Suffix::Index(Index::Brackets { expression: Expression::String(name), .. }) + | Suffix::Index(Index::Dot { name, .. }) => name.token_type().as_str(), + _ => unreachable!(), + }; + let field = fields.iter().find_map(|TypeField { key, value, .. }| { + let TypeFieldKey::Name(key) = key else { unreachable!() }; + let key = key.token_type().as_str(); + (field == key).then_some(value) + }); + field.cloned().ok_or_else(|| { + box_error!(suffix.tokens().next().unwrap(), "failed to find field in {{ {fields} }}") + }) + } + + TypeInfo::Optional { base, .. } => match suffix { + Suffix::Call(Call::MethodCall(call)) => match call.args() { + FunctionArgs::Parentheses { arguments, .. } if arguments.is_empty() => { + match call.name().token_type().as_str() { + "is_nil" | "is_value" => Ok(TypeInfo::number().clone()), + "value" => Ok(*base), + m => Err(box_error!(suffix.tokens().next().unwrap(), "unknown method '{base}::{m}'")), + } + } + _ => Err(box_error!( + suffix.tokens().next().unwrap(), + "can't pass parguments to '{base}::{}'", + call.name(), + )), + }, + _ => Err(box_error!(suffix.tokens().next().unwrap(), "incorrect usage of optional value")), + }, + + TypeInfo::Typeof { .. } => Ok(TypeInfo::string().clone()), + })?; + + Ok((ty, self.symbols)) + } + + fn expression_as_type(self, as_ty: &TypeInfo, expression: &'a Expression) -> Result<(), TypeComputeError> { + let (ty, _) = self.sub().expression(expression)?; + (ty == *as_ty).then_some(()).ok_or_else(|| { + box_error!(expression.tokens().next().unwrap(), "the expression should be of type '{as_ty}', got: '{ty}'",) + }) + } + + fn local_assignment(mut self, assignment: &'a LocalAssignment) -> TypeComputeResult<'a> { + let variables = assignment.names().iter(); + let variables = variables + .zip(assignment.type_specifiers().map(|ty| ty.map(TypeSpecifier::type_info))) + .zip(assignment.expressions()); + let variables = variables.map(|((name, ty), val)| { + let ty = match ty { + None => self.sub().expression(val)?.0, + Some(ty) => { + self.sub().expression_as_type(ty, val)?; + ty.clone() + } + }; + Ok::<_, TypeComputeError>((name.token_type().as_str().into(), ty)) + }); + let symbols = self + .symbols + .extend(variables.collect::<Result<Vec<_>, TypeComputeError>>()?) + .map_err(|variable| { + box_error!(assignment.local_token(), "can't declare {variable} because it shadows a global variable",) + })? + .take(); + Ok((TypeInfo::default(), symbols)) + } + + fn compound_assignment(self, assignment: &'a CompoundAssignment) -> TypeComputeResult<'a> { + todo!() + } + + fn yields(self, yields: &'a Yield) -> TypeComputeResult<'a> { + if !self.in_job { + Err(box_error!(yields.token(), "yielding values is only possible from jobs")) + } else { + todo!() + } + } + + fn assignation(self, variable: &'a Var, expression: &'a Expression) -> Result<(), TypeComputeError> { + match variable { + Var::Expression(_) => todo!(), + Var::Name(variable) => match variable.token_type() { + TokenType::Identifier { identifier } if self.symbols.root().get(identifier).is_some() => { + Err(box_error!(variable, "try to assign a global variable")) + } + TokenType::Identifier { identifier } => match self.symbols.get(identifier).cloned() { + Some(ty) => self.expression_as_type(&ty, expression), + None => Err(box_error!(variable, "try to assign an undefined variable")), + }, + _ => unreachable!(), + }, + } + } + + fn stmt(self, stmt: &'a Stmt) -> TypeComputeResult<'a> { + match stmt { + Stmt::CompoundAssignment(assignments) => self.compound_assignment(assignments), + Stmt::LocalAssignment(assignment) => self.local_assignment(assignment), + Stmt::Assignment(assignments) => self.assignments(assignments), + Stmt::FunctionCall(call) => self.suffixes(call.prefix(), call.suffixes()), + Stmt::Yield(yields) => self.yields(yields), + Stmt::Do(block) => self.block(block.block()), + + Stmt::If(if_stmt) => { + self.sub().expression_as_type(TypeInfo::number(), if_stmt.condition())?; + self.sub().block(if_stmt.block())?; + for elseif in if_stmt.else_if().into_iter().flatten() { + self.sub().expression_as_type(TypeInfo::number(), elseif.condition())?; + self.sub().block(elseif.block())?; + } + if let Some(block) = if_stmt.else_block() { + self.sub().block(block)?; + } + Ok((TypeInfo::default(), self.symbols)) + } + + Stmt::Repeat(repeat_stmt) => { + let symbols = self.sub().block(repeat_stmt.block())?.1; + TypeCompute { symbols, ..self } + .in_loop() + .expression_as_type(TypeInfo::number(), repeat_stmt.until())?; + Ok((TypeInfo::default(), self.symbols)) + } + + Stmt::While(while_stmt) => { + self.sub() + .expression_as_type(TypeInfo::number(), while_stmt.condition())?; + self.sub().in_loop().block(while_stmt.block())?; + Ok((TypeInfo::default(), self.symbols)) + } + + Stmt::NumericFor(for_stmt) => { + self.sub().expression_as_type(TypeInfo::number(), for_stmt.start())?; + self.sub().expression_as_type(TypeInfo::number(), for_stmt.end())?; + if let Some(step) = for_stmt.step() { + self.sub().expression_as_type(TypeInfo::number(), step)?; + } + self.sub() + .set(for_stmt.index_variable(), TypeInfo::number().clone())? + .block(for_stmt.block())?; + Ok((TypeInfo::default(), self.symbols)) + } + + Stmt::GenericFor(_) => todo!(), + + Stmt::JobDeclaration(decl) => { + Err(box_error!(decl.function_token(), "nested declaration of job is forbidden")) + } + + Stmt::FunctionDeclaration(decl) => unsupported(decl.function_token(), "nested declaration of functions"), + Stmt::LocalFunction(decl) => unsupported(decl.function_token(), "nested declaration of functions"), + Stmt::TypeDeclaration(_) => unsupported(stmt.tokens().next().unwrap(), "custom types"), + + Stmt::Import(_) | Stmt::Write(_) | Stmt::Main(_) | Stmt::OptionDecl(_) => { + unreachable!("should have been already checked / can't be inside function and job declarations") + } + } + } + + fn last_stmt(self, stmt: &'a LastStmt) -> TypeComputeResult<'a> { + match stmt { + LastStmt::Break(token) | LastStmt::Continue(token) => match self.in_loop { + true => Ok((TypeInfo::default(), self.symbols)), + false => Err(box_error!(token, "invalid statement, not inside a loop")), + }, + + LastStmt::Return(returns) if returns.returns().len() >= 2 => { + unsupported(returns.token(), "tuples to return multiple things") + } + LastStmt::Return(returns) if returns.returns().len() == 1 => (self.returns != TypeInfo::default_ref()) + .then(|| self.expression(returns.returns().iter().next().unwrap())) + .ok_or_else(|| { + box_error!(returns.token(), "function or job returns something, but this return statement is empty") + })?, + LastStmt::Return(returns) if returns.returns().len() == 1 => (self.returns != TypeInfo::default_ref()) + .then(|| (TypeInfo::default(), self.symbols)) + .ok_or_else(|| { + box_error!( + returns.token(), + "expected to return an expression of type {}, but returns nothing here", + self.returns, + ) + }), + LastStmt::Return(_) => unreachable!(), + } + } + + fn block(self, block: &'a Block) -> TypeComputeResult<'a> { + let symbols = block.stmts().try_fold(self.symbols.sub_scope(), |symbols, stmt| { + Ok::<_, TypeComputeError>(TypeCompute { symbols, ..self }.stmt(stmt)?.1) + })?; + Ok(match block.last_stmt() { + Some(stmt) => (TypeCompute { symbols, ..self }.last_stmt(stmt)?.0, self.symbols), + None => (TypeInfo::default(), self.symbols), + }) + } + + fn callable(mut self, callable: &'a FunctionBody, is_job: bool) -> TypeComputeResult<'a> { + self.in_job = is_job; + self.returns = callable + .return_type() + .map(|specifier| specifier.type_info()) + .unwrap_or(TypeInfo::default_ref()); + + if let Some((idx, parameter)) = callable + .parameters() + .iter() + .zip(callable.type_specifiers().map(|ty| ty.map(|ty| ty.type_info()))) + .enumerate() + .find_map(|(idx, (parameter, specifier))| match specifier { + Some(ty) => self + .symbols + .set(parameter.token_type().as_str(), ty.clone()) + .is_err() + .then_some((idx + 1, parameter)), + None => Some((idx + 1, parameter)), + }) + { + return Err(box_error!( + parameter.tokens().next().unwrap(), + "parameter n°{idx} named '{parameter}' has no type specifier or is an ellipse '...' or shadows a global variable", + )); + } + + self.block(callable.block()) + } +} diff --git a/src/Rust/vvs_parser/src/vivy/passes/type_collector.rs b/src/Rust/vvs_parser/src/vivy/passes/type_collector.rs new file mode 100644 index 0000000000000000000000000000000000000000..e24536a60e14a80d3169e6c8eec9ac588402cb25 --- /dev/null +++ b/src/Rust/vvs_parser/src/vivy/passes/type_collector.rs @@ -0,0 +1,11 @@ +use crate::vivy::library::*; + +crate::declare_pass! { + /// Collector of custom type, to register them in the library. + #[allow(dead_code)] + visit::TypeCollector: 'a {} + + aux_infos { library: &'a mut Library } +} + +impl crate::visitors::Visitor for TypeCollector<'_> {} diff --git a/src/Rust/vvs_parser/src/vivy/search_path.rs b/src/Rust/vvs_parser/src/vivy/search_path.rs new file mode 100644 index 0000000000000000000000000000000000000000..fd24ed86a9b2edc9d05b7958f06fcb1890e6e23a --- /dev/null +++ b/src/Rust/vvs_parser/src/vivy/search_path.rs @@ -0,0 +1,51 @@ +//! Used to search for other files when using the `import` statement in Vivy Script. + +use std::{borrow::Cow, fs, path::PathBuf}; + +/// Search path, can pass the name of a module and will try to return the associated code. +#[derive(Default)] +pub struct SearchPath { + folders: Vec<PathBuf>, +} + +/// The extension for vivy script files. +pub const VIVY_SCRIPT_EXTENSION: &str = "vvs"; + +impl SearchPath { + /// Create a new search path. + pub const fn new() -> Self { + Self { folders: Vec::new() } + } + + /// Resolve the search path to get the desired code. + pub fn resolve(&self, import: &str) -> Option<Cow<'static, str>> { + self.folders.iter().find_map(|folder| { + let mut path = folder.join(import); + path.set_extension(VIVY_SCRIPT_EXTENSION); + let code = fs::read_to_string(path).ok()?; + Some(Cow::Owned(code)) + }) + } + + /// Add a folder to the search list. + pub fn push(&mut self, folder: PathBuf) { + self.folders.push(folder) + } +} + +impl Extend<PathBuf> for SearchPath { + /// Add multiple folders to the search list. + fn extend<T: IntoIterator<Item = PathBuf>>(&mut self, iter: T) { + self.folders.extend(iter) + } +} + +impl FromIterator<PathBuf> for SearchPath { + /// Create a search list from a list of folders. + fn from_iter<T: IntoIterator<Item = PathBuf>>(iter: T) -> Self { + Self { folders: iter.into_iter().collect() } + } +} + +/// The default search path, by default we only search the pre-packaged files. +pub(crate) static DEFAULT_SEARCH_PATH: SearchPath = SearchPath::new(); diff --git a/src/Rust/vvs_parser/src/vivy/symbol_table.rs b/src/Rust/vvs_parser/src/vivy/symbol_table.rs new file mode 100644 index 0000000000000000000000000000000000000000..156e6036de0283dee5bee35afef324f90e506459 --- /dev/null +++ b/src/Rust/vvs_parser/src/vivy/symbol_table.rs @@ -0,0 +1,103 @@ +use crate::{traits::DefaultRef, ShortString}; +use hashbrown::HashMap; +use std::ops; + +/// The symbol table stores the available symbols with theyr type or whatever. +pub struct SymbolTable<'a, T> { + /// A possible parent for this scope. The invariant is: either [SymbolTable::parent] or + /// [SymbolTable::imported] can be non-empty/null. + parent: Option<&'a SymbolTable<'a, T>>, + + /// Imported scopes. The invariant is: either [SymbolTable::parent] or [SymbolTable::imported] + /// can be non-empty/null. + imported: Vec<&'a SymbolTable<'a, T>>, + + /// List of symbols from this scope. + symbols: HashMap<ShortString, T>, +} + +impl<T> Default for SymbolTable<'_, T> { + fn default() -> Self { + Self { parent: None, symbols: HashMap::new(), imported: vec![] } + } +} + +impl<'a, T> SymbolTable<'a, T> { + /// Create a new sub-scoped symbol table. + pub fn sub_scope(&'a self) -> Self { + Self { parent: Some(self), symbols: Default::default(), imported: vec![] } + } + + /// Add a new variable to the current scope. We override symbols (non-UB shadowing of + /// variables). Note that we can't shadow or set variables from the root scope as it denotes + /// the global state. In case of error we return the name of the problematic variable. + pub fn set(&mut self, symbol: impl Into<ShortString> + AsRef<str>, value: T) -> Result<&mut Self, ShortString> { + if self.root().get(symbol.as_ref()).is_none() { + self.symbols.insert(symbol.into(), value); + Ok(self) + } else { + Err(symbol.into()) + } + } + + /// Add variables from an iterator. Same rules as [Self::set]. + pub fn extend(&mut self, iter: impl IntoIterator<Item = (ShortString, T)>) -> Result<&mut Self, ShortString> { + iter.into_iter() + .try_fold(self, |this, (symbol, value)| this.set(symbol, value)) + } + + /// Imports other scopes into this one. Note that if this scope is not the root one, then we + /// will panic... + pub fn import(&mut self, iter: impl IntoIterator<Item = &'a SymbolTable<'a, T>>) -> &mut Self { + debug_assert!(self.parent.is_none(), "can't have a parent and import another scope"); + self.imported.extend(iter); + self + } + + /// Get the root scope. + pub fn root(&self) -> &Self { + let mut root = self; + while let Some(parent) = root.parent { + root = parent; + } + root + } + + /// Get a variable/callback/function from this scope or any parent scope. + pub fn get(&self, symbol: impl AsRef<str>) -> Option<&T> { + self.symbols + .get(symbol.as_ref()) + .or_else(|| self.parent?.get(symbol.as_ref())) + .or_else(|| self.imported.iter().find_map(|scope| scope.get(symbol.as_ref()))) + } + + /// Consume the mutable reference to give back the owned table. + pub(crate) fn take(&mut self) -> Self { + std::mem::take(self) + } +} + +impl<T> FromIterator<(ShortString, T)> for SymbolTable<'_, T> { + fn from_iter<I: IntoIterator<Item = (ShortString, T)>>(iter: I) -> Self { + let mut table = Self::default(); + let _ = table.extend(iter); + table + } +} + +impl<Idx: AsRef<str>, T: DefaultRef + 'static> ops::Index<Idx> for SymbolTable<'_, T> { + type Output = T; + + /// Same as [SymbolTable::get] but we returns a reference to a default value if the variable was not found. + fn index(&self, index: Idx) -> &Self::Output { + self.get(index).unwrap_or_else(|| T::default_ref()) + } +} + +impl<'a> SymbolTable<'a, crate::ast::TypeInfo> { + /// Create a new type symbol table, e.g. a [SymbolTable] where the values are + /// [crate::ast::TypeInfo]. This can be usefull for type checking passes. + pub fn new(ast: &crate::ast::Ast, options: Option<&crate::ast::OptionTable>) -> Self { + todo!() + } +} diff --git a/src/Rust/vvs_parser/vivy-script.vim b/src/Rust/vvs_parser/vivy-script.vim new file mode 100644 index 0000000000000000000000000000000000000000..f5ccddb8c0130f4cbe790d842bf27235ac882e1e --- /dev/null +++ b/src/Rust/vvs_parser/vivy-script.vim @@ -0,0 +1,37 @@ +if exists('b:current_syntax') | finish | endif +let b:current_syntax = 'vivy script' + +syn keyword VVKeywords option import set repeat main end do then typeof yield +syn keyword VVKeywords for while if else return local in elseif elif until +syn keyword VVOperators or xor not and mod +syn keyword VVBoolean true false +syn keyword VVSelf self + +syn keyword VVDeclCallable function job nextgroup=VVSDeclCallableName +syn match VVDeclCallableName '[a-zA-Z_][a-zA-Z_0-9]*\ze(' +syn match VVType ':\ *\zs[a-zA-Z_][a-zA-Z_0-9]*\(<[a-zA-Z_][a-zA-Z_0-9]*>\)\?' + +syn region VVString1 start=/"/ skip=/\\"/ end=/"/ +syn region VVString2 start=/'/ skip=/\\'/ end=/'/ +syn region VVString3 start=/\[\[/ end=/\]\]/ +syn match VVNumber /-\?\<\d\+\.\d*\(e[+-]\d\+\)\?\>/ +syn match VVNumber /-\?\<\d\+\>/ + +syn match VVComment1 "--\(-\)\?.*$" +syn region VVComment2 start="--\(-\)\?\[\[*" end="\]\]" + +syn match VVVariable '[A-Z_][A-Z_0-9]*' + +hi def link VVDeclCallable Keyword +hi def link VVDeclCallableName Function +hi def link VVKeywords Keyword +hi def link VVOperators Keyword +hi def link VVSelf Constant +hi def link VVType Type +hi def link VVComment1 Comment +hi def link VVComment2 Comment +hi def link VVNumber Float +hi def link VVBoolean Boolean +hi def link VVString1 String +hi def link VVString2 String +hi def link VVString3 String diff --git a/src/Rust/vvs_parser_derive/Cargo.toml b/src/Rust/vvs_parser_derive/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..f25fee11662dd10364747b8466a6031e84bb7ad5 --- /dev/null +++ b/src/Rust/vvs_parser_derive/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "vvs_parser_derive" +license = "MPL-2.0" +description = "Internally used for the vvs_parser project. Do not use." + +version.workspace = true +authors.workspace = true +edition.workspace = true + +[lib] +proc-macro = true + +[dependencies] +indexmap.workspace = true +proc-macro2.workspace = true +quote.workspace = true + +syn = { version = "1", features = ["extra-traits"] } diff --git a/src/Rust/vvs_parser_derive/LICENSE.md b/src/Rust/vvs_parser_derive/LICENSE.md new file mode 100644 index 0000000000000000000000000000000000000000..2b8bbd4546a3f2c86fb661e735422cda8d896427 --- /dev/null +++ b/src/Rust/vvs_parser_derive/LICENSE.md @@ -0,0 +1,347 @@ +Mozilla Public License Version 2.0 +================================== + +### 1. Definitions + +**1.1. “Contributorâ€** + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +**1.2. “Contributor Versionâ€** + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +**1.3. “Contributionâ€** + means Covered Software of a particular Contributor. + +**1.4. “Covered Softwareâ€** + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +**1.5. “Incompatible With Secondary Licensesâ€** + means + +* **(a)** that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or +* **(b)** that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +**1.6. “Executable Formâ€** + means any form of the work other than Source Code Form. + +**1.7. “Larger Workâ€** + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +**1.8. “Licenseâ€** + means this document. + +**1.9. “Licensableâ€** + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +**1.10. “Modificationsâ€** + means any of the following: + +* **(a)** any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or +* **(b)** any new file in Source Code Form that contains any Covered + Software. + +**1.11. “Patent Claims†of a Contributor** + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +**1.12. “Secondary Licenseâ€** + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +**1.13. “Source Code Formâ€** + means the form of the work preferred for making modifications. + +**1.14. “You†(or “Yourâ€)** + means an individual or a legal entity exercising rights under this + License. For legal entities, “You†includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, “control†means **(a)** the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or **(b)** ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +### 2. License Grants and Conditions + +#### 2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +* **(a)** under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and +* **(b)** under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +#### 2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +#### 2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +* **(a)** for any code that a Contributor has removed from Covered Software; + or +* **(b)** for infringements caused by: **(i)** Your and any other third party's + modifications of Covered Software, or **(ii)** the combination of its + Contributions with other software (except as part of its Contributor + Version); or +* **(c)** under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +#### 2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +#### 2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +#### 2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +#### 2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +### 3. Responsibilities + +#### 3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +#### 3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +* **(a)** such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +* **(b)** You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +#### 3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +#### 3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +#### 3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +### 4. Inability to Comply Due to Statute or Regulation + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: **(a)** comply with +the terms of this License to the maximum extent possible; and **(b)** +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +### 5. Termination + +**5.1.** The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated **(a)** provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and **(b)** on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +**5.2.** If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +**5.3.** In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +### 6. Disclaimer of Warranty + +> Covered Software is provided under this License on an “as is†+> basis, without warranty of any kind, either expressed, implied, or +> statutory, including, without limitation, warranties that the +> Covered Software is free of defects, merchantable, fit for a +> particular purpose or non-infringing. The entire risk as to the +> quality and performance of the Covered Software is with You. +> Should any Covered Software prove defective in any respect, You +> (not any Contributor) assume the cost of any necessary servicing, +> repair, or correction. This disclaimer of warranty constitutes an +> essential part of this License. No use of any Covered Software is +> authorized under this License except under this disclaimer. + +### 7. Limitation of Liability + +> Under no circumstances and under no legal theory, whether tort +> (including negligence), contract, or otherwise, shall any +> Contributor, or anyone who distributes Covered Software as +> permitted above, be liable to You for any direct, indirect, +> special, incidental, or consequential damages of any character +> including, without limitation, damages for lost profits, loss of +> goodwill, work stoppage, computer failure or malfunction, or any +> and all other commercial damages or losses, even if such party +> shall have been informed of the possibility of such damages. This +> limitation of liability shall not apply to liability for death or +> personal injury resulting from such party's negligence to the +> extent applicable law prohibits such limitation. Some +> jurisdictions do not allow the exclusion or limitation of +> incidental or consequential damages, so this exclusion and +> limitation may not apply to You. + +### 8. Litigation + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +### 9. Miscellaneous + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +### 10. Versions of the License + +#### 10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +#### 10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +#### 10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +#### 10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +## Exhibit A - Source Code Form License Notice + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +## Exhibit B - “Incompatible With Secondary Licenses†Notice + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/src/Rust/vvs_parser_derive/src/derive.rs b/src/Rust/vvs_parser_derive/src/derive.rs new file mode 100644 index 0000000000000000000000000000000000000000..4d6c5cf9d6761ae7d26742f5968d2f94a382b2da --- /dev/null +++ b/src/Rust/vvs_parser_derive/src/derive.rs @@ -0,0 +1,139 @@ +use proc_macro2::TokenStream; +use quote::{format_ident, quote}; +use syn::{parse_macro_input, DeriveInput}; + +pub trait DeriveGenerator: EnumGenerator + StructGenerator { + fn complete(input: &syn::DeriveInput, tokens: TokenStream) -> TokenStream; + + fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let input = parse_macro_input!(input as DeriveInput); + + let expanded = match &input.data { + syn::Data::Enum(data) => <Self as EnumGenerator>::generate(&input.ident, data), + syn::Data::Struct(data) => <Self as StructGenerator>::generate(&input.ident, data), + _ => unimplemented!(), + }; + + Self::complete(&input, expanded).into() + } +} + +pub trait EnumGenerator { + fn generate(input: &syn::Ident, enumm: &syn::DataEnum) -> TokenStream; +} + +pub trait StructGenerator { + fn generate(input: &syn::Ident, strukt: &syn::DataStruct) -> TokenStream; +} + +pub trait MatchEnumGenerator { + const DEREF: bool = false; + const SELF: &'static str = "self"; + + fn complete(input: TokenStream) -> TokenStream { + input + } + + fn case_named(_input: &syn::Ident, _variant: &syn::Ident, _fields: &syn::FieldsNamed) -> TokenStream { + quote! {} + } + + fn case_unnamed(_input: &syn::Ident, _variant: &syn::Ident, _fields: &syn::FieldsUnnamed) -> TokenStream { + quote! {} + } + + fn case_unit(_input: &syn::Ident, _variant: &syn::Ident) -> TokenStream { + quote! {} + } +} + +impl<T: MatchEnumGenerator> EnumGenerator for T { + fn generate(input_ident: &syn::Ident, enumm: &syn::DataEnum) -> TokenStream { + let mut cases = Vec::with_capacity(enumm.variants.len()); + + for variant in &enumm.variants { + let variant_ident = &variant.ident; + + match &variant.fields { + syn::Fields::Named(fields) => { + cases.push(T::case_named(input_ident, variant_ident, fields)); + } + + syn::Fields::Unnamed(fields) => { + cases.push(T::case_unnamed(input_ident, variant_ident, fields)); + } + + syn::Fields::Unit => cases.push(T::case_unit(input_ident, variant_ident)), + } + } + + let self_ident = format_ident!("{}", T::SELF); + let deref = if T::DEREF { Some(quote! { * }) } else { None }; + + T::complete(quote! { + match #deref #self_ident { + #(#cases)* + } + }) + } +} + +pub trait Hint +where + Self: Sized, +{ + fn key_value(_key: String, _value: String) -> Option<Self> { + None + } + + fn unit(_name: String) -> Option<Self> { + None + } +} + +pub fn search_hint<T: Hint>(name: &str, attrs: &[syn::Attribute]) -> Option<T> { + macro_rules! path_ident { + ($path:expr) => { + match $path.get_ident() { + Some(ident) => ident, + None => continue, + } + }; + } + + for attr in attrs { + let meta = match attr.parse_meta() { + Ok(meta) => meta, + Err(_) => continue, + }; + + if path_ident!(meta.path()) != name { + continue; + }; + + if let syn::Meta::List(list) = meta { + for nested in list.nested { + match nested { + syn::NestedMeta::Meta(syn::Meta::Path(path)) => { + return T::unit(path_ident!(path).to_string()); + } + + syn::NestedMeta::Meta(syn::Meta::NameValue(name_value)) => { + return T::key_value( + path_ident!(name_value.path).to_string(), + match name_value.lit { + syn::Lit::Str(lit_str) => lit_str.value(), + + other => unimplemented!("nested meta value: {:#?}", other), + }, + ); + } + + other => unimplemented!("unknown attribute: {:#?}", other), + } + } + } + } + + None +} diff --git a/src/Rust/vvs_parser_derive/src/lib.rs b/src/Rust/vvs_parser_derive/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..d62ebbc2ed3a1b7313baf43ee36a1d665aa3afc4 --- /dev/null +++ b/src/Rust/vvs_parser_derive/src/lib.rs @@ -0,0 +1,21 @@ +#![recursion_limit = "128"] + +extern crate proc_macro; + +mod derive; +mod node; +mod visit; + +use derive::DeriveGenerator; + +use proc_macro::TokenStream; + +#[proc_macro_derive(Visit, attributes(visit))] +pub fn derive_visit(input: TokenStream) -> TokenStream { + visit::VisitGenerator::derive(input) +} + +#[proc_macro_derive(Node, attributes(node))] +pub fn derive_node(input: TokenStream) -> TokenStream { + node::NodeGenerator::derive(input) +} diff --git a/src/Rust/vvs_parser_derive/src/node.rs b/src/Rust/vvs_parser_derive/src/node.rs new file mode 100644 index 0000000000000000000000000000000000000000..5efb943949dbc6cc61c890b0f2b24e4d6c8d93f4 --- /dev/null +++ b/src/Rust/vvs_parser_derive/src/node.rs @@ -0,0 +1,429 @@ +use crate::derive::*; + +use proc_macro2::TokenStream; +use quote::{format_ident, quote}; + +fn token_getter(ty: &syn::Type, ident: &syn::Ident, mut prefix: Option<TokenStream>, deref: bool) -> TokenStream { + if let syn::Type::Path(path) = ty { + let token_ref = path.path.segments.first().expect("no first segment?"); + + // Clippy suggests *cow.ident, which doesn't work + #[allow(clippy::cmp_owned)] + if token_ref.ident.to_string() == "TokenReference" { + return quote! { + crate::node::TokenItem::TokenReference(&#prefix #ident) + }; + } + } + + if deref { + prefix = Some(quote! { * }); + } + + quote! { + crate::node::TokenItem::MoreTokens(&#prefix #ident) + } +} + +#[derive(PartialEq)] +enum NodeHint { + FullRange, +} + +impl Hint for NodeHint { + fn unit(name: String) -> Option<Self> { + if name == "full_range" { + Some(NodeHint::FullRange) + } else { + None + } + } +} + +pub struct NodeGenerator; + +impl DeriveGenerator for NodeGenerator { + fn complete(input: &syn::DeriveInput, tokens: TokenStream) -> TokenStream { + let input_ident = &input.ident; + let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); + + let macro_name = format_ident!("NodeGenerator{}", input_ident); + + let pattern = quote! {{ + range => $range:expr, + similar => $similar:expr, + tokens => $tokens:expr, + }}; + + quote! { + macro_rules! #macro_name { + ("range", #pattern) => { + $range + }; + + ("similar", #pattern) => { + $similar + }; + + ("tokens", #pattern) => { + $tokens + } + } + + impl #impl_generics crate::node::Node #impl_generics for #input_ident #ty_generics #where_clause { + fn start_position(&self) -> Option<crate::tokenizer::Position> { + Some(#macro_name!("range", { #tokens })?.0) + } + + fn end_position(&self) -> Option<crate::tokenizer::Position> { + Some(#macro_name!("range", { #tokens })?.1) + } + + fn similar(&self, other: &Self) -> bool { + #macro_name!("similar", { #tokens }) + } + + fn tokens<'a>(&'a self) -> crate::node::Tokens<'a> { + #macro_name!("tokens", { #tokens }) + } + } + + impl #impl_generics crate::private::Sealed for #input_ident #ty_generics #where_clause {} + } + } +} + +impl StructGenerator for NodeGenerator { + fn generate(ident: &syn::Ident, strukt: &syn::DataStruct) -> TokenStream { + let range = StructRangeGenerator::generate(ident, strukt); + let similar = StructSimilarGenerator::generate(ident, strukt); + let tokens = StructTokensGenerator::generate(ident, strukt); + + quote! { + range => { #range }, + similar => { #similar }, + tokens => { #tokens }, + } + } +} + +pub struct StructRangeGenerator; + +impl StructGenerator for StructRangeGenerator { + fn generate(_: &syn::Ident, strukt: &syn::DataStruct) -> TokenStream { + let fields = strukt + .fields + .iter() + .map(|field| field.ident.as_ref().unwrap()) + .collect::<Vec<_>>(); + + let full_range = strukt + .fields + .iter() + .find(|field| search_hint("node", &field.attrs) == Some(NodeHint::FullRange)); + + if let Some(full_range) = full_range { + let ident = full_range.ident.as_ref().unwrap(); + quote! { + self.#ident.range() + } + } else { + let (mut start_position, mut end_position) = + (Vec::with_capacity(fields.len()), Vec::with_capacity(fields.len())); + + for field in &fields { + start_position.push(quote! { + .or_else(|| { + self.#field.start_position() + }) + }); + } + + for field in fields.iter().rev() { + end_position.push(quote! { + .or_else(|| { + self.#field.end_position() + }) + }); + } + + quote! { + Some((None #(#start_position)*?, None #(#end_position)*?)) + } + } + } +} + +pub struct StructSimilarGenerator; + +impl StructGenerator for StructSimilarGenerator { + fn generate(_: &syn::Ident, strukt: &syn::DataStruct) -> TokenStream { + let fields = strukt + .fields + .iter() + .map(|field| field.ident.as_ref().unwrap()) + .collect::<Vec<_>>(); + + quote! { + #( + self.#fields.similar(&other.#fields) && + )* true + } + } +} + +pub struct StructTokensGenerator; + +impl StructGenerator for StructTokensGenerator { + fn generate(_: &syn::Ident, strukt: &syn::DataStruct) -> TokenStream { + let mut getters = Vec::with_capacity(strukt.fields.len()); + + for field in &strukt.fields { + getters.push(token_getter( + &field.ty, + field.ident.as_ref().unwrap(), + Some(quote! { + self. + }), + false, + )); + } + + quote! { + crate::node::Tokens { + items: vec![#( + #getters, + )*], + } + } + } +} + +impl EnumGenerator for NodeGenerator { + fn generate(ident: &syn::Ident, enumm: &syn::DataEnum) -> TokenStream { + let range = EnumRangeGenerator::generate(ident, enumm); + let similar = EnumSimilarGenerator::generate(ident, enumm); + let tokens = EnumTokensGenerator::generate(ident, enumm); + + quote! { + range => { + #[allow(unused)] + #range + }, + + similar => { #similar }, + tokens => { #tokens }, + } + } +} + +pub struct EnumRangeGenerator; + +impl MatchEnumGenerator for EnumRangeGenerator { + fn case_named(input: &syn::Ident, variant: &syn::Ident, named: &syn::FieldsNamed) -> TokenStream { + let fields = named + .named + .iter() + .map(|field| field.ident.as_ref().unwrap()) + .collect::<Vec<_>>(); + + let full_range = named + .named + .iter() + .find(|field| search_hint("node", &field.attrs) == Some(NodeHint::FullRange)); + + let body = if let Some(full_range) = full_range { + let ident = full_range.ident.as_ref().unwrap(); + quote! { + #ident.range() + } + } else { + let (mut start_position, mut end_position) = + (Vec::with_capacity(fields.len()), Vec::with_capacity(fields.len())); + + for field in &fields { + start_position.push(quote! { + .or_else(|| { + #field.start_position() + }) + }); + } + + for field in fields.iter().rev() { + end_position.push(quote! { + .or_else(|| { + #field.end_position() + }) + }); + } + + quote! { + Some((None #(#start_position)*?, None #(#end_position)*?)) + } + }; + + quote! { + #input::#variant { + #(#fields,)* + } => { + #body + } + } + } + + fn case_unnamed(input: &syn::Ident, variant: &syn::Ident, fields: &syn::FieldsUnnamed) -> TokenStream { + let fields = &fields.unnamed; + + if fields.len() == 1 { + quote! { + #input::#variant(inner) => { + Some((inner.start_position()?, inner.end_position()?)) + } + } + } else { + let fields_count = fields.len() - 1; + let field_match: Vec<_> = fields + .iter() + .enumerate() + .map(|(index, _)| { + syn::Ident::new( + match index { + 0 => "first", + _x if _x == fields_count => "last", + _ => "_", + }, + variant.span(), + ) + }) + .collect(); + + quote! { + #input::#variant( + #(#field_match,)* + ) => { + Some((first.start_position()?, last.end_position()?)) + } + } + } + } +} + +pub struct EnumSimilarGenerator; + +impl MatchEnumGenerator for EnumSimilarGenerator { + fn case_named(input: &syn::Ident, variant: &syn::Ident, named: &syn::FieldsNamed) -> TokenStream { + let fields = named + .named + .iter() + .map(|field| field.ident.as_ref().unwrap()) + .collect::<Vec<_>>(); + + let other_fields: Vec<_> = fields.iter().map(|ident| format_ident!("other_{}", ident)).collect(); + + quote! { + #input::#variant { + #(#fields,)* + } => { + if let #input::#variant { + #( + #fields: #other_fields, + )* + } = &other { + #( + #fields.similar(#other_fields) && + )* true + } else { + false + } + } + } + } + + fn case_unnamed(input: &syn::Ident, variant: &syn::Ident, fields: &syn::FieldsUnnamed) -> TokenStream { + let fields: Vec<_> = fields + .unnamed + .iter() + .enumerate() + .map(|(index, _)| format_ident!("__self_{}", index)) + .collect(); + + let other_fields: Vec<_> = fields.iter().map(|ident| format_ident!("other_{}", ident)).collect(); + + quote! { + #input::#variant( + #(#fields,)* + ) => { + if let #input::#variant(#(#other_fields,)*) = &other { + #( + #fields.similar(#other_fields) && + )* true + } else { + false + } + } + } + } + + fn case_unit(input: &syn::Ident, variant: &syn::Ident) -> TokenStream { + quote! { + #input::#variant => other == #input::#variant + } + } +} + +pub struct EnumTokensGenerator; + +impl MatchEnumGenerator for EnumTokensGenerator { + const DEREF: bool = true; + + fn case_named(input: &syn::Ident, variant: &syn::Ident, named: &syn::FieldsNamed) -> TokenStream { + let named = &named.named; + + let mut fields = Vec::with_capacity(named.len()); + let mut getters = Vec::with_capacity(named.len()); + + for field in named { + fields.push(field.ident.as_ref().unwrap()); + getters.push(token_getter(&field.ty, field.ident.as_ref().unwrap(), None, true)); + } + + quote! { + #input::#variant { + #(ref #fields,)* + } => { + crate::node::Tokens { + items: vec![#( + #getters, + )*], + } + } + } + } + + fn case_unnamed(input: &syn::Ident, variant: &syn::Ident, fields: &syn::FieldsUnnamed) -> TokenStream { + let names: Vec<_> = fields + .unnamed + .iter() + .enumerate() + .map(|(index, _)| format_ident!("__self_{}", index)) + .collect(); + + let mut getters = Vec::with_capacity(fields.unnamed.len()); + + for (field, name) in fields.unnamed.iter().zip(&names) { + getters.push(token_getter(&field.ty, name, None, true)); + } + + quote! { + #input::#variant( + #(ref #names,)* + ) => { + crate::node::Tokens { + items: vec![#( + #getters, + )*], + } + } + } + } +} diff --git a/src/Rust/vvs_parser_derive/src/visit.rs b/src/Rust/vvs_parser_derive/src/visit.rs new file mode 100644 index 0000000000000000000000000000000000000000..2eb585ca08bbd317dcaf69ef218cf05c8f5d91d7 --- /dev/null +++ b/src/Rust/vvs_parser_derive/src/visit.rs @@ -0,0 +1,264 @@ +use crate::derive::*; +use proc_macro2::TokenStream; +use quote::{format_ident, quote}; +use std::collections::HashMap; + +// Not 100% accurate, but it is to full-moon's codebase +fn snake_case(pascal_case: &str) -> String { + let mut chars = pascal_case.chars(); + let mut result = chars.next().unwrap().to_ascii_lowercase().to_string(); + + for character in chars { + if character.is_ascii_uppercase() { + result.push('_'); + result.push(character.to_ascii_lowercase()); + } else { + result.push(character); + } + } + + result +} + +#[derive(Debug, PartialEq)] +enum VisitHint { + Contains(String), + Skip, + SkipVisitSelf, + VisitAs(String), +} + +impl Hint for VisitHint { + fn key_value(key: String, value: String) -> Option<Self> { + if key == "visit_as" { + Some(VisitHint::VisitAs(value)) + } else if key == "contains" { + Some(VisitHint::Contains(value)) + } else { + None + } + } + + fn unit(name: String) -> Option<Self> { + match name.as_str() { + "skip" => Some(VisitHint::Skip), + "skip_visit_self" => Some(VisitHint::SkipVisitSelf), + _ => None, + } + } +} + +pub struct VisitGenerator; + +impl VisitGenerator { + fn visit_fields(data_fields: &syn::Fields, prefix: TokenStream) -> TokenStream { + let mut fields = Vec::new(); + let mut contains = HashMap::new(); + + for field in data_fields + .iter() + .filter(|field| search_hint("visit", &field.attrs) != Some(VisitHint::Skip)) + { + let ident = field.ident.as_ref().unwrap(); + let token_stream = quote! { #prefix #ident }; + + if let Some(VisitHint::Contains(contains_node)) = search_hint("visit", &field.attrs) { + contains.insert(contains_node, ident); + } else if let Some(contains_me) = contains.remove(&ident.to_string()) { + fields.push(quote! { + #prefix #contains_me.tokens.0 + }); + + fields.push(token_stream); + + fields.push(quote! { + #prefix #contains_me.tokens.1 + }); + } else { + fields.push(token_stream); + } + } + + assert!(contains.is_empty(), "#[visit(contains = \"...\")] used in wrong order: {contains:?}",); + + quote! { + #(visit!(#fields, visitor);)* + } + } +} + +impl DeriveGenerator for VisitGenerator { + fn complete(input: &syn::DeriveInput, tokens: TokenStream) -> TokenStream { + let input_ident = &input.ident; + let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); + + let (visit_self, visit_self_end) = match search_hint("visit", &input.attrs) { + Some(VisitHint::SkipVisitSelf) => (quote! {}, quote! {}), + Some(VisitHint::VisitAs(visit_as)) => { + let visit_as_end = syn::Ident::new(&format!("visit_{visit_as}_end"), input_ident.span()); + let visit_as = syn::Ident::new(&format!("visit_{visit_as}"), input_ident.span()); + + ( + quote! { + visit_self!(#visit_as); + }, + quote! { + visit_self!(#visit_as_end); + }, + ) + } + _ => { + // name of self in snake_case + let ssself = + syn::Ident::new(&format!("visit_{}", snake_case(&input_ident.to_string())), input_ident.span()); + + let ssself_end = + syn::Ident::new(&format!("visit_{}_end", snake_case(&input_ident.to_string())), input_ident.span()); + + ( + quote! { + visit_self!(#ssself); + }, + quote! { + visit_self!(#ssself_end); + }, + ) + } + }; + + quote! { + #[allow(unused_macros)] + impl #impl_generics crate::visitors::Visit for #input_ident #ty_generics #where_clause { + fn visit<V: crate::visitors::Visitor>(&self, visitor: &mut V) { + macro_rules! visit { + ($visit_what: expr, $visitor: expr) => { + $visit_what.visit($visitor); + } + } + + macro_rules! visit_self { + ($name: ident) => { + visitor.$name(self); + } + } + + macro_rules! set_self { + ($value: expr) => { + $value; + } + } + + macro_rules! if_visit { + ({ $($used: expr)* } else { $($unused: expr)* }) => { + { + $($used;)* + } + } + } + + #visit_self + #tokens + #visit_self_end + } + } + + #[allow(unused_macros)] + impl #impl_generics crate::visitors::VisitMut for #input_ident #ty_generics #where_clause { + fn visit_mut<V: crate::visitors::VisitorMut>(mut self, visitor: &mut V) -> Self { + macro_rules! visit { + ($visit_what: expr, $visitor: expr) => { + $visit_what = $visit_what.visit_mut($visitor); + } + } + + macro_rules! visit_self { + ($name: ident) => { + self = visitor.$name(self); + } + } + + macro_rules! set_self { + ($value: expr) => { + self = $value; + } + } + + macro_rules! if_visit { + ({ $($unused: expr)* } else { $($used: expr)* }) => { + $($used)* + } + } + + #visit_self + #tokens + #visit_self_end + self + } + } + } + } +} + +impl StructGenerator for VisitGenerator { + fn generate(_: &syn::Ident, strukt: &syn::DataStruct) -> TokenStream { + Self::visit_fields(&strukt.fields, quote! {self.}) + } +} + +impl MatchEnumGenerator for VisitGenerator { + fn complete(input: TokenStream) -> TokenStream { + quote! { + set_self!(#input); + } + } + + fn case_named(input: &syn::Ident, variant: &syn::Ident, named: &syn::FieldsNamed) -> TokenStream { + let fields: Vec<_> = named.named.iter().map(|field| field.ident.as_ref().unwrap()).collect(); + + quote! { + #input::#variant { + #(#fields,)* + } => { + if_visit!({ + #( + #fields.visit(visitor) + )* + } else { + #input::#variant { + #( + #fields: #fields.visit_mut(visitor), + )* + } + }) + } + } + } + + fn case_unnamed(input: &syn::Ident, variant: &syn::Ident, fields: &syn::FieldsUnnamed) -> TokenStream { + let fields: Vec<_> = fields + .unnamed + .iter() + .enumerate() + .map(|(index, _)| format_ident!("__self_{}", index)) + .collect(); + let fields = &fields; + + quote! { + #input::#variant( + #(#fields,)* + ) => { + if_visit!({ + #( + #fields.visit(visitor) + )* + } else { + #input::#variant( + #( + #fields.visit_mut(visitor), + )* + ) + }) + } + } + } +} diff --git a/src/Rust/vvs_procmacro/Cargo.toml b/src/Rust/vvs_procmacro/Cargo.toml index 3e99f27c4f2c4e3f9b13b4b8108390ba1fc94874..a2e00d0e0d56768f33c529876d51decc8c0d35fc 100644 --- a/src/Rust/vvs_procmacro/Cargo.toml +++ b/src/Rust/vvs_procmacro/Cargo.toml @@ -1,15 +1,17 @@ [package] -name = "vvs_procmacro" +name = "vvs_procmacro" +description = "The procmacro utility crate for VVS" version.workspace = true authors.workspace = true edition.workspace = true license.workspace = true -description = "The procmacro utility crate for VVS" [lib] proc-macro = true [dependencies] -syn = { version = "2.0", features = ["full"] } -quote = "1.0" -proc-macro2 = "1.0" +quote.workspace = true +proc-macro2.workspace = true +anyhow.workspace = true + +syn = { version = "2", features = ["full"] } diff --git a/src/Rust/vvs_procmacro/src/enums.rs b/src/Rust/vvs_procmacro/src/enums.rs new file mode 100644 index 0000000000000000000000000000000000000000..54d115eda51068d501bfc5706f1e939fbd3b8f4f --- /dev/null +++ b/src/Rust/vvs_procmacro/src/enums.rs @@ -0,0 +1,62 @@ +//! Implement what is needed to make life easier with C-like enums in Rust. + +use proc_macro2::*; +use quote::*; + +pub(crate) fn impl_derive_enum_variant_count(syn_item: syn::DeriveInput) -> TokenStream { + let (len, name) = match syn_item.data { + syn::Data::Enum(enum_item) => ( + enum_item.variants.len(), + Ident::new(&format!("{}_LENGTH", syn_item.ident.to_string().to_uppercase()), syn_item.ident.span()), + ), + _ => panic!("EnumVariantCount only works on Enums"), + }; + quote! { pub const #name : usize = #len; } +} + +pub(crate) fn impl_derive_enum_variant_iter(syn_item: syn::DeriveInput) -> TokenStream { + let (enum_name, name, content) = match syn_item.data { + syn::Data::Enum(enum_item) => { + let variants = enum_item + .variants + .into_iter() + .map(|variant| format!("{}::{}", syn_item.ident, variant.ident)); + let variants = variants.collect::<Vec<_>>().join(", "); + ( + syn_item.ident.clone(), + Ident::new(&format!("{}_VALUES", syn_item.ident.to_string().to_uppercase()), syn_item.ident.span()), + syn::parse_str::<syn::Expr>(&format!("&[ {variants} ]")) + .expect("failed generation of enum's variant list"), + ) + } + _ => panic!("EnumVariantIter only works on Enums"), + }; + quote! { pub const #name : &[#enum_name] = #content; } +} + +pub(crate) fn impl_derive_enum_variant_from_str(syn_item: syn::DeriveInput) -> TokenStream { + let enum_item = match syn_item.data { + syn::Data::Enum(enum_item) => enum_item, + _ => panic!("EnumVariantFromStr only works on Enums"), + }; + let name = syn_item.ident; + let match_branches = enum_item + .variants + .into_iter() + .map(|variant| format!("{:?} => Ok({name}::{}),", variant.ident.to_string().to_lowercase(), variant.ident)) + .chain(Some("_ => Err(format!(\"unknown field '{{s}}'\")),".to_string())) + .collect::<Vec<_>>() + .join(""); + let match_branches = + syn::parse_str::<syn::Expr>(&format!("match s.trim().to_lowercase().as_str() {{ {match_branches} }}")) + .expect("failed generation of enum's FromStr implementation"); + quote! { + impl std::str::FromStr for #name { + type Err = std::string::String; + fn from_str(s: &str) -> std::result::Result<Self, Self::Err> { + #match_branches + } + + } + } +} diff --git a/src/Rust/vvs_procmacro/src/lib.rs b/src/Rust/vvs_procmacro/src/lib.rs index 64bbd40ddfc3d205048f3e5b2ecc4bb5eb0800f6..3085206b376fbe293412f6efffd2524b691d8618 100644 --- a/src/Rust/vvs_procmacro/src/lib.rs +++ b/src/Rust/vvs_procmacro/src/lib.rs @@ -1,85 +1,63 @@ -#![forbid(unsafe_code)] +mod enums; +mod vvrt; use proc_macro::TokenStream; -use proc_macro2::*; -use quote::*; -use syn::{parse_macro_input, DeriveInput}; +use quote::quote; +use syn::parse_macro_input; #[proc_macro_derive(EnumVariantCount)] pub fn derive_enum_variant_count(input: TokenStream) -> TokenStream { - let syn_item = parse_macro_input!(input as DeriveInput); - let (len, name) = match syn_item.data { - syn::Data::Enum(enum_item) => ( - enum_item.variants.len(), - Ident::new( - &format!("{}_LENGTH", syn_item.ident.to_string().to_uppercase()), - syn_item.ident.span(), - ), - ), - _ => panic!("EnumVariantCount only works on Enums"), - }; - quote! { pub const #name : usize = #len; }.into() + let input = parse_macro_input!(input as syn::DeriveInput); + enums::impl_derive_enum_variant_count(input).into() } #[proc_macro_derive(EnumVariantIter)] pub fn derive_enum_variant_iter(input: TokenStream) -> TokenStream { - let syn_item = parse_macro_input!(input as DeriveInput); - let (enum_name, name, content) = match syn_item.data { - syn::Data::Enum(enum_item) => ( - syn_item.ident.clone(), - Ident::new( - &format!("{}_VALUES", syn_item.ident.to_string().to_uppercase()), - syn_item.ident.span(), - ), - syn::parse_str::<syn::Expr>(&format!( - "&[ {} ]", - enum_item - .variants - .into_iter() - .map(|variant| format!("{}::{}", syn_item.ident, variant.ident)) - .collect::<Vec<_>>() - .join(", "), - )) - .expect("failed generation of enum's variant list"), - ), - _ => panic!("EnumVariantIter only works on Enums"), - }; - quote! { pub const #name : &[#enum_name] = #content; }.into() + let input = parse_macro_input!(input as syn::DeriveInput); + enums::impl_derive_enum_variant_iter(input).into() } #[proc_macro_derive(EnumVariantFromStr)] pub fn derive_enum_variant_from_str(input: TokenStream) -> TokenStream { - let syn_item = parse_macro_input!(input as DeriveInput); - let enum_item = match syn_item.data { - syn::Data::Enum(enum_item) => enum_item, - _ => panic!("EnumVariantFromStr only works on Enums"), - }; - let name = syn_item.ident; - let match_branches = enum_item - .variants - .into_iter() - .map(|variant| { - format!( - "{:?} => Ok({name}::{}),", - variant.ident.to_string().to_lowercase(), - variant.ident - ) - }) - .chain(Some("_ => Err(format!(\"unknown field '{{s}}'\")),".to_string())) - .collect::<Vec<_>>() - .join(""); - let match_branches = syn::parse_str::<syn::Expr>(&format!( - "match s.trim().to_lowercase().as_str() {{ {match_branches} }}" - )) - .expect("failed generation of enum's FromStr implementation"); - quote! { - impl std::str::FromStr for #name { - type Err = std::string::String; - fn from_str(s: &str) -> std::result::Result<Self, Self::Err> { - #match_branches - } + let input = parse_macro_input!(input as syn::DeriveInput); + enums::impl_derive_enum_variant_from_str(input).into() +} + +/// Processes everything to create the export rule for LLVM. We will rename the functions +/// accordingly. +/// +/// You need to have the `ManageFunctions` and `Properties` in scope to use this macro. +/// +/// Re-export what is inside the module for `super`. With the name passed as argument we export the +/// function `{name}_llvm_properties` that will returns the properties for LLVM. +#[proc_macro_attribute] +pub fn vvrt_bridge(arg: TokenStream, input: TokenStream) -> TokenStream { + let name = parse_macro_input!(arg as syn::Ident); + let module = parse_macro_input!(input as syn::ItemMod); + + let (module, funcs) = vvrt::impl_vvrt_bridge(name.to_string(), module).unwrap(); + let module_name = &module.ident; - } + let has_clone = funcs.iter().any(|(_, role, ..)| { + role.as_ref() + .map(|role| matches!(role, vvrt::Role::Clone)) + .unwrap_or_default() + }); + let has_drop = funcs.iter().any(|(_, role, ..)| { + role.as_ref() + .map(|role| matches!(role, vvrt::Role::Drop)) + .unwrap_or_default() + }); + if has_clone ^ has_drop { + panic!("you can't have a drop implementation without the clone one, or the other way around") + } + + let funcs = vvrt::gen_method_infos(name, funcs).unwrap(); + + quote! { + #module + pub(super) use self::#module_name::*; + #funcs } .into() } diff --git a/src/Rust/vvs_procmacro/src/vvrt/gen.rs b/src/Rust/vvs_procmacro/src/vvrt/gen.rs new file mode 100644 index 0000000000000000000000000000000000000000..6ad18aa2ffb8269090d0957a633ac03792a89a9b --- /dev/null +++ b/src/Rust/vvs_procmacro/src/vvrt/gen.rs @@ -0,0 +1,134 @@ +use crate::vvrt::{MethodInfo, Role, Type}; +use anyhow::bail; +use proc_macro2::TokenStream; +use quote::quote; + +fn gen_type_call(ty: &Type, arg: &syn::Ident) -> TokenStream { + match ty { + Type::None => quote! { LLVMVoidTypeInContext(#arg) }, + Type::Integer => quote! { LLVMInt32TypeInContext(#arg) }, + Type::Floating => quote! { LLVMFloatTypeInContext(#arg) }, + Type::Boolean => quote! { LLVMInt1TypeInContext(#arg) }, + Type::StrPtr => quote! { LLVMPointerTypeInContext(#arg, 0) }, + Type::VVRT(vvrt) => { + let vvrt = syn::Ident::new(vvrt, arg.span()); + quote! { #vvrt::llvm_type(#arg) } + } + } +} + +fn get_asttype(ty: &Type) -> TokenStream { + match ty { + Type::None => quote! { ASTType::Nil }, + Type::Integer => quote! { ASTType::Integer }, + Type::Floating => quote! { ASTType::Floating }, + Type::Boolean => quote! { ASTType::Boolean }, + Type::StrPtr => quote! { ASTType::String }, + Type::VVRT("VVRTString") => quote! { ASTType::String }, + Type::VVRT("VVRTTable") => quote! { ASTType::AnyTable }, + Type::VVRT("VVRTSeq") => quote! { ASTType::AnySequence }, + Type::VVRT("VVRTAny") => quote! { ASTType::Any }, + Type::VVRT("VVRTVariant") => quote! { ASTType::Variant }, + Type::VVRT("VVRTType") => quote! { ASTType::Integer }, + Type::VVRT("VVRTLine") => quote! { ASTType::Line }, + Type::VVRT("VVRTSyllabe") => quote! { ASTType::Syllabe }, + ty => unreachable!("unknown type {ty:?}"), + } +} + +pub(crate) fn gen_method_infos(name: syn::Ident, infos: Vec<MethodInfo>) -> anyhow::Result<TokenStream> { + macro_rules! get_manage { + ($role: ident) => { + infos + .iter() + .find_map(|(name, role, ..)| matches!(role, Some(Role::$role)).then_some(name.as_str())) + }; + } + + macro_rules! opt_string { + ($expr: expr) => { + match $expr { + None => quote! { None }, + Some(str) => quote! { Some(#str) }, + } + }; + } + + macro_rules! quote_vec { + ($inner: expr) => { + match $inner { + Some(inner) => quote! { vec![#inner] }, + None => quote! { vec![] }, + } + }; + } + + let arg = syn::Ident::new("c", name.span()); + + let manage_len = opt_string!(get_manage!(Len)); + let manage_eq = opt_string!(get_manage!(Eq)); + + let manage = match (get_manage!(Drop), get_manage!(Clone)) { + (None, None) => quote! { None }, + (Some(drop), Some(clone)) => quote! { + Some(ManageFunctions { + clone: #clone, + drop: #drop, + }) + }, + _ => bail!("clone and drop functions must be present at the same time, or none of them"), + }; + + let methods = infos.into_iter().map(|(name, _, args, returns)| { + let llvm_returns = gen_type_call(&returns, &arg); + let llvm_args_len: u32 = args.len().try_into().expect("too many arguments"); + let llvm_args = quote_vec!(args + .iter() + .map(|ty| gen_type_call(ty, &arg)) + .reduce(|acc, item| quote! { #acc, #item })); + + let ast_returns = get_asttype(&returns); + let ast_args = quote_vec!(args + .into_iter() + .map(|ty| get_asttype(&ty)) + .reduce(|acc, item| quote! { #acc, #item })); + + let func = syn::Ident::new(&name, arg.span()); + + quote! {{ + let func: unsafe extern "C" fn() = unsafe { std::mem::transmute(#func as *const ()) }; + let mut llvm_args = #llvm_args; // We compute the vector here for safety. + let ast_type = ASTType::Function(#ast_args, Box::new(#ast_returns)); // Also needs the ast type. + let functy = vvs_llvm::LLVMFunctionType( + #llvm_returns, // Should be Ok there. + llvm_args.as_mut_ptr(), #llvm_args_len, // We pre-computed the length here. + 0 // No variadic functions there. + ); + (#name, (func, functy, ast_type)) + }} + }); + let methods = quote_vec!(methods.reduce(|acc, item| quote! { #acc, #item })); + + Ok(quote! { + impl LLVMExported for #name { + unsafe fn llvm_type(c: LLVMContextRef) -> LLVMTypeRef { + #[allow(dead_code)] + static SIZE_IS_VALID: () = { + assert!(std::mem::size_of::<#name>() == 8); + assert!(std::mem::align_of::<#name>() == 8); + }; + LLVMPointerTypeInContext(c, 0) + } + + unsafe fn llvm_properties(c: LLVMContextRef) -> Properties { + use vvs_lang::ast::ASTType; + Properties { + manage: #manage, + equality: #manage_eq, + len: #manage_len, + methods: hashbrown::HashMap::from_iter(#methods), + } + } + } + }) +} diff --git a/src/Rust/vvs_procmacro/src/vvrt/mod.rs b/src/Rust/vvs_procmacro/src/vvrt/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..d4b671d0f4a778d3859f02f966f915c83d7bbd8d --- /dev/null +++ b/src/Rust/vvs_procmacro/src/vvrt/mod.rs @@ -0,0 +1,75 @@ +//! Utility macros used in the Vivy Script Runtime. + +mod gen; +mod structs; + +pub(crate) use self::{gen::*, structs::*}; + +use anyhow::anyhow; +use proc_macro2::{Ident, TokenStream, TokenTree}; +use quote::quote; +use quote::ToTokens; +use syn::{ + token::{Pub, Unsafe}, + Generics, Visibility, +}; + +fn handle_function(name: &str, func: &mut syn::ItemFn) -> anyhow::Result<MethodInfo> { + func.vis = Visibility::Public(Pub::default()); + func.sig.asyncness = None; + func.sig.unsafety = Some(Unsafe::default()); + func.sig.constness = None; + func.sig.variadic = None; + func.sig.generics = Generics::default(); + + let func_name = func.sig.ident.to_string().to_lowercase(); + let role = Role::try_from(func_name.as_str()).ok(); + let func_name = format!("{name}_{}", func_name); + func.sig.ident = Ident::new(&func_name, func.sig.ident.span()); + + let args = func.sig.inputs.iter().map(|inputs| { + Type::try_from( + syn::parse2::<syn::Type>( + inputs + .to_token_stream() + .into_iter() + .skip_while(|tok| !matches!(tok, TokenTree::Punct(p) if p.as_char() == ':')) + .skip(1) + .collect::<TokenStream>(), + ) + .unwrap(), + ) + }); + let args = args.collect::<Result<Vec<_>, _>>()?; + + // Skip the arrow + let returns = if func.sig.output.to_token_stream().into_iter().count().eq(&0) { + Type::None + } else { + let returns = func.sig.output.to_token_stream().into_iter().skip(2); + Type::try_from(syn::parse2::<syn::Type>(returns.collect())?)? + }; + + Ok((func_name, role, args, returns)) +} + +pub(crate) fn impl_vvrt_bridge( + name: String, + mut module: syn::ItemMod, +) -> anyhow::Result<(syn::ItemMod, Vec<MethodInfo>)> { + if let Some((_, items)) = module.content.as_mut() { + let funcs = items.iter_mut().map(|item| match item { + syn::Item::Fn(item) => handle_function(&name, item).map(Some), + _ => Ok(None), + }); + let funcs = funcs + .collect::<Result<Vec<_>, _>>()? + .into_iter() + .flatten() + .collect::<Vec<_>>(); + items.push(syn::parse2(quote! { use super::*; })?); + Ok((module, funcs)) + } else { + Err(anyhow!("expected a module")) + } +} diff --git a/src/Rust/vvs_procmacro/src/vvrt/structs.rs b/src/Rust/vvs_procmacro/src/vvrt/structs.rs new file mode 100644 index 0000000000000000000000000000000000000000..3ca09db62b4602723394d731e83309ef21c19def --- /dev/null +++ b/src/Rust/vvs_procmacro/src/vvrt/structs.rs @@ -0,0 +1,69 @@ +use anyhow::anyhow; +use quote::ToTokens; + +pub(crate) type MethodInfo = (String, Option<Role>, Vec<Type>, Type); + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) enum Role { + Clone, + Eq, + Drop, + Len, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[allow(clippy::upper_case_acronyms)] +pub(crate) enum Type { + /// Void, None, Null, etc. + None, + + /// Special type for the `*const u8` type. We only have const pointers here. This is used to + /// create strings from static slices... + StrPtr, + + /// Integers, we use 32 bit integers. + Integer, + + /// Floating numbers, we use 32 bit floats. + Floating, + + /// Boolean. + Boolean, + + /// A builtin VVRT type (Vivy Script Runtime) + VVRT(&'static str), +} + +impl TryFrom<&str> for Role { + type Error = anyhow::Error; + fn try_from(value: &str) -> Result<Self, Self::Error> { + match value.to_lowercase().as_ref() { + "clone" => Ok(Self::Clone), + "eq" => Ok(Self::Eq), + "drop" => Ok(Self::Drop), + "len" => Ok(Self::Len), + str => Err(anyhow!("unknown role `{str}`")), + } + } +} + +impl TryFrom<syn::Type> for Type { + type Error = anyhow::Error; + fn try_from(value: syn::Type) -> Result<Self, Self::Error> { + match value { + syn::Type::Path(path) => match &path.path.require_ident()?.to_string()[..] { + str if str.starts_with("VVRT") => Ok(Type::VVRT(String::leak(str.to_string()))), + "i32" => Ok(Type::Integer), + "f32" => Ok(Type::Floating), + "bool" => Ok(Type::Boolean), + "()" => Ok(Type::None), + str => Err(anyhow!("unknown type `{str}`")), + }, + syn::Type::Ptr(inner) => match *inner.elem { + syn::Type::Path(ty) if ty.path.require_ident()? == "u8" => Ok(Type::StrPtr), + ty => Err(anyhow!("expected u8 to form string pointer, got: {}", ty.into_token_stream().to_string())), + }, + ty => Err(anyhow!("type can't be casted into base_type: {}", ty.into_token_stream().to_string())), + } + } +} diff --git a/src/Rust/vvs_runtime/Cargo.toml b/src/Rust/vvs_runtime/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..fe6bd029299748f0c4045f9e40e4902b66806479 --- /dev/null +++ b/src/Rust/vvs_runtime/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "vvs_runtime" +description = "The runtime for Vivy Script" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +log.workspace = true +anyhow.workspace = true +serde.workspace = true +serde_json.workspace = true + +vvs_runtime_types.workspace = true +vvs_utils.workspace = true +vvs_llvm.workspace = true + +[build-dependencies] +anyhow.workspace = true +vvs_llvm = { workspace = true, features = ["link"] } diff --git a/src/Rust/vvs_runtime/build.rs b/src/Rust/vvs_runtime/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..a01480722a65c2a0de92058e860bdc41610328d4 --- /dev/null +++ b/src/Rust/vvs_runtime/build.rs @@ -0,0 +1,3 @@ +fn main() -> anyhow::Result<()> { + vvs_llvm::build::llvm_link() +} diff --git a/src/Rust/vvs_runtime/src/jit.rs b/src/Rust/vvs_runtime/src/jit.rs new file mode 100644 index 0000000000000000000000000000000000000000..953bc4aeb79ac6995deb15747a908c75aaf8f72e --- /dev/null +++ b/src/Rust/vvs_runtime/src/jit.rs @@ -0,0 +1,157 @@ +use crate::workers::Workers; +use anyhow::{bail, Context}; +use std::{ + ffi::{c_int, c_void, CStr, CString}, + ptr, + sync::{ + atomic::{AtomicU64, Ordering}, + Arc, + }, +}; +use vvs_llvm::*; +use vvs_runtime_types::VVRTSymbol; + +#[allow(dead_code)] +pub struct JIT { + jit: *mut LLVMOrcOpaqueLLJIT, + es: *mut LLVMOrcOpaqueExecutionSession, + + tsctx: *mut LLVMOrcOpaqueThreadSafeContext, + + irtl: *mut LLVMOrcOpaqueIRTransformLayer, + objl: *mut LLVMOrcOpaqueObjectLayer, + dylib: *mut LLVMOrcOpaqueJITDylib, + + workers: Workers, +} + +macro_rules! llvm_expect { + (unsafe $err: expr, $msg: literal $(, $arg: expr)* $(,)?) => {{ + unsafe { llvm_expect!($err, $msg $(, $arg)*) } + }}; + + ($err: expr, $msg: literal $(, $arg: expr)* $(,)?) => {{ + let err = $err; + if !err.is_null() { + let msg = std::ffi::CStr::from_ptr(LLVMGetErrorMessage(err)) + .to_string_lossy() + .to_string(); + LLVMConsumeError(err); + bail!("{}: {}", format_args!($msg, $(, $arg)*), msg) + } + }}; +} + +/// This function should be visible because it starts with `VVRT` +#[allow(non_snake_case)] +pub extern "C" fn VVRTHelloWorld() { + println!("Hello World from LLVM JIT"); +} + +/// This function should not be visible because it doesn't start with `VVRT` +pub extern "C" fn hello_world() { + println!("wtf !?"); +} + +extern "C" fn orc_sym_filter(_: *mut c_void, sym: LLVMOrcSymbolStringPoolEntryRef) -> c_int { + eprintln!("toto"); + let Ok(sym) = unsafe { CStr::from_ptr(LLVMOrcSymbolStringPoolEntryStr(sym)) }.to_str() else { + log::error!("got a symbol which name was not valid utf8 from orc"); + return 0; + }; + sym.starts_with("VVRT") as c_int +} + +impl JIT { + /// Create a new JIT thingy to execute Vivy Script code. + pub fn new() -> anyhow::Result<JIT> { + if let Err(err) = vvs_llvm::initialize_llvm() { + log::error!("{err}"); + } + + unsafe { + // Create the jit. + let mut jit = ptr::null_mut(); + let mut tmb = ptr::null_mut(); + llvm_expect!(LLVMOrcJITTargetMachineBuilderDetectHost(&mut tmb), "failed to create orc jit builder"); + + let jit_builder = LLVMOrcCreateLLJITBuilder(); + LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(jit_builder, tmb); + llvm_expect!(LLVMOrcCreateLLJIT(&mut jit, jit_builder), "failed to create the orc jit"); + + log::debug!("got data layout: {}", CStr::from_ptr(LLVMOrcLLJITGetDataLayoutStr(jit)).to_string_lossy()); + + // Create things, in this order. + let es = LLVMOrcLLJITGetExecutionSession(jit); + let objl = LLVMOrcCreateRTDyldObjectLinkingLayerWithSectionMemoryManager(es); + let irtl = LLVMOrcLLJITGetIRTransformLayer(jit); + let dylib = LLVMOrcExecutionSessionCreateBareJITDylib(es, b"<main>\0".as_ptr() as *const _); + + // Allow to search for symbols in the current process, only if they start with `VVRT`. + let mut dg = std::ptr::null_mut(); + llvm_expect!( + LLVMOrcCreateDynamicLibrarySearchGeneratorForProcess( + &mut dg, + LLVMOrcLLJITGetGlobalPrefix(jit), + Some(orc_sym_filter), + std::ptr::null_mut() + ), + "failed to create an orc dylib search generator for the current process" + ); + LLVMOrcJITDylibAddGenerator(dylib, dg); + + // Ok. Create workers and return the struct. + let tsctx = LLVMOrcCreateNewThreadSafeContext(); + let workers = Workers::new(|flag: Arc<AtomicU64>| loop { + match flag.load(Ordering::SeqCst) { + 0 => std::thread::yield_now(), + u64::MAX => return Ok(()), + x => bail!("won't handle work package n°{x}"), + } + })?; + Ok(JIT { jit, es, dylib, tsctx, irtl, objl, workers }) + } + } + + /// Get the context out of the JIT thingy. Used to create a LLVM module to be used latter by + /// the JIT. + pub fn ctx(&self) -> LLVMContextRef { + unsafe { LLVMOrcThreadSafeContextGetContext(self.tsctx) } + } + + /// Add a new module to the JIT engine. + /// + /// # Safety + /// The passed module ([LLVMModuleRef]) must not be a null pointer and must be a valid LLVM + /// module with valid code for the runtime. This module should be created by the [vvs_codegen] + /// crate or you can have problems executing it... + pub unsafe fn add_module(&self, module: LLVMModuleRef) -> anyhow::Result<()> { + let tsm = LLVMOrcCreateNewThreadSafeModule(module, self.tsctx); + let rc = LLVMOrcLLJITAddLLVMIRModule(self.jit, self.dylib, tsm); + llvm_expect!(rc, "failed to add the module into the jit"); + Ok(()) + } + + /// LookUp a symbol defined in the JIT. + pub fn lookup<'a>(&self, name: &'a str) -> anyhow::Result<VVRTSymbol<'a>> { + let mut addr = Default::default(); + let symbol = VVRTSymbol::try_from(name)?; + let str = CString::new(name).with_context(|| "CString::new failed")?; + llvm_expect!(unsafe + LLVMOrcLLJITLookup(self.jit, &mut addr, str.as_ptr()), + "failed to lookup symbol `{name}`" + ); + Ok(symbol.with_addr(addr)) + } +} + +impl Drop for JIT { + fn drop(&mut self) { + self.workers.pre_drop(); + unsafe { + LLVMOrcDisposeThreadSafeContext(self.tsctx); + LLVMOrcDisposeLLJIT(self.jit); + LLVMOrcDisposeObjectLayer(self.objl); + } + } +} diff --git a/src/Rust/vvs_runtime/src/lib.rs b/src/Rust/vvs_runtime/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..4eb83d6c59bb490ee381fbdd0305f3bf5a72c620 --- /dev/null +++ b/src/Rust/vvs_runtime/src/lib.rs @@ -0,0 +1,6 @@ +mod jit; +mod workers; + +// Re-exports +pub use crate::jit::*; +pub use vvs_runtime_types::types; diff --git a/src/Rust/vvs_runtime/src/workers.rs b/src/Rust/vvs_runtime/src/workers.rs new file mode 100644 index 0000000000000000000000000000000000000000..9c69cad1ffc5327b75d15e8b5c7c5141c8959d62 --- /dev/null +++ b/src/Rust/vvs_runtime/src/workers.rs @@ -0,0 +1,106 @@ +//! A simple implementation of worker threads, unix only for now. HWloc seems to have difficulties +//! on MacOS, so this should be Ok for Linux and BSDs... + +use anyhow::{bail, Context, Result}; +use std::{ + cell::Cell, + sync::{ + atomic::{AtomicU64, Ordering}, + Arc, + }, + thread::JoinHandle, +}; + +thread_local! { + pub static WORKER_THREAD_IDX: Cell<u16> = const { Cell::new(u16::MAX) }; +} + +/// Contains worker threads, we bind one per physical core. We can distribute work to those threads +/// and wait for the distributed work to be done. +pub(crate) struct Workers { + handles: Vec<(JoinHandle<()>, Arc<AtomicU64>)>, +} + +fn join_handles<T>(handles: impl Iterator<Item = JoinHandle<T>>) { + for handle in handles { + if let Err(err) = handle.join() { + let idx = WORKER_THREAD_IDX.get(); + log::error!("failed to join thread n°{idx} with error: {err:?}") + } + } +} + +fn cancel_threads(handles: impl Iterator<Item = Arc<AtomicU64>>) { + for atomic in handles { + atomic.store(u64::MAX, Ordering::SeqCst); + } +} + +impl Workers { + /// Create new worker threads. We use a closure passed by the user. When work is asked for the + /// workers the passed integer is set to a non-zero constant (you can't assume it's value), + /// when the thread has finish it's work the atomic must be set to 0. + /// + /// If we want to cancel the thread, the passed atomic will be set to `U64_MAX`. + pub fn new(user_func: impl Fn(Arc<AtomicU64>) -> Result<()> + Send + Clone + 'static) -> Result<Self> { + let thread_count = std::thread::available_parallelism() + .map(std::num::NonZeroUsize::get) + .unwrap_or(1); + (0..thread_count) + .map(|idx| Self::launch_thread(user_func.clone(), idx)) + .try_fold(vec![], |mut acc, item| match item { + Err(err) => Err((acc, err)), + Ok(item) => { + acc.push(item); + Ok(acc) + } + }) + .map(|handles| Self { handles }) + .map_err(|(handles, err)| { + cancel_threads(handles.iter().map(|(_, rc)| rc.clone())); + join_handles(handles.into_iter().map(|(hdl, _)| hdl)); + err + }) + } + + /// Launch a thread with a user function on a core of the topology. + fn launch_thread( + user_func: impl Fn(Arc<AtomicU64>) -> Result<()> + Send + 'static, + idx: usize, + ) -> Result<(JoinHandle<()>, Arc<AtomicU64>)> { + let flag = Arc::new(AtomicU64::new(0)); + let ret_flag = flag.clone(); + + let idx_i16: u16 = idx.try_into().with_context(|| "try to launch to many threads")?; + if idx_i16 == u16::MAX { + bail!("try to launch to many threads"); + } + + let handle = std::thread::Builder::new() + .name(format!("VVRT-Worker-{idx}")) + .spawn(move || { + WORKER_THREAD_IDX.set(idx_i16); + log::debug!("start thread n°{idx}"); + if let Err(err) = user_func(flag.clone()) { + log::error!("thread n°{idx} exits with error: {err}"); + } + flag.store(0, Ordering::SeqCst); + log::debug!("exit thread n°{idx}"); + })?; + + Ok((handle, ret_flag)) + } + + /// Pre-drop all the threads and cancel the work to do. + pub fn pre_drop(&mut self) { + let handles = std::mem::take(&mut self.handles); + cancel_threads(handles.iter().map(|(_, rc)| rc.clone())); + join_handles(handles.into_iter().map(|(hdl, _)| hdl)); + } +} + +impl Drop for Workers { + fn drop(&mut self) { + self.pre_drop(); + } +} diff --git a/src/Rust/vvs_runtime_types/Cargo.toml b/src/Rust/vvs_runtime_types/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..1e1ab1a6e6608f0d5b0a8555c1b0643a481a43e7 --- /dev/null +++ b/src/Rust/vvs_runtime_types/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "vvs_runtime_types" +description = "The types for the runtime for Vivy Script" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +log.workspace = true +serde.workspace = true +serde_json.workspace = true +anyhow.workspace = true +hashbrown.workspace = true + +unicode-segmentation.workspace = true + +vvs_procmacro.workspace = true +vvs_utils.workspace = true +vvs_lang.workspace = true +vvs_llvm.workspace = true +vvs_ass.workspace = true + +[build-dependencies] +anyhow.workspace = true +vvs_llvm = { workspace = true, features = ["link"] } diff --git a/src/Rust/vvs_runtime_types/build.rs b/src/Rust/vvs_runtime_types/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..a01480722a65c2a0de92058e860bdc41610328d4 --- /dev/null +++ b/src/Rust/vvs_runtime_types/build.rs @@ -0,0 +1,3 @@ +fn main() -> anyhow::Result<()> { + vvs_llvm::build::llvm_link() +} diff --git a/src/Rust/vvs_runtime_types/src/lib.rs b/src/Rust/vvs_runtime_types/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..b5950e8b5d87bc12146a1de535ebf0e52b18c80f --- /dev/null +++ b/src/Rust/vvs_runtime_types/src/lib.rs @@ -0,0 +1,13 @@ +//! Here we have the types that will be used by the runtime, with their description so that the +//! codegen can correctly use them. + +mod mangle; +mod pointer; + +pub mod types; +pub mod vvll; + +pub use self::{mangle::*, pointer::*}; + +#[cfg(any(test, doctest))] +mod tests; diff --git a/src/Rust/vvs_runtime_types/src/mangle.rs b/src/Rust/vvs_runtime_types/src/mangle.rs new file mode 100644 index 0000000000000000000000000000000000000000..2945a3349eaefef9ebe9afff27d8d80a50576230 --- /dev/null +++ b/src/Rust/vvs_runtime_types/src/mangle.rs @@ -0,0 +1,163 @@ +use anyhow::{anyhow, bail}; +use std::{ffi::CString, str::FromStr}; +use vvs_lang::ast::ASTType; +use vvs_llvm::*; + +/// Materialize which type of symbol we have. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum VVRTSymbolType { + Constant, + Function, + Option, + Method, +} + +/// Describes a symbol. Can specify an ORCv2 execution address. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct VVRTSymbol<'a> { + pub sym: VVRTSymbolType, + pub module: &'a str, + pub name: &'a str, + addr: Option<LLVMOrcExecutorAddress>, +} + +impl VVRTSymbolType { + /// Get the string representation of the symbol type. + pub fn as_str(&self) -> &'static str { + match self { + VVRTSymbolType::Constant => "Constant", + VVRTSymbolType::Function => "Function", + VVRTSymbolType::Option => "Option", + VVRTSymbolType::Method => "Method", + } + } +} + +impl FromStr for VVRTSymbolType { + type Err = anyhow::Error; + fn from_str(s: &str) -> Result<Self, Self::Err> { + match s.trim() { + "Constant" => Ok(VVRTSymbolType::Constant), + "Function" => Ok(VVRTSymbolType::Function), + "Option" => Ok(VVRTSymbolType::Option), + "Method" => Ok(VVRTSymbolType::Method), + s => Err(anyhow!("unknown symbol type `{s}`")), + } + } +} + +impl std::fmt::Display for VVRTSymbolType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(self.as_str()) + } +} + +impl AsRef<str> for VVRTSymbolType { + fn as_ref(&self) -> &str { + self.as_str() + } +} + +impl<'a> VVRTSymbol<'a> { + /// Create a new symbol. + pub fn new(ty: VVRTSymbolType, module: &'a str, name: &'a str) -> anyhow::Result<Self> { + if let Some(idx) = module.find(|c: char| !c.is_alphanumeric()) { + bail!("invalid character found in module name at position `{idx}`: {module}") + } + if let Some(idx) = name.find(|c: char| c.is_whitespace() || c == '\0') { + bail!("invalid character found in name at position `{idx}`: {name}") + } + Ok(Self { sym: ty, module, name, addr: None }) + } + + pub fn method(ty: &ASTType, name: &'a str) -> anyhow::Result<Self> { + let module = match ty { + ASTType::Any => "Any", + ASTType::Line => "Line", + ASTType::String => "String", + ASTType::Syllabe => "Syllabe", + ty if ty.is_variant() => "Variant", + ty if ty.is_table() => "Table", + ty if ty.is_sequence() => "Sequence", + ty => bail!("can't have methods for type `{ty}`"), + }; + Ok(VVRTSymbol { sym: VVRTSymbolType::Method, module, name, addr: None }) + } + + /// Builder-like syntax to take a symbol and associate it to an execution address gotten from + /// the JIT engine. We ignore any previous address. + pub fn with_addr(mut self, addr: LLVMOrcExecutorAddress) -> Self { + self.addr = Some(addr); + self + } + + /// Mangle the symbol to get the name of it for the JIT engine or to find the symbol in the + /// LLVM module. This is a heavy operation. + /// + /// If the symbol was not valid we panic. If the symbol was correctly constructed/parsed this + /// should not happen. + pub fn mangle(&self) -> CString { + CString::new(self.to_string()).expect("invalid symbol") + } +} + +impl<'a> std::fmt::Display for VVRTSymbol<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let Self { sym, module, name, .. } = self; + match sym { + // Some shenanigans for builtin symbols... + VVRTSymbolType::Method => { + let mut module = unicode_segmentation::UnicodeSegmentation::graphemes(*module, true); + let first = module.next().map(|str| str.to_uppercase()).unwrap_or_default(); + let tail = module.as_str(); + write!(f, "VV{first}{tail}_{}", name.to_lowercase()) + } + + // A simple rule for symbols generated from users' code. + _ => write!(f, "_VV{sym}_{module}_{name}"), + } + } +} + +impl<'a> TryFrom<&'a str> for VVRTSymbol<'a> { + type Error = anyhow::Error; + fn try_from(value: &'a str) -> Result<Self, Self::Error> { + const CORRECT_SYMBOLS: &str = "`_VV{{sym}}_{{module}}_{{name}}` or `VV{{builtin_type}}_{{name}}`"; + + let trimmed_value = value.trim(); + if let Some(pos) = trimmed_value.find('\0') { + bail!("invalid symbol name `{trimmed_value}`, found null byte at {pos}") + } + + let Some((sym, value)) = (match trimmed_value.strip_prefix("_VV") { + Some(trimmed_value) => trimmed_value.split_once('_'), + None => match trimmed_value.strip_prefix("VV") { + Some(trimmed_value) => Some((VVRTSymbolType::Method.as_str(), trimmed_value)), + None => bail!("invalid symbol name `{trimmed_value}`, didn't start with `_VV` or `VV`"), + }, + }) else { + bail!("invalid symbol name `{trimmed_value}`, should be {CORRECT_SYMBOLS}") + }; + + let Some((module, name)) = value.split_once('_') else { + bail!("invalid symbol name `{trimmed_value}`, should be {CORRECT_SYMBOLS}") + }; + + Self::new(sym.parse()?, module, name) + } +} + +#[test] +fn test_vvrt_symbol() { + use vvs_utils::*; + + assert_eq!( + assert_ok!(VVRTSymbol::try_from("_VVConstant_retime_start")), + VVRTSymbol { sym: VVRTSymbolType::Constant, module: "retime", name: "start", addr: None } + ); + + assert_eq!( + "_VVFunction_tag_syl_modulo".to_string(), + VVRTSymbol { sym: VVRTSymbolType::Function, module: "tag", name: "syl_modulo", addr: None }.to_string() + ); +} diff --git a/src/Rust/vvs_runtime_types/src/pointer.rs b/src/Rust/vvs_runtime_types/src/pointer.rs new file mode 100644 index 0000000000000000000000000000000000000000..68f689ccc3c04e34046b3511263a1508bd8ac626 --- /dev/null +++ b/src/Rust/vvs_runtime_types/src/pointer.rs @@ -0,0 +1,140 @@ +use std::{ + cmp::Ordering, + hash::{Hash, Hasher}, + marker::PhantomData, + mem::{align_of, size_of}, + ptr::NonNull, +}; + +/// A tagged pointer: a space-efficient representation of a pointer that smuggles an integer tag +/// into it. +/// +/// `BITS` specifies how many bits are used for the tag. The alignment of `T` must be large enough +/// to store this many bits. +/// +/// # Safety +/// The passed pointers, at construction time and each time you modify this struct, should all be +/// properly aligned, or your code may panic. The passed pointer must also be dereferenceable. +#[repr(transparent)] +pub struct TaggedPtr<T, const BITS: u8>(NonNull<u8>, PhantomData<NonNull<T>>); + +impl<T, const BITS: u8> TaggedPtr<T, BITS> { + const ASSERT: () = { + assert!(size_of::<usize>() == size_of::<u64>(), "we only work with 64 bits architectures"); + assert!(align_of::<T>().is_power_of_two(), "expected alignment of `T` to be a power of 2"); + assert!( + match size_of::<T>() { + 0 => true, + n => n >= align_of::<T>(), + }, + "expected size of non-ZST `T` to be at least alignment" + ); + assert!(size_of::<T>() % align_of::<T>() == 0, "expected size of `T` to be multiple of alignment"); + assert!(1_usize.checked_shl(BITS as u32).is_some(), "`1 << BITS` doesn't fit in a `usize`"); + assert!(align_of::<T>().trailing_zeros() >= BITS as u32, "alignment of `T` must be at least `1 << BITS`"); + }; + + const ALIGNMENT: usize = 1_usize.wrapping_shl(BITS as u32); + const MASK: usize = Self::ALIGNMENT - 1; + + /// Creates a new tagged pointer. Only the lower `BITS` bits of `tag` are stored. + /// + /// If build in debug, a check is performed at compile time to ensure that the alignment of `T` + /// is sufficient to smuggle the tag. + #[allow(path_statements, clippy::no_effect)] + #[inline] + pub fn new(ptr: NonNull<T>, tag: usize) -> Self { + Self::ASSERT; // Static assert! + let ptr = ptr.as_ptr().cast::<u8>(); + + let offset = ptr.align_offset(Self::ALIGNMENT); + debug_assert!(offset != usize::MAX, "align offset failed"); + debug_assert!(offset & Self::MASK == 0, "`ptr` is not aligned enough"); + + let ptr = ptr.wrapping_add(tag & Self::MASK); + Self(unsafe { NonNull::new_unchecked(ptr) }, PhantomData) + } + + /// Gets the pointer and tag stored by the tagged pointer. + #[inline] + pub fn get(self) -> (NonNull<T>, usize) { + let ptr = self.0.as_ptr(); + let tag = Self::ALIGNMENT.wrapping_sub(ptr.align_offset(Self::ALIGNMENT)) & Self::MASK; + let ptr = ptr.wrapping_sub(tag).cast::<T>(); + + // SAFETY: ptr + 1 - 1 == ptr + (unsafe { NonNull::new_unchecked(ptr) }, tag) + } + + /// Get the address of the pointed thing as an integer. Here for moar reasons we only work with + /// 64 bit architectures, thus the `usize == u64`. + #[inline] + pub fn addr(self) -> u64 { + self.ptr().as_ptr() as u64 + } + + /// Gets the pointer stored by the tagged pointer, without the tag. + #[inline] + pub fn ptr(self) -> NonNull<T> { + self.get().0 + } + + /// Gets the tag stored by the tagged pointer. + #[inline] + pub fn tag(self) -> usize { + self.get().1 + } + + /// Sets the pointer without modifying the tag. + #[inline] + pub fn set_ptr(&mut self, ptr: NonNull<T>) { + *self = Self::new(ptr, self.tag()); + } + + /// Sets the tag without modifying the pointer. + #[inline] + pub fn set_tag(&mut self, tag: usize) { + *self = Self::new(self.ptr(), tag); + } +} + +impl<T, const BITS: u8> Copy for TaggedPtr<T, BITS> {} +impl<T, const BITS: u8> Clone for TaggedPtr<T, BITS> { + fn clone(&self) -> Self { + *self + } +} + +impl<T, const BITS: u8> Eq for TaggedPtr<T, BITS> {} +impl<T, const BITS: u8> PartialEq for TaggedPtr<T, BITS> { + fn eq(&self, other: &Self) -> bool { + self.0 == other.0 + } +} + +impl<T, const BITS: u8> PartialOrd for TaggedPtr<T, BITS> { + fn partial_cmp(&self, other: &Self) -> Option<Ordering> { + Some(self.cmp(other)) + } +} +impl<T, const BITS: u8> Ord for TaggedPtr<T, BITS> { + fn cmp(&self, other: &Self) -> Ordering { + self.0.cmp(&other.0) + } +} + +impl<T, const BITS: u8> Hash for TaggedPtr<T, BITS> { + fn hash<H: Hasher>(&self, state: &mut H) { + self.0.hash(state); + } +} + +impl<T, const BITS: u8> std::fmt::Debug for TaggedPtr<T, BITS> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let (ptr, tag) = self.get(); + f.debug_struct("TaggedPtr") + .field("ptr", &ptr) + .field("tag", &tag) + .finish() + } +} diff --git a/src/Rust/vvs_runtime_types/src/tests.rs b/src/Rust/vvs_runtime_types/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..ab13f1258ea84c34d314d6624db46f9751f78d01 --- /dev/null +++ b/src/Rust/vvs_runtime_types/src/tests.rs @@ -0,0 +1,136 @@ +use hashbrown::HashMap; + +use crate::{ + types::{VVRTAny, VVRTType}, + TaggedPtr, +}; +use core::{mem::size_of, ptr::NonNull}; +use std::mem::align_of; + +#[test] +fn test_ptr_size() { + assert_eq!(size_of::<usize>(), size_of::<u64>()); + assert_eq!(size_of::<*const u64>(), size_of::<u64>()); +} + +#[test] +fn test_ptr_align() { + assert_eq!(size_of::<NonNull<u64>>(), 8); + assert_eq!(align_of::<NonNull<u64>>(), 8); + assert_eq!(align_of::<NonNull<HashMap<Box<str>, VVRTAny>>>(), 8); + assert_eq!(align_of::<NonNull<Vec<VVRTAny>>>(), 8); +} + +#[test] +fn test_type_sizes() { + use std::mem::size_of; + assert_eq!(size_of::<VVRTAny>(), 8); + assert_eq!(size_of::<VVRTType>(), 1); +} + +#[repr(align(2))] +#[derive(Debug, Eq, PartialEq)] +struct Align2(pub u16); + +#[repr(align(4))] +#[derive(Debug, Eq, PartialEq)] +struct Align4(pub u32); + +#[repr(align(8))] +#[derive(Debug, Eq, PartialEq)] +struct Align8(pub u64); + +#[test] +#[allow(clippy::let_unit_value)] +fn check_ptr_basic() { + for i in 0..64 { + let x = i as u8 * 3; + let tp = TaggedPtr::<_, 0>::new((&x).into(), i); + assert_eq!(tp.get(), ((&x).into(), 0)); + assert_eq!(*unsafe { tp.ptr().as_ref() }, x); + + let x = Align2(i as u16 * 5); + let tp = TaggedPtr::<_, 1>::new((&x).into(), i); + assert_eq!(tp.get(), ((&x).into(), i & 0b1)); + assert_eq!(*unsafe { tp.ptr().as_ref() }, x); + + let mut x = Align4(i as u32 * 7); + let ptr = NonNull::from(&mut x); + let tp = TaggedPtr::<_, 2>::new(ptr, i); + assert_eq!(tp.get(), (ptr, i & 0b11)); + unsafe { tp.ptr().as_mut() }.0 += 1; + assert_eq!(x.0, i as u32 * 7 + 1); + + let x = Align8(i as u64 * 11); + let tp = TaggedPtr::<_, 3>::new((&x).into(), i); + assert_eq!(tp.get(), ((&x).into(), i & 0b111)); + assert_eq!(*unsafe { tp.ptr().as_ref() }, x); + } +} + +#[test] +#[allow(clippy::let_unit_value)] +fn check_ptr_overaligned() { + for i in 0..64 { + let x = Align2(i as u16 * 3); + let tp = TaggedPtr::<_, 0>::new((&x).into(), i); + assert_eq!(tp.get(), ((&x).into(), 0)); + assert_eq!(*unsafe { tp.ptr().as_ref() }, x); + + let x = Align4(i as u32 * 5); + let tp = TaggedPtr::<_, 1>::new((&x).into(), i); + assert_eq!(tp.get(), ((&x).into(), i & 0b1)); + assert_eq!(*unsafe { tp.ptr().as_ref() }, x); + + let x = Align8(i as u64 * 7); + let tp = TaggedPtr::<_, 2>::new((&x).into(), i); + assert_eq!(tp.get(), ((&x).into(), i & 0b11)); + assert_eq!(*unsafe { tp.ptr().as_ref() }, x); + } +} + +#[test] +#[allow(clippy::let_unit_value)] +fn check_ptr_zst() { + for i in 0..8 { + let x = (); + let tp = TaggedPtr::<_, 0>::new((&x).into(), i); + assert_eq!(tp.get(), ((&x).into(), 0)); + } +} + +#[test] +fn check_ptr_size() { + assert_eq!(size_of::<TaggedPtr<u64, 3>>(), size_of::<core::ptr::NonNull<u64>>()); + assert_eq!(size_of::<TaggedPtr<u64, 3>>(), size_of::<Option<TaggedPtr<u64, 3>>>()); +} + +#[test] +fn check_ptr_not_entirely_dereferenceable() { + #[repr(align(8))] + #[allow(dead_code)] + struct Type(u64, u64, u64); + + let a = Type(1, 2, 3); + let mut tp = TaggedPtr::<_, 2>::new((&a).into(), 0b10); + assert_eq!(tp.get(), ((&a).into(), 0b10)); + + let mut b = Align4(0); + let ptr = NonNull::from(&mut b).cast(); + tp.set_ptr(ptr); + assert_eq!(tp.ptr(), ptr); + tp.set_tag(0b11); + assert_eq!(tp.tag(), 0b11); + unsafe { tp.ptr().cast::<Align4>().as_mut() }.0 = 1234; + assert_eq!(b.0, 1234); +} + +#[test] +#[should_panic] +fn runtime_ptr_not_aligned_enough() { + let ptr: *mut Align2 = &mut Align2(0); + let ptr = unsafe { (ptr as *mut u8).add(1) }; + let ptr = ptr as *mut Align2; + let ptr = unsafe { NonNull::new_unchecked(ptr) }; + TaggedPtr::<_, 1>::new(ptr, 0); +} diff --git a/src/Rust/vvs_runtime_types/src/types/any.rs b/src/Rust/vvs_runtime_types/src/types/any.rs new file mode 100644 index 0000000000000000000000000000000000000000..1771dc8c21b9621776becd28aa89786a4a513f7e --- /dev/null +++ b/src/Rust/vvs_runtime_types/src/types/any.rs @@ -0,0 +1,318 @@ +//! Contains definitions for the [VVRTAny] runtime object and its associated methods. + +/// Implement [TryFrom<VVRTAny>] and [TryFrom<&VVRTAny>] for a given object that can be contained +/// inside [VVRTAny]. +macro_rules! impl_try_from_any { + ($vvrtty: ident => $struct: ident) => { + impl TryFrom<crate::types::VVRTAny> for $struct { + #[inline] + fn try_from(value: crate::types::VVRTAny) -> Result<Self, Self::Error> { + unsafe { VVRTAny_is_ty(value, VVRTType::$vvrtty) } + .then_some(Self(value.ptr())) + .ok_or(value.ty()) + } + type Error = crate::types::VVRTType; + } + + impl TryFrom<&crate::types::VVRTAny> for $struct { + #[inline] + fn try_from(value: &crate::types::VVRTAny) -> Result<Self, Self::Error> { + (*value).try_into() + } + type Error = crate::types::VVRTType; + } + }; +} +pub(super) use impl_try_from_any; + +use crate::{types::*, TaggedPtr}; +use std::{ + mem::{align_of, transmute}, + ptr::NonNull, +}; + +/// We represent the *any* Vivy Script type by an enum. We try to fit this bad boi into 8 bytes +/// with a tagged pointer. With 3 bits for the tag we have values from 0 to 7, is enaugh to store +/// the [VVRTType]. We store the [VVRTType::Nil] as [None] so we can gain one slot. +/// +/// Nil is all zero, which is Ok even if we have a non-null thingy (at least I hope). +#[derive(Debug, Clone, Copy)] +#[repr(transparent)] +pub struct VVRTAny(Option<TaggedPtr<u64, 3>>); + +impl VVRTAny { + /// Get the real type of the object inside the `any` container. + #[inline] + pub fn ty(&self) -> VVRTType { + self.map_or_default(|this| unsafe { transmute(this.tag() as u8 + 1) }) + } + + /// Map on the inner tagged pointer, or return the specified default. + #[inline] + pub fn map_or<U, F: FnOnce(TaggedPtr<u64, 3>) -> U>(self, default: U, f: F) -> U { + self.0.map_or(default, f) + } + + /// Map on the inner tagger pointer, or return the default value for the returned type. + #[inline] + pub fn map_or_default<U: Default, F: FnOnce(TaggedPtr<u64, 3>) -> U>(self, f: F) -> U { + self.0.map_or(U::default(), f) + } + + /// Get the pointer out of the tagged pointer, or a dangling pointer in the case where we store + /// a value of type [VVRTType::Nil]. + #[inline] + pub(crate) fn ptr<T: Sized>(&self) -> NonNull<T> { + debug_assert_eq!(align_of::<T>(), 8); + self.map_or(NonNull::dangling(), |this| unsafe { + NonNull::new_unchecked(this.ptr().as_ptr() as *mut T) + }) + } + + /// Build the [VVRTAny] from a pointer assumed to be not null and the type of such pointer. + #[inline] + unsafe fn from_parts(ptr: *mut u64, ty: VVRTType) -> Self { + Self((ty != VVRTType::Nil).then(|| TaggedPtr::new(NonNull::new_unchecked(ptr), ty as usize - 1))) + } + + /// Tells whever the contained type is a floating number or not. + #[inline] + pub fn number_is_f32(&self) -> bool { + (self.ty() == VVRTType::Number) && VVRTNumber::from(*self).is_f32() + } + + /// Tells whever the contained type is an integer number or not. + #[inline] + pub fn number_is_i32(&self) -> bool { + (self.ty() == VVRTType::Number) && VVRTNumber::from(*self).is_i32() + } +} + +impl Default for VVRTAny { + /// By default, [VVRTAny] contains an object of type [VVRTType::Nil]. + #[inline] + fn default() -> Self { + Self(None) + } +} + +impl From<VVRTAny> for VVRTNumber { + fn from(value: VVRTAny) -> Self { + value.map_or_default(|ptr| VVRTNumber::from_number_be_bytes(ptr.addr().to_be_bytes())) + } +} + +impl From<VVRTNumber> for VVRTAny { + fn from(value: VVRTNumber) -> Self { + unsafe { Self::from_parts(value.as_ptr(), VVRTType::Number) } + } +} + +impl From<VVRTAny> for bool { + #[inline] + fn from(this: VVRTAny) -> Self { + Into::<i32>::into(this) != 0 + } +} + +impl From<VVRTAny> for i32 { + #[inline] + fn from(this: VVRTAny) -> Self { + VVRTNumber::from(this).into() + } +} + +impl From<VVRTAny> for f32 { + #[inline] + fn from(this: VVRTAny) -> Self { + VVRTNumber::from(this).into() + } +} + +impl From<VVRTVariant> for VVRTAny { + #[inline] + fn from(ptr: VVRTVariant) -> Self { + unsafe { Self::from_parts(ptr.as_ptr(), VVRTType::Variant) } + } +} + +impl From<VVRTString> for VVRTAny { + #[inline] + fn from(ptr: VVRTString) -> Self { + unsafe { Self::from_parts(ptr.as_ptr(), VVRTType::String) } + } +} + +impl From<VVRTTable> for VVRTAny { + #[inline] + fn from(ptr: VVRTTable) -> Self { + unsafe { Self::from_parts(ptr.as_ptr(), VVRTType::Table) } + } +} + +impl From<VVRTSeq> for VVRTAny { + #[inline] + fn from(ptr: VVRTSeq) -> Self { + unsafe { Self::from_parts(ptr.as_ptr(), VVRTType::Seq) } + } +} + +impl From<VVRTLine> for VVRTAny { + #[inline] + fn from(ptr: VVRTLine) -> Self { + unsafe { Self::from_parts(ptr.as_ptr(), VVRTType::ASSLine) } + } +} + +impl From<VVRTSyllabe> for VVRTAny { + #[inline] + fn from(ptr: VVRTSyllabe) -> Self { + unsafe { Self::from_parts(ptr.as_ptr(), VVRTType::ASSSyllabe) } + } +} + +impl From<i32> for VVRTAny { + #[inline] + fn from(value: i32) -> Self { + unsafe { Self::from_parts(VVRTNumber::from(value).as_ptr(), VVRTType::Number) } + } +} + +impl From<bool> for VVRTAny { + #[inline] + fn from(value: bool) -> Self { + (value as i32).into() + } +} + +impl From<f32> for VVRTAny { + #[inline] + fn from(value: f32) -> Self { + unsafe { Self::from_parts(VVRTNumber::from(value).as_ptr(), VVRTType::Number) } + } +} + +impl Eq for VVRTAny {} +impl PartialEq for VVRTAny { + #[inline] + fn eq(&self, other: &Self) -> bool { + unsafe { + macro_rules! into { + ($what: expr) => { + self.try_into().unwrap_unchecked() + }; + } + match self.ty() { + ty if ty != other.ty() => false, + VVRTType::Nil => true, + VVRTType::Number => self.0.unwrap_unchecked().addr() == other.0.unwrap_unchecked().addr(), + VVRTType::ASSSyllabe => VVRTSyllabe_eq(into!(self), into!(other)), + VVRTType::ASSLine => VVRTLine_eq(into!(self), into!(other)), + VVRTType::Variant => VVRTVariant_eq(into!(self), into!(other)), + VVRTType::String => VVRTString_eq(into!(self), into!(other)), + VVRTType::Table => VVRTTable_eq(into!(self), into!(other)), + VVRTType::Seq => VVRTSeq_eq(into!(self), into!(other)), + } + } + } +} + +/// Module used to define functions to be exported for the JIT. +#[allow(clippy::missing_safety_doc)] +#[vvs_procmacro::vvrt_bridge(VVRTAny)] +mod ffi { + #[no_mangle] + pub unsafe extern "C" fn nil() -> VVRTAny { + Default::default() + } + + #[no_mangle] + pub unsafe extern "C" fn ty(any: VVRTAny) -> VVRTType { + any.ty() + } + + #[no_mangle] + pub unsafe extern "C" fn is_ty(any: VVRTAny, ty: VVRTType) -> bool { + any.ty() == ty + } + + #[no_mangle] + pub unsafe extern "C" fn is_nil(any: VVRTAny) -> bool { + any.0.is_none() + } + + #[no_mangle] + pub unsafe extern "C" fn deep_clone(any: VVRTAny) -> VVRTAny { + match any.ty() { + // Shallow copy + VVRTType::Nil | VVRTType::Number => any, + VVRTType::String => VVRTString_clone(any.try_into().unwrap_unchecked()).into(), + VVRTType::Variant => VVRTVariant_clone(any.try_into().unwrap_unchecked()).into(), + + // Deep copy + VVRTType::Seq => VVRTSeq_deep_clone(any.try_into().unwrap_unchecked()).into(), + VVRTType::Table => VVRTTable_deep_clone(any.try_into().unwrap_unchecked()).into(), + VVRTType::ASSLine => VVRTLine_deep_clone(any.try_into().unwrap_unchecked()).into(), + VVRTType::ASSSyllabe => VVRTSyllabe_deep_clone(any.try_into().unwrap_unchecked()).into(), + } + } + + #[no_mangle] + pub unsafe extern "C" fn clone(any: VVRTAny) -> VVRTAny { + match any.ty() { + VVRTType::Nil | VVRTType::Number => any, + VVRTType::Seq => VVRTSeq_clone(any.try_into().unwrap_unchecked()).into(), + VVRTType::Table => VVRTTable_clone(any.try_into().unwrap_unchecked()).into(), + VVRTType::String => VVRTString_clone(any.try_into().unwrap_unchecked()).into(), + VVRTType::Variant => VVRTVariant_clone(any.try_into().unwrap_unchecked()).into(), + VVRTType::ASSLine => VVRTLine_clone(any.try_into().unwrap_unchecked()).into(), + VVRTType::ASSSyllabe => VVRTSyllabe_clone(any.try_into().unwrap_unchecked()).into(), + } + } + + #[no_mangle] + pub unsafe extern "C" fn drop(any: VVRTAny) { + match any.ty() { + VVRTType::Nil | VVRTType::Number => {} + VVRTType::Seq => VVRTSeq_drop(any.try_into().unwrap_unchecked()), + VVRTType::Table => VVRTTable_drop(any.try_into().unwrap_unchecked()), + VVRTType::String => VVRTString_drop(any.try_into().unwrap_unchecked()), + VVRTType::Variant => VVRTVariant_drop(any.try_into().unwrap_unchecked()), + VVRTType::ASSLine => VVRTLine_drop(any.try_into().unwrap_unchecked()), + VVRTType::ASSSyllabe => VVRTSyllabe_drop(any.try_into().unwrap_unchecked()), + } + } + + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn eq(this: VVRTAny, other: VVRTAny) -> bool { this == other } + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn ne(this: VVRTAny, other: VVRTAny) -> bool { this != other } + + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn from_boolean (o: bool) -> VVRTAny { o.into() } + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn from_integer (o: i32) -> VVRTAny { o.into() } + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn from_floating(o: f32) -> VVRTAny { o.into() } + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn from_string (o: VVRTString) -> VVRTAny { o.into() } + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn from_table (o: VVRTTable) -> VVRTAny { o.into() } + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn from_seq (o: VVRTSeq) -> VVRTAny { o.into() } + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn from_variant (o: VVRTVariant) -> VVRTAny { o.into() } + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn from_line (o: VVRTLine) -> VVRTAny { o.into() } + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn from_syllabe (o: VVRTSyllabe) -> VVRTAny { o.into() } + + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn as_boolean (any: VVRTAny) -> bool { any.into() } + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn as_integer (any: VVRTAny) -> i32 { any.into() } + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn as_floating(any: VVRTAny) -> f32 { any.into() } + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn as_string (any: VVRTAny) -> VVRTString { any.try_into().unwrap_unchecked() } + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn as_table (any: VVRTAny) -> VVRTTable { any.try_into().unwrap_unchecked() } + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn as_seq (any: VVRTAny) -> VVRTSeq { any.try_into().unwrap_unchecked() } + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn as_variant (any: VVRTAny) -> VVRTVariant { any.try_into().unwrap_unchecked() } + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn as_line (any: VVRTAny) -> VVRTLine { any.try_into().unwrap_unchecked() } + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn as_syllabe (any: VVRTAny) -> VVRTSyllabe { any.try_into().unwrap_unchecked() } + + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn maybe_as_boolean (any: VVRTAny) -> bool { VVRTAny_as_boolean(any) } + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn maybe_as_integer (any: VVRTAny) -> i32 { VVRTAny_as_integer(any) } + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn maybe_as_floating(any: VVRTAny) -> f32 { VVRTAny_as_floating(any) } + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn maybe_as_string (any: VVRTAny) -> VVRTString { any.try_into().unwrap_or(VVRTString ::dangling()) } + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn maybe_as_table (any: VVRTAny) -> VVRTTable { any.try_into().unwrap_or(VVRTTable ::dangling()) } + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn maybe_as_seq (any: VVRTAny) -> VVRTSeq { any.try_into().unwrap_or(VVRTSeq ::dangling()) } + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn maybe_as_variant (any: VVRTAny) -> VVRTVariant { any.try_into().unwrap_or(VVRTVariant::dangling()) } + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn maybe_as_line (any: VVRTAny) -> VVRTLine { any.try_into().unwrap_or(VVRTLine ::dangling()) } + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn maybe_as_syllabe (any: VVRTAny) -> VVRTSyllabe { any.try_into().unwrap_or(VVRTSyllabe::dangling()) } +} diff --git a/src/Rust/vvs_runtime_types/src/types/line.rs b/src/Rust/vvs_runtime_types/src/types/line.rs new file mode 100644 index 0000000000000000000000000000000000000000..79dfd2bd3879f92eca0e8b69aebeec5f4b10513e --- /dev/null +++ b/src/Rust/vvs_runtime_types/src/types/line.rs @@ -0,0 +1,90 @@ +use crate::types::*; +use std::{ptr::NonNull, rc::Rc}; +use vvs_ass::ASSLine; + +/// Represent a line, in an ffi-safe way. We represent if the line was create by using an Rc or was +/// built from a reference. +#[derive(Debug, Clone, Copy)] +#[repr(C)] +pub struct VVRTLine(NonNull<ASSLine<VVRTTable>>); +crate::types::any::impl_try_from_any! { ASSLine => VVRTLine } + +impl VVRTLine { + #[inline] + pub fn dangling() -> Self { + Self(NonNull::dangling()) + } + + #[inline] + pub fn as_ptr(self) -> *mut u64 { + self.0.as_ptr() as *mut _ + } + + #[inline] + pub fn is_rc(&self) -> bool { + !self.as_ref().aux.rt_infos().is_ass_borrowed + } +} + +impl From<ASSLine<VVRTTable>> for VVRTLine { + fn from(mut value: ASSLine<VVRTTable>) -> Self { + value.aux.rt_infos_mut().is_ass_borrowed = false; + let ptr = Rc::into_raw(Rc::new(value)) as *mut _; + VVRTLine(unsafe { NonNull::new_unchecked(ptr) }) + } +} + +impl AsRef<ASSLine<VVRTTable>> for VVRTLine { + fn as_ref(&self) -> &ASSLine<VVRTTable> { + unsafe { self.0.as_ref() } + } +} + +impl AsMut<ASSLine<VVRTTable>> for VVRTLine { + fn as_mut(&mut self) -> &mut ASSLine<VVRTTable> { + unsafe { self.0.as_mut() } + } +} + +impl Eq for VVRTLine {} +impl PartialEq for VVRTLine { + fn eq(&self, other: &Self) -> bool { + self.as_ref().eq(other.as_ref()) + } +} + +/// Module used to defined functions to be exported to the JIT. +#[allow(clippy::missing_safety_doc)] +#[vvs_procmacro::vvrt_bridge(VVRTLine)] +mod ffi { + #[no_mangle] + pub unsafe extern "C" fn deep_clone(this: VVRTLine) -> VVRTLine { + this.as_ref().clone().into() + } + + #[no_mangle] + unsafe extern "C" fn clone(this @ VVRTLine(ptr): VVRTLine) -> VVRTLine { + match this.is_rc() { + false => VVRTLine_deep_clone(this), + true => { + Rc::increment_strong_count(ptr.as_ptr()); + this + } + } + } + + #[no_mangle] + unsafe extern "C" fn drop(this @ VVRTLine(ptr): VVRTLine) { + if this.is_rc() { + Rc::decrement_strong_count(ptr.as_ptr()) + } + } + + #[no_mangle] + unsafe extern "C" fn len(this: VVRTLine) -> i32 { + this.as_ref().content.len().clamp(0, i32::MAX as usize) as i32 + } + + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn eq(this: VVRTLine, other: VVRTLine) -> bool { PartialEq::eq(&this, &other) } + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn ne(this: VVRTLine, other: VVRTLine) -> bool { PartialEq::ne(&this, &other) } +} diff --git a/src/Rust/vvs_runtime_types/src/types/mod.rs b/src/Rust/vvs_runtime_types/src/types/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..1e8972a6cfcf7456903aba3263eda46071f3ac71 --- /dev/null +++ b/src/Rust/vvs_runtime_types/src/types/mod.rs @@ -0,0 +1,178 @@ +//! Here we have the base types for the runtime. + +/// Get the list of all the builtin types. +macro_rules! builtin_types { + ($macro: ident) => { + $macro!(any, sequence, string, table, variant, line, syllabe); + }; +} + +/// Declare the modules associated with the builtin types. +macro_rules! decl_modules { + ($mod: ident $(,)?) => { + mod $mod; + }; + ($mod: ident, $($mods: ident),+ $(,)?) => { + decl_modules!($mod); + decl_modules!($($mods),+); + }; +} +builtin_types!(decl_modules); + +mod number; + +use self::{any::*, line::*, number::*, sequence::*, string::*, syllabe::*, table::*, variant::*}; +use crate::vvll::*; +use std::sync::OnceLock; +use vvs_llvm::*; + +#[cfg(test)] +mod test; + +pub use self::{ + any::VVRTAny, line::VVRTLine, sequence::VVRTSeq, string::VVRTString, syllabe::VVRTSyllabe, table::VVRTTable, + variant::VVRTVariant, +}; + +/// Get the builtin types +pub fn builtin_types() -> &'static [&'static str] { + #[allow(dead_code)] + static NUMBERS_ARE_COHERENT: () = { + assert!( + std::mem::size_of::<f32>() == std::mem::size_of::<i32>(), + "we need for the layout of the numbers to be the same to do our shenanigans" + ); + assert!( + std::mem::align_of::<f32>() == std::mem::align_of::<i32>(), + "we need for the layout of the numbers to be the same to do our shenanigans" + ); + }; + + static TYPES: OnceLock<Vec<&'static str>> = OnceLock::new(); + TYPES + .get_or_init(|| { + let mut ret = vec![]; + macro_rules! decl_hashmap { + ($mod: ident $(,)?) => {{ + ret.push(stringify!($mod)); + }}; + ($mod: ident, $($mods: ident),+ $(,)?) => {{ + decl_hashmap!($mod); + decl_hashmap!($($mods),+); + }}; + } + builtin_types!(decl_hashmap); + ret + }) + .as_slice() +} + +/// Represent every types. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(u8)] +pub enum VVRTType { + /// Null, we ensure that [Option<VVRTAny>::None] is 0. + Nil = 0, + + /// Numbers are floats or integers + Number = 1, + + /// An immutable string + String = 2, + + /// Table, a container indexed by string. + Table = 3, + + /// A sequence, a container indexed by integer, items are pushed or poped. + Seq = 4, + + /// A variant. + Variant = 5, + + /// An ASS Line + ASSLine = 6, + + /// An ASS Syllabe + ASSSyllabe = 7, +} + +impl Default for VVRTType { + fn default() -> Self { + #[allow(dead_code)] + const SMUGGLE_TYPE: () = match VVRTType::Nil { + t @ VVRTType::Nil + | t @ VVRTType::String + | t @ VVRTType::Number + | t @ VVRTType::Table + | t @ VVRTType::Seq + | t @ VVRTType::ASSLine + | t @ VVRTType::ASSSyllabe + | t @ VVRTType::Variant => assert!(t as usize <= 8), + }; + #[rustfmt::skip] #[allow(dead_code)] + const TYPE_ABI: () = { + // Non-managed + assert!((VVRTType::Number as usize - 1) == 0b000); + + // Managed + assert!((VVRTType::String as usize - 1) == 0b001); + assert!((VVRTType::Table as usize - 1) == 0b010); + assert!((VVRTType::Seq as usize - 1) == 0b011); + assert!((VVRTType::Variant as usize - 1) == 0b100); + assert!((VVRTType::ASSLine as usize - 1) == 0b101); + assert!((VVRTType::ASSSyllabe as usize - 1) == 0b110); + + // We want to use 0b111 for user types in the future... + }; + VVRTType::Nil + } +} + +impl VVRTType { + /// Get the type as a constant to be used in LLVM codegen. + /// + /// # Safety + /// The [LLVMContextRef] must be valid. + #[inline] + pub unsafe fn as_llvm_const(&self, c: LLVMContextRef) -> LLVMValueRef { + LLVMConstInt(LLVMInt8TypeInContext(c), *self as u64, 0) + } +} + +impl LLVMExported for VVRTType { + unsafe fn llvm_type(c: LLVMContextRef) -> LLVMTypeRef { + #[allow(dead_code)] + const TYPE_IS_VALID: () = { + assert!(std::mem::size_of::<VVRTType>() == 1); + assert!(std::mem::align_of::<VVRTType>() == 1); + }; + LLVMInt8TypeInContext(c) + } + + unsafe fn llvm_properties(_: LLVMContextRef) -> Properties { + Default::default() + } +} + +impl AsRef<str> for VVRTType { + #[inline] + fn as_ref(&self) -> &str { + match self { + VVRTType::Nil => "nil", + VVRTType::String => "string", + VVRTType::Number => "number", + VVRTType::Table => "table", + VVRTType::Seq => "seq", + VVRTType::Variant => "variant", + VVRTType::ASSLine => "line", + VVRTType::ASSSyllabe => "line", + } + } +} + +impl std::fmt::Display for VVRTType { + #[inline] + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(self.as_ref()) + } +} diff --git a/src/Rust/vvs_runtime_types/src/types/number.rs b/src/Rust/vvs_runtime_types/src/types/number.rs new file mode 100644 index 0000000000000000000000000000000000000000..dead33bedb2318f1d52ff6185b7e302aa3b00e57 --- /dev/null +++ b/src/Rust/vvs_runtime_types/src/types/number.rs @@ -0,0 +1,116 @@ +//! Contains utility to manipulate numbers from the runtime. + +use vvs_utils::either; + +/// Wrapper type for numbers that is intended to be used only for the [crate::types::VVRTAny] +/// and [crate::types::VVRTVariant] structs. +#[derive(Clone, Copy)] +#[repr(transparent)] +pub struct VVRTNumber(u64); + +impl VVRTNumber { + const FLT_TAG: u8 = 1; + const INT_TAG: u8 = !Self::FLT_TAG; + + /// Cast the number as a pointer. We ensure by construction that this pointer is never null. + /// You may never deref this pointer! + #[inline] + pub fn as_ptr(&self) -> *mut u64 { + self.0 as *mut _ + } + + /// In debug mode, assert that the passed bytes are a valid number representation. In case of + /// success re-return those bytes. + /// + /// In release build this function is a NoOp. + #[inline] + fn assert_is_number(bytes: [u8; 8]) -> [u8; 8] { + let [.., flag, z1, z2, z3] = bytes; + debug_assert!(z1 == z2 && z2 == z3 && z3 == 0, "invalid number"); + debug_assert!(flag == Self::INT_TAG || flag == Self::FLT_TAG, "invalid tag"); + bytes + } + + /// Get the byte representation of the number we store. + fn as_bytes(&self) -> (u8, [u8; 4]) { + let [b1, b2, b3, b4, flag, _, _, _] = Self::assert_is_number(self.0.to_be_bytes()); + (flag, [b1, b2, b3, b4]) + } + + /// Create [VVRTAny] from bytes assumed to be a valid number representation. + #[inline] + pub fn from_number_be_bytes(bytes: [u8; 8]) -> Self { + Self(u64::from_be_bytes(Self::assert_is_number(bytes))) + } + + /// Tells whever the contained type is a floating number or not. + #[inline] + pub fn is_f32(&self) -> bool { + self.as_bytes().0 == Self::FLT_TAG + } + + /// Tells whever the contained type is an integer number or not. + #[inline] + pub fn is_i32(&self) -> bool { + !self.is_f32() + } +} + +impl Default for VVRTNumber { + fn default() -> Self { + 0_i32.into() + } +} + +impl From<VVRTNumber> for i32 { + fn from(value: VVRTNumber) -> Self { + let (flag, bytes) = value.as_bytes(); + either!(flag == VVRTNumber::INT_TAG + => i32::from_be_bytes(bytes) + ; f32::from_be_bytes(bytes) as i32 + ) + } +} + +impl From<VVRTNumber> for f32 { + fn from(value: VVRTNumber) -> Self { + let (flag, bytes) = value.as_bytes(); + either!(flag == VVRTNumber::INT_TAG + => i32::from_be_bytes(bytes) as f32 + ; f32::from_be_bytes(bytes) + ) + } +} + +impl From<i32> for VVRTNumber { + fn from(value: i32) -> Self { + let [b1, b2, b3, b4] = value.to_be_bytes(); + VVRTNumber::from_number_be_bytes([b1, b2, b3, b4, VVRTNumber::INT_TAG, 0, 0, 0]) + } +} + +impl From<f32> for VVRTNumber { + fn from(value: f32) -> Self { + let [b1, b2, b3, b4] = value.to_be_bytes(); + VVRTNumber::from_number_be_bytes([b1, b2, b3, b4, VVRTNumber::FLT_TAG, 0, 0, 0]) + } +} + +impl std::fmt::Debug for VVRTNumber { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let (flag, bytes) = self.as_bytes(); + f.debug_struct("VVRTNumber") + .field("flag", &flag) + .field("bytes", &bytes) + .finish() + } +} + +impl std::fmt::Display for VVRTNumber { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self.is_f32() { + true => write!(f, "{}", Into::<f32>::into(*self)), + false => write!(f, "{}", Into::<i32>::into(*self)), + } + } +} diff --git a/src/Rust/vvs_runtime_types/src/types/sequence.rs b/src/Rust/vvs_runtime_types/src/types/sequence.rs new file mode 100644 index 0000000000000000000000000000000000000000..3d315014ec52852e3805f4dcbcb1eae831ce0d62 --- /dev/null +++ b/src/Rust/vvs_runtime_types/src/types/sequence.rs @@ -0,0 +1,107 @@ +use crate::types::*; +use std::{ptr::NonNull, rc::Rc}; + +#[derive(Debug, Clone, Copy)] +#[repr(transparent)] +pub struct VVRTSeq(NonNull<Vec<VVRTAny>>); +crate::types::any::impl_try_from_any! { Seq => VVRTSeq } + +impl VVRTSeq { + #[inline] + pub fn dangling() -> Self { + Self(NonNull::dangling()) + } + + #[inline] + pub fn as_ptr(self) -> *mut u64 { + self.0.as_ptr() as *mut _ + } + + #[inline] + fn as_slice(&self) -> &[VVRTAny] { + unsafe { self.0.as_ref() }.as_slice() + } + + #[inline] + fn from_vec(content: Vec<VVRTAny>) -> Self { + unsafe { Self(NonNull::new_unchecked(Rc::into_raw(Rc::new(content)) as *mut _)) } + } +} + +impl Default for VVRTSeq { + #[inline] + fn default() -> Self { + Self::from_vec(Default::default()) + } +} + +impl Eq for VVRTSeq {} +impl PartialEq for VVRTSeq { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.as_slice() == other.as_slice() + } +} + +/// Module used to defined functions to be exported to the JIT. +#[allow(clippy::missing_safety_doc)] +#[vvs_procmacro::vvrt_bridge(VVRTSeq)] +mod ffi { + #[no_mangle] + pub unsafe extern "C" fn new() -> VVRTSeq { + Default::default() + } + + /// Here we decrement the count of each child because we owned them. We don't support cyclic + /// references... + #[no_mangle] + pub unsafe extern "C" fn drop(this @ VVRTSeq(ptr): VVRTSeq) { + this.as_slice().iter().for_each(|child| VVRTAny_drop(*child)); + Rc::decrement_strong_count(ptr.as_ptr()); + } + + /// Here we increment the count of each child because we owned them. We don't support cyclic + /// references... + #[no_mangle] + pub unsafe extern "C" fn clone(this @ VVRTSeq(ptr): VVRTSeq) -> VVRTSeq { + this.as_slice().iter().for_each(|child| { + let _ = VVRTAny_clone(*child); + }); + Rc::increment_strong_count(ptr.as_ptr()); + VVRTSeq(ptr) + } + + #[no_mangle] + pub unsafe extern "C" fn deep_clone(VVRTSeq(ptr): VVRTSeq) -> VVRTSeq { + let mut content = Vec::with_capacity(ptr.as_ref().len()); + ptr.as_ref().iter().for_each(|e| content.push(VVRTAny_deep_clone(*e))); + VVRTSeq::from_vec(content) + } + + /// Get an item from the sequence, clone it. + #[no_mangle] + pub unsafe extern "C" fn get(this: VVRTSeq, idx: i32) -> VVRTAny { + this.as_slice() + .get(idx.clamp(0, i32::MAX) as usize) + .map(|item| VVRTAny_clone(*item)) + .unwrap_or_default() + } + + /// Push an item into the sequence, we take ownership of the item. + #[no_mangle] + pub unsafe extern "C" fn push(VVRTSeq(mut this): VVRTSeq, item: VVRTAny) { + debug_assert!( + !matches!(item.ty(), VVRTType::Table | VVRTType::Seq), + "can't store container in containers" + ); + this.as_mut().push(item); + } + + #[no_mangle] + pub unsafe extern "C" fn len(seq: VVRTSeq) -> i32 { + seq.as_slice().len().try_into().expect("sequence to big") + } + + #[rustfmt::skip] #[no_mangle] unsafe extern "C" fn eq(this: VVRTSeq, other: VVRTSeq) -> bool { PartialEq::eq(&this, &other) } + #[rustfmt::skip] #[no_mangle] unsafe extern "C" fn ne(this: VVRTSeq, other: VVRTSeq) -> bool { PartialEq::ne(&this, &other) } +} diff --git a/src/Rust/vvs_runtime_types/src/types/string.rs b/src/Rust/vvs_runtime_types/src/types/string.rs new file mode 100644 index 0000000000000000000000000000000000000000..e6525f71dd3f57b27312ad6c8c270cd3aa0eca64 --- /dev/null +++ b/src/Rust/vvs_runtime_types/src/types/string.rs @@ -0,0 +1,122 @@ +use crate::types::*; +use std::{hash::Hash, ptr::NonNull, rc::Rc}; + +/// We represent a string, in an FFI-Safe way because slices are not FFI-Safe... +#[derive(Debug, Clone, Copy)] +#[repr(transparent)] +pub struct VVRTString(NonNull<Vec<u8>>); +crate::types::any::impl_try_from_any! { String => VVRTString } + +impl VVRTString { + #[inline] + pub fn dangling() -> Self { + Self(NonNull::dangling()) + } + + #[inline] + pub fn as_ptr(self) -> *mut u64 { + self.0.as_ptr() as *mut _ + } + + #[inline] + pub fn as_str(&self) -> &str { + unsafe { std::str::from_utf8_unchecked(self.as_bytes()) } + } + + #[inline] + pub fn as_bytes(&self) -> &[u8] { + unsafe { self.0.as_ref().as_slice() } + } + + #[inline] + pub fn from_bytes(bytes: &[u8]) -> Self { + Self::from_vec(bytes.to_vec()) + } + + #[inline] + pub fn from_vec(bytes: Vec<u8>) -> Self { + unsafe { VVRTString(NonNull::new_unchecked(Rc::into_raw(Rc::new(bytes)) as *mut _)) } + } +} + +impl Default for VVRTString { + fn default() -> Self { + Self::from_vec(Default::default()) + } +} + +impl AsRef<str> for VVRTString { + #[inline] + fn as_ref(&self) -> &str { + self.as_str() + } +} + +impl Eq for VVRTString {} +impl PartialEq for VVRTString { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.as_str() == other.as_str() + } +} + +impl Hash for VVRTString { + #[inline] + fn hash<H: std::hash::Hasher>(&self, state: &mut H) { + self.as_str().hash(state); + } +} + +impl PartialOrd for VVRTString { + #[inline] + fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { + PartialOrd::partial_cmp(self.as_str(), other.as_str()) + } +} + +/// Module used to defined functions to be exported to the JIT. +#[allow(clippy::missing_safety_doc)] +#[vvs_procmacro::vvrt_bridge(VVRTString)] +mod ffi { + #[no_mangle] + unsafe extern "C" fn new_from_raw(ptr: *const u8, len: i32) -> VVRTString { + let len: usize = len.try_into().expect("string too big"); + VVRTString::from_bytes(std::slice::from_raw_parts(ptr, len)) + } + + #[no_mangle] + unsafe extern "C" fn cat(left: VVRTString, right: VVRTString) -> VVRTString { + let mut res = left.as_bytes().to_vec(); + res.extend_from_slice(right.as_bytes()); + VVRTString::from_vec(res) + } + + #[no_mangle] + pub unsafe extern "C" fn deep_clone(this: VVRTString) -> VVRTString { + VVRTString_clone(this) + } + + #[no_mangle] + unsafe extern "C" fn clone(VVRTString(ptr): VVRTString) -> VVRTString { + Rc::increment_strong_count(ptr.as_ptr()); + VVRTString(ptr) + } + + #[no_mangle] + unsafe extern "C" fn drop(VVRTString(ptr): VVRTString) { + Rc::decrement_strong_count(ptr.as_ptr()) + } + + #[no_mangle] + unsafe extern "C" fn len(str: VVRTString) -> i32 { + str.as_str().len().try_into().expect("string too long") + } + + use std::cmp::Ordering::*; + #[rustfmt::skip] #[no_mangle] unsafe extern "C" fn eq(a: VVRTString, b: VVRTString) -> bool { PartialEq::eq(&a, &b) } + #[rustfmt::skip] #[no_mangle] unsafe extern "C" fn ne(a: VVRTString, b: VVRTString) -> bool { PartialEq::ne(&a, &b) } + #[rustfmt::skip] #[no_mangle] unsafe extern "C" fn lt(a: VVRTString, b: VVRTString) -> bool { matches!(a.partial_cmp(&b), Some(Less )) } + #[rustfmt::skip] #[no_mangle] unsafe extern "C" fn gt(a: VVRTString, b: VVRTString) -> bool { matches!(a.partial_cmp(&b), Some(Greater )) } + #[rustfmt::skip] #[no_mangle] unsafe extern "C" fn le(a: VVRTString, b: VVRTString) -> bool { matches!(a.partial_cmp(&b), Some(Less | Equal)) } + #[rustfmt::skip] #[no_mangle] unsafe extern "C" fn ge(a: VVRTString, b: VVRTString) -> bool { matches!(a.partial_cmp(&b), Some(Greater | Equal)) } +} diff --git a/src/Rust/vvs_runtime_types/src/types/syllabe.rs b/src/Rust/vvs_runtime_types/src/types/syllabe.rs new file mode 100644 index 0000000000000000000000000000000000000000..4fedf77492776567bcaf3f2f9b3d4f3ac8b2c322 --- /dev/null +++ b/src/Rust/vvs_runtime_types/src/types/syllabe.rs @@ -0,0 +1,91 @@ +use crate::types::*; +use std::{ptr::NonNull, rc::Rc}; +use vvs_ass::ASSSyllabe; + +/// Represent a syllabe, in an ffi-safe way. We represent if the syllabe was create by using an Rc +/// or was built from a reference. +#[derive(Debug, Clone, Copy)] +#[repr(C)] +pub struct VVRTSyllabe(NonNull<ASSSyllabe<VVRTTable>>); +crate::types::any::impl_try_from_any! { ASSSyllabe => VVRTSyllabe } + +impl VVRTSyllabe { + #[inline] + pub fn dangling() -> Self { + Self(NonNull::dangling()) + } + + #[inline] + pub fn as_ptr(self) -> *mut u64 { + self.0.as_ptr() as *mut _ + } + + #[inline] + pub fn is_rc(&self) -> bool { + !self.as_ref().aux.rt_infos().is_ass_borrowed + } +} + +impl From<ASSSyllabe<VVRTTable>> for VVRTSyllabe { + fn from(mut value: ASSSyllabe<VVRTTable>) -> Self { + value.aux.rt_infos_mut().is_ass_borrowed = false; + let ptr = Rc::into_raw(Rc::new(value)) as *mut _; + VVRTSyllabe(unsafe { NonNull::new_unchecked(ptr) }) + } +} + +impl AsRef<ASSSyllabe<VVRTTable>> for VVRTSyllabe { + fn as_ref(&self) -> &ASSSyllabe<VVRTTable> { + unsafe { self.0.as_ref() } + } +} + +impl AsMut<ASSSyllabe<VVRTTable>> for VVRTSyllabe { + fn as_mut(&mut self) -> &mut ASSSyllabe<VVRTTable> { + unsafe { self.0.as_mut() } + } +} + + +impl Eq for VVRTSyllabe {} +impl PartialEq for VVRTSyllabe { + fn eq(&self, other: &Self) -> bool { + self.as_ref().eq(other.as_ref()) + } +} + +/// Module used to defined functions to be exported to the JIT. +#[allow(clippy::missing_safety_doc)] +#[vvs_procmacro::vvrt_bridge(VVRTSyllabe)] +mod ffi { + #[no_mangle] + pub unsafe extern "C" fn deep_clone(this: VVRTSyllabe) -> VVRTSyllabe { + this.as_ref().clone().into() + } + + #[no_mangle] + unsafe extern "C" fn clone(this @ VVRTSyllabe(ptr): VVRTSyllabe) -> VVRTSyllabe { + match this.is_rc() { + false => VVRTSyllabe_deep_clone(this), + true => { + Rc::increment_strong_count(ptr.as_ptr()); + this + } + } + } + + #[no_mangle] + unsafe extern "C" fn drop(this @ VVRTSyllabe(ptr): VVRTSyllabe) { + if this.is_rc() { + Rc::decrement_strong_count(ptr.as_ptr()) + } + } + + #[no_mangle] + unsafe extern "C" fn len(this: VVRTSyllabe) -> i32 { + this.as_ref().content.len().clamp(0, i32::MAX as usize) as i32 + } + + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn eq(this: VVRTSyllabe, other: VVRTSyllabe) -> bool { PartialEq::eq(&this, &other) } + #[rustfmt::skip] #[no_mangle] pub unsafe extern "C" fn ne(this: VVRTSyllabe, other: VVRTSyllabe) -> bool { PartialEq::ne(&this, &other) } +} diff --git a/src/Rust/vvs_runtime_types/src/types/table.rs b/src/Rust/vvs_runtime_types/src/types/table.rs new file mode 100644 index 0000000000000000000000000000000000000000..fa89182e36116a1b3c267123a9de797cf93eda6e --- /dev/null +++ b/src/Rust/vvs_runtime_types/src/types/table.rs @@ -0,0 +1,171 @@ +use crate::types::*; +use hashbrown::HashMap; +use std::{ptr::NonNull, rc::Rc}; + +/// Aux struct used to store infos about runtime types that imbark a VVRTTable and where we don't +/// have enaugh space in the trailing zeros of the pointer to store them... +#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)] +pub struct VVRTInfos { + pub is_ass_borrowed: bool, +} + +/// A table, really just a hashmap. +/// +/// NOTE: Needs to be clone to be able to be used in the ASS things... +/// +/// In a table we also embark an AUX structure to store runtime informations about ass types that +/// owns this table, or any other thing that may be necessary latter down the line... When +/// comparing tables we don't compare the [VVRTInfos] struct. +#[derive(Debug, Clone, Copy)] +#[repr(transparent)] +pub struct VVRTTable(NonNull<(HashMap<VVRTString, VVRTAny>, VVRTInfos)>); +crate::types::any::impl_try_from_any! { Table => VVRTTable } + +impl VVRTTable { + #[inline] + pub fn dangling() -> Self { + Self(NonNull::dangling()) + } + + #[inline] + pub fn as_ptr(self) -> *mut u64 { + self.0.as_ptr() as *mut _ + } + + #[inline] + pub fn iter(&self) -> hashbrown::hash_map::Iter<VVRTString, VVRTAny> { + unsafe { self.0.as_ref() }.0.iter() + } + + #[inline] + pub fn iter_mut(&mut self) -> hashbrown::hash_map::IterMut<VVRTString, VVRTAny> { + unsafe { self.0.as_mut() }.0.iter_mut() + } + + #[inline] + pub fn rt_infos(&self) -> &VVRTInfos { + &unsafe { self.0.as_ref() }.1 + } + + #[inline] + pub fn rt_infos_mut(&mut self) -> &mut VVRTInfos { + &mut unsafe { self.0.as_mut() }.1 + } +} + +impl AsMut<HashMap<VVRTString, VVRTAny>> for VVRTTable { + fn as_mut(&mut self) -> &mut HashMap<VVRTString, VVRTAny> { + &mut unsafe { self.0.as_mut() }.0 + } +} + +impl AsRef<HashMap<VVRTString, VVRTAny>> for VVRTTable { + fn as_ref(&self) -> &HashMap<VVRTString, VVRTAny> { + &unsafe { self.0.as_ref() }.0 + } +} + +impl vvs_ass::AuxTable for VVRTTable { + #[inline] + fn deep_clone(&self) -> Self { + unsafe { VVRTTable_deep_clone(*self) } + } +} + +impl Default for VVRTTable { + #[inline] + fn default() -> Self { + HashMap::<VVRTString, VVRTAny>::default().into() + } +} + +impl From<HashMap<VVRTString, VVRTAny>> for VVRTTable { + #[inline] + fn from(value: HashMap<VVRTString, VVRTAny>) -> Self { + Self(unsafe { NonNull::new_unchecked(Rc::into_raw(Rc::new(value)) as *mut _) }) + } +} + +impl Eq for VVRTTable {} +impl PartialEq for VVRTTable { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.as_ref().eq(other.as_ref()) + } +} + +/// Module used to define functions to be exported for the JIT. +#[allow(clippy::missing_safety_doc)] +#[vvs_procmacro::vvrt_bridge(VVRTTable)] +mod ffi { + #[no_mangle] + pub unsafe extern "C" fn new() -> VVRTTable { + Default::default() + } + + /// Deeply clone the table. + #[no_mangle] + pub unsafe extern "C" fn deep_clone(this: VVRTTable) -> VVRTTable { + this.as_ref() + .iter() + .map(|(k, v)| (VVRTString_clone(*k), VVRTAny_deep_clone(*v))) + .collect::<HashMap<_, _>>() + .into() + } + + /// Increment the count of each child because we own them. This function is not-reentrent and + /// we don't support cyclic references... + #[no_mangle] + pub unsafe extern "C" fn clone(this @ VVRTTable(ptr): VVRTTable) -> VVRTTable { + this.iter().for_each(|(key, value)| { + let _ = VVRTString_clone(*key); + let _ = VVRTAny_clone(*value); + }); + Rc::increment_strong_count(ptr.as_ptr()); + VVRTTable(ptr) + } + + // Decrement the count of each child because we own them. We don't support cyclic references... + #[no_mangle] + pub unsafe extern "C" fn drop(this @ VVRTTable(ptr): VVRTTable) { + this.iter().for_each(|(key, value)| { + VVRTString_drop(*key); + VVRTAny_drop(*value); + }); + Rc::decrement_strong_count(ptr.as_ptr()) + } + + /// Insert something into the table. Any old present value will be dropped. The key and value + /// are consumed by this function. + #[no_mangle] + pub unsafe extern "C" fn insert(mut table: VVRTTable, key: VVRTString, value: VVRTAny) { + debug_assert!( + !matches!(value.ty(), VVRTType::Table | VVRTType::Seq), + "can't store container in containers" + ); + if let Some(old) = table.as_mut().insert(key, value) { + VVRTAny_drop(old) + } + } + + /// Insert something into the table. Any old present value will be dropped. The value is + /// consumed by this function. The key string will be used to create a new string. + #[no_mangle] + pub unsafe extern "C" fn insert_from_raw_key(table: VVRTTable, key: *const u8, len: i32, value: VVRTAny) { + let key = VVRTString_new_from_raw(key, len); + VVRTTable_insert(table, key, value); + } + + /// Get the content of of the table. The thing is cloned when getted from the table. + #[no_mangle] + pub unsafe extern "C" fn get(table: VVRTTable, key: VVRTString) -> VVRTAny { + table + .as_ref() + .get(&key) + .map(|item| VVRTAny_clone(*item)) + .unwrap_or_default() + } + + #[rustfmt::skip] #[no_mangle] unsafe extern "C" fn eq(this: VVRTTable, other: VVRTTable) -> bool { PartialEq::eq(&this, &other) } + #[rustfmt::skip] #[no_mangle] unsafe extern "C" fn ne(this: VVRTTable, other: VVRTTable) -> bool { PartialEq::ne(&this, &other) } +} diff --git a/src/Rust/vvs_runtime_types/src/types/test.rs b/src/Rust/vvs_runtime_types/src/types/test.rs new file mode 100644 index 0000000000000000000000000000000000000000..f10738bf74b413051d629b592744fb4473541963 --- /dev/null +++ b/src/Rust/vvs_runtime_types/src/types/test.rs @@ -0,0 +1,30 @@ +use super::*; +use std::mem::size_of; + +#[test] +fn nil_and_options() { + let nil = unsafe { VVRTAny_nil() }; + assert_eq!(nil.ty(), VVRTType::Nil, "invalid type"); + assert_eq!(size_of::<VVRTType>(), size_of::<Option<VVRTType>>()); +} + +#[test] +fn any_integer() { + unsafe { + let zero = Into::<VVRTAny>::into(0i32); + assert!(VVRTAny_is_ty(zero, VVRTType::Number)); + assert!(!zero.number_is_f32()); + assert!(zero.number_is_i32()); + assert_eq!(VVRTAny_as_integer(zero), 0); + assert_eq!(VVRTAny_as_floating(zero), 0.0); + + let zero = Into::<VVRTAny>::into(0f32); + assert!(VVRTAny_is_ty(zero, VVRTType::Number)); + assert!(zero.number_is_f32()); + assert!(!zero.number_is_i32()); + assert_eq!(VVRTAny_as_integer(zero), 0); + assert_eq!(VVRTAny_as_floating(zero), 0.0); + + assert!(VVRTAny_ne(Into::<VVRTAny>::into(0f32), Into::<VVRTAny>::into(0i32))); + } +} diff --git a/src/Rust/vvs_runtime_types/src/types/variant.rs b/src/Rust/vvs_runtime_types/src/types/variant.rs new file mode 100644 index 0000000000000000000000000000000000000000..92da9f775f9b113fdfe44d95a7d4e3159c6e55b8 --- /dev/null +++ b/src/Rust/vvs_runtime_types/src/types/variant.rs @@ -0,0 +1,361 @@ +use crate::types::*; +use anyhow::{anyhow, bail, ensure}; +use std::{ + alloc, + mem::{size_of, transmute}, + ptr::NonNull, + slice, str, +}; + +/// Store all the registered variants. We share variants between colors and movements. +static mut VARIANTS: Vec<VariantDescription> = Vec::new(); + +struct VariantDescription { + /// The name of the variant family in the AST, like color or movement. + ast_name: &'static str, + + /// The name of the variant in its family, like `rgb`, `move`, etc. + variant_name: &'static str, + + /// The content of this variant, we store the runtime types here. + arguments: Vec<VVRTType>, + + /// The layout of this variant. If we have a string we don't store the content of said string + /// here, we only take into account the integer used to store the length of the string. + layout: alloc::Layout, + + /// The layouts of the content of this variant. Note that we also store the offset of the + /// discriminent in this vector. Because of that, we have the following: + /// `assert!(arguments.len() == offsets.len() + 1)`; + offsets: Vec<usize>, +} + +unsafe fn get_variant_argument_count_by_discriminent(discriminent: usize) -> i32 { + VARIANTS[discriminent].arguments.len() as i32 +} + +unsafe fn get_variant_desc_by_name( + ast: &str, + var: &str, +) -> (usize, &'static alloc::Layout, &'static [usize], &'static [VVRTType]) { + VARIANTS + .iter() + .enumerate() + .find_map( + |(idx, VariantDescription { ast_name, variant_name, layout, offsets, arguments })| { + (*ast_name == ast && *variant_name == var).then_some((idx, layout, &**offsets, &**arguments)) + }, + ) + .expect("asked to build an invalid variant") +} + +#[derive(Debug, Clone, Copy)] +#[repr(transparent)] +pub struct VVRTVariant(NonNull<u64>); +crate::types::any::impl_try_from_any! { Variant => VVRTVariant } + +impl VVRTVariant { + #[inline] + pub fn dangling() -> Self { + Self(NonNull::dangling()) + } + + #[inline] + pub fn discriminent(&self) -> usize { + unsafe { *transmute::<*mut u64, *const usize>(self.0.as_ptr()) } + } + + /// # Safety + /// This function is not thread safe. + pub unsafe fn register_runtime_variant( + ast_name: &'static str, + variant_name: &'static str, + arguments: Vec<VVRTType>, + ) -> anyhow::Result<()> { + use VVRTType::*; + let name = format!("{ast_name}.{variant_name}"); + + if let [heads @ .., last] = &arguments[..] { + heads.iter().copied().enumerate().try_for_each(|(idx, ty)| { + (!matches!(ty, Number)) + .then_some(()) + .ok_or_else(|| anyhow!("found invalid argument type `{ty}` at position {idx} in variant `{name}`")) + })?; + ensure!( + matches!(last, String | Number), + "found invalid argument type `{last}` at last position in variant `{name}`" + ); + } + + (!VARIANTS + .iter() + .any(|desc| desc.ast_name == ast_name && desc.variant_name == variant_name)) + .then(|| -> anyhow::Result<()> { + let (layout, offsets) = VVRTVariant::layout(&arguments)?; + VARIANTS.push(VariantDescription { ast_name, variant_name, arguments, layout, offsets }); + Ok(()) + }) + .ok_or_else(|| anyhow!("redefinition of variant {name}"))? + } + + /// Get the location of the variant. + #[inline] + pub fn as_ptr(self) -> *mut u64 { + self.0.as_ptr() + } + + /// Get the base of the memory corresponding to the passed index along side the type of this + /// memory location. + unsafe fn offset_of_index(&self, idx: i32) -> (*const u8, VVRTType) { + let VariantDescription { arguments, offsets, .. } = + VARIANTS.get(self.discriminent()).expect("variant was not valid"); + + debug_assert!(arguments.len() == offsets.len() + 1, "invalid variant"); + debug_assert!(arguments.len() > idx as usize, "invalid index"); + + // In the offsets we store the initial index for the discriminent in the offsets also! + let ptr: *const u8 = self.0.as_ptr().byte_add(offsets[idx as usize + 1]) as *const _; + (ptr, arguments[idx as usize]) + } + + /// Compute the layout for the content of a variant. Because of how we represent strings in a + /// variant, a vairant is immutable, like strings. Here we don't put the space for the content + /// of the string because we can't know it. + fn layout(body: &[VVRTType]) -> anyhow::Result<(alloc::Layout, Vec<usize>)> { + // We need the first element to be the discriminent of the variant. The discriminent is + // the index in the variant vector, thus we need a usize. + let init = (alloc::Layout::new::<usize>(), vec![0]); + + // We fold the body into the layout. + let fold = |(body, mut offsets): (alloc::Layout, Vec<usize>), elem: VVRTType| { + let (body, next) = body.extend(match elem { + // Only the length. Because of the alignement, the next two bytes are always + // allocated for the content of the string, so we don't waste too much space. + VVRTType::String => alloc::Layout::new::<i32>(), + + // For numbers we directly use an any. + VVRTType::Number => alloc::Layout::new::<VVRTAny>(), + + _ => bail!("invalid type `{elem}` in variant"), + })?; + offsets.push(next); + Ok::<_, anyhow::Error>((body, offsets)) + }; + + body.iter() + .copied() + .try_fold(init, fold) + .map(|(layout, offsets)| (layout.pad_to_align(), offsets)) + } + + /// Get the layout for the current value. In this layout we have the space for the content of + /// the string. + fn get_value_layout(&self) -> alloc::Layout { + let VariantDescription { arguments, layout, offsets, .. } = unsafe { &VARIANTS[self.discriminent()] }; + + match (arguments.last(), offsets.last()) { + (Some(VVRTType::String), Some(offset)) => { + // Get the memory layout for where we store the string. + let str_len = unsafe { *(self.0.as_ptr().add(*offset) as *const i32) as usize }; + let str_layout = alloc::Layout::array::<u8>(str_len); + + // Get the total layout. Just assert we are not doing things too big. + let layout = layout.extend(str_layout.expect("too big")).expect("too big").0; + + // Because of C things, we must pad the layout up to the align value, which should + // be the same as `*mut u64`. + layout.pad_to_align() + } + + _ => *layout, + } + } + + /// Like [VVRTVariant_get] but for [VVRTNumber]. Return default on type error. + fn get_number(&self, idx: i32) -> VVRTNumber { + match unsafe { self.offset_of_index(idx) } { + (ptr, VVRTType::Number) => Into::into(unsafe { *(ptr as *const VVRTAny) }), + _ => Default::default(), + } + } + + /// Like [self::VVRTVariant_get] but for the string in the variant. Return default on type + /// error. Here we don't have an index because we know that we have only one string in the + /// variant and that it's at the last index. + fn get_string(&self) -> &str { + match unsafe { self.offset_of_index(get_variant_argument_count_by_discriminent(self.discriminent()) - 1) } { + (ptr, VVRTType::String) => unsafe { + str::from_utf8_unchecked(slice::from_raw_parts( + ptr.byte_add(size_of::<i32>()), + *(ptr as *const i32) as usize, + )) + }, + _ => Default::default(), + } + } +} + +impl AsRef<[u8]> for VVRTVariant { + #[inline] + fn as_ref(&self) -> &[u8] { + unsafe { slice::from_raw_parts(self.0.as_ptr() as *const u8, self.get_value_layout().size()) } + } +} + +impl Eq for VVRTVariant {} +impl PartialEq for VVRTVariant { + #[inline] + fn eq(&self, other: &Self) -> bool { + (self.discriminent() == other.discriminent()) && (self.as_ref() == other.as_ref()) + } +} + +/// Module used to defined functions to be exported to the JIT. +#[allow(clippy::missing_safety_doc)] +#[vvs_procmacro::vvrt_bridge(VVRTVariant)] +mod ffi { + use std::borrow::Cow; + + #[no_mangle] + unsafe extern "C" fn new( + ast_ptr: *const u8, + ast_len: i32, + var_ptr: *const u8, + var_len: i32, + str_ptr: *const u8, + str_len: i32, + ) -> VVRTVariant { + let ast = str::from_utf8_unchecked(slice::from_raw_parts(ast_ptr, ast_len as usize)); + let var = str::from_utf8_unchecked(slice::from_raw_parts(var_ptr, var_len as usize)); + let (discriminent, layout, offsets, types) = get_variant_desc_by_name(ast, var); + + // Get the layout for the variant to allocate. + let (layout, string_offset) = match types { + [body @ .., _] if body.iter().copied().any(|t| t == VVRTType::String) => { + unreachable!("strings must be in last position in variants") + } + [.., VVRTType::String] => { + let (layout, next) = layout + .extend(alloc::Layout::array::<u8>(str_len as usize).expect("too big")) + .expect("too big"); + (layout.pad_to_align(), Some(next)) + } + _ => (*layout, None), + }; + + // Create and initialize the variant. Pay attention that the unit of the pointer is a byte + // (a u8...) + let ptr: NonNull<u8> = NonNull::new(alloc::alloc(layout)).expect("out of memory"); + *transmute::<*mut u8, *mut usize>(ptr.as_ptr()) = discriminent; + slice::from_raw_parts_mut(ptr.as_ptr(), layout.size()) + .iter_mut() + .skip(size_of::<usize>()) + .for_each(|byte: &mut u8| std::ptr::write(byte, 0)); + + // If we have a string we must copy it. + if let Some(string_offset) = string_offset { + std::ptr::write( + ptr.as_ptr().byte_add(*offsets.last().expect("invalid variant")) as *mut i32, + str_len, + ); + std::ptr::copy_nonoverlapping(str_ptr, ptr.as_ptr().byte_add(string_offset), str_len as usize); + } + + // Ok, we can return the thing. + VVRTVariant(NonNull::new_unchecked(ptr.as_ptr() as *mut _)) + } + + /// Create a new string from the content of the variant. + #[no_mangle] + unsafe extern "C" fn to_string(var: VVRTVariant) -> VVRTString { + let discriminent = var.discriminent(); + let VariantDescription { ast_name, variant_name, arguments, .. } = &VARIANTS[discriminent]; + let mut pretty = format!("#({ast_name}.{variant_name}"); + + arguments.iter().copied().enumerate().for_each(|(idx, arg)| { + pretty.push_str(if idx == 0 { " " } else { ", " }); + pretty.push_str(&match arg { + VVRTType::Number => Cow::Owned(format!("{}", var.get_number(idx as i32))), + VVRTType::String => Cow::Borrowed(var.get_string()), + ty => unreachable!("invalid variant {ast_name}.{variant_name} at idx {idx}, got type: {ty}"), + }); + }); + + pretty.push(')'); + VVRTString::from_vec(pretty.into()) + } + + #[no_mangle] + unsafe extern "C" fn clone(this: VVRTVariant) -> VVRTVariant { + let layout = this.get_value_layout(); // Get the layout of the value, because we need to + // take into account the string part if any. + let ptr = NonNull::new(alloc::alloc(layout) as *mut u64).expect("out of memory"); + std::ptr::copy_nonoverlapping(this.0.as_ptr() as *const u8, ptr.as_ptr() as *mut u8, layout.size()); + VVRTVariant(ptr) + } + + /// Like [self::VVRTVariant_get] but for the string in the variant. Return default on type + /// error. Here we don't have an index because we know that we have only one string in the + /// variant and that it's at the last index. The string is allocated here and the codegen will + /// need to insert a drop call... + #[no_mangle] + pub unsafe extern "C" fn get_string(this: VVRTVariant) -> VVRTString { + Into::into(VVRTString::from_bytes(this.get_string().as_bytes())) + } + + /// Like [self::VVRTVariant_get] but for i32. Return default on type error. + #[no_mangle] + pub unsafe extern "C" fn get_i32(this: VVRTVariant, idx: i32) -> i32 { + this.get_number(idx).into() + } + + /// Like [self::VVRTVariant_get] but for f32. Return default on type error. + #[no_mangle] + pub unsafe extern "C" fn get_f32(this: VVRTVariant, idx: i32) -> f32 { + this.get_number(idx).into() + } + + /// Clone the result, may be freed by the user. + #[no_mangle] + pub unsafe extern "C" fn get(this: VVRTVariant, idx: i32) -> VVRTAny { + match this.offset_of_index(idx) { + // For numbers we use directly the any to store them. Because of the discriminent + // everything is already aligned in a good way. + (ptr, VVRTType::Number) => *(ptr as *const VVRTAny), + + // We have a string, the first 4 bytes are the length of said string, the next things + // are the content of said string. + (ptr, VVRTType::String) => Into::into(VVRTString::from_bytes(slice::from_raw_parts( + ptr.byte_add(size_of::<i32>()), + *(ptr as *const i32) as usize, + ))), + + _ => unreachable!("variant was not valid"), + } + } + + #[no_mangle] + pub unsafe extern "C" fn deep_clone(this: VVRTVariant) -> VVRTVariant { + VVRTVariant_clone(this) + } + + /// Creates a new string! + #[no_mangle] + unsafe extern "C" fn get_variant_name(ptr: VVRTVariant) -> VVRTString { + VVRTString::from_bytes(VARIANTS[ptr.discriminent()].variant_name.as_bytes()) + } + + /// Creates a new string! + #[no_mangle] + unsafe extern "C" fn get_ast_name(ptr: VVRTVariant) -> VVRTString { + VVRTString::from_bytes(VARIANTS[ptr.discriminent()].ast_name.as_bytes()) + } + + #[no_mangle] + unsafe extern "C" fn drop(var @ VVRTVariant(ptr): VVRTVariant) { + alloc::dealloc(ptr.as_ptr() as *mut _, var.get_value_layout()); + } + + #[rustfmt::skip] #[no_mangle] unsafe extern "C" fn eq(this: VVRTVariant, other: VVRTVariant) -> bool { PartialEq::eq(&this, &other) } + #[rustfmt::skip] #[no_mangle] unsafe extern "C" fn ne(this: VVRTVariant, other: VVRTVariant) -> bool { PartialEq::ne(&this, &other) } +} diff --git a/src/Rust/vvs_runtime_types/src/vvll.rs b/src/Rust/vvs_runtime_types/src/vvll.rs new file mode 100644 index 0000000000000000000000000000000000000000..cbaaeed35e945b95d92cd7dc7d398fb06730550a --- /dev/null +++ b/src/Rust/vvs_runtime_types/src/vvll.rs @@ -0,0 +1,101 @@ +#![allow(non_snake_case)] + +use hashbrown::{HashMap, HashSet}; +use std::{ffi::CString, sync::OnceLock}; +use vvs_lang::ast::ASTType; +use vvs_llvm::*; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct ManageFunctions { + pub clone: &'static str, + pub drop: &'static str, +} + +/// Store properties about a type and the associated functions. +#[derive(Debug, Default)] +pub struct Properties { + /// The drop/clone functions if present for this type. If [None], then we don't need to manage + /// the memory for this type. The drop function takes the thing, and the clone a const pointer + /// to the thing. + pub manage: Option<ManageFunctions>, + + /// The function to call to check the equality. Must take only two arguments, const pointers to + /// the same type, and return a boolean. This function doesn't consume the arguments. + pub equality: Option<&'static str>, + + /// The function to call to get the length of the item. Must take one argument, a const pointer + /// to the thing. This function doesn't consume the arguments. This function returns an + /// integer. + pub len: Option<&'static str>, + + /// Stores all the methods with some informations about them. + pub methods: HashMap<&'static str, (unsafe extern "C" fn(), LLVMTypeRef, ASTType)>, +} + +/// Trait used to give to the codegen the layout and functions associated with a type that is +/// present in the runtime and that must be handled in the codegen. +pub trait LLVMExported { + /// Get the layout of the type. + /// + /// # Safety + /// The [LLVMContextRef] must be valid. + unsafe fn llvm_type(_: LLVMContextRef) -> LLVMTypeRef; + + /// Get all the functions associated with a type and some properties of this type. For example, + /// integers and floating numbers can be copied without having to clone them, but strings, any, + /// table, sequences, etc, must be cloned and dropped when no longer used. + /// + /// # Safety + /// The [LLVMContextRef] must be valid. + unsafe fn llvm_properties(_: LLVMContextRef) -> Properties; +} + +/// Tells if a type is managed or not. +/// +/// # Safety +/// - All the managed types must have been exported into at least one module +/// - This function is not thread-safe +pub unsafe fn LLVMTypeIsManaged(ty: LLVMTypeRef) -> bool { + managed_types().contains(&ty) +} + +unsafe fn managed_types() -> &'static mut HashSet<LLVMTypeRef> { + static mut MANAGED_TYPES: OnceLock<HashSet<LLVMTypeRef>> = OnceLock::new(); + MANAGED_TYPES.get_or_init(HashSet::new); + MANAGED_TYPES.get_mut().expect(" should have been created") +} + +/// Register all the exported types and functions into a module. +/// +/// # Safety +/// - The [LLVMContextRef] must be valid +/// - the [LLVMModuleRef] must be valid +/// - This function is not thread-safe +pub unsafe fn LLVMRegisterExportedIntoModule( + c: LLVMContextRef, + m: LLVMModuleRef, +) -> Vec<(&'static str, ASTType, LLVMValueRef, LLVMTypeRef)> { + let mut ret = Vec::default(); + + macro_rules! handle { + ($ty: ty, $($tys: ty),+ $(,)?) => { + handle!($ty); + handle!($($tys),+); + }; + ($ty: ty) => { + let Properties { manage, equality: _, len: _, methods } = <$ty>::llvm_properties(c); + if manage.is_some() { + managed_types().insert(<$ty>::llvm_type(c)); + } + for (name, (_, ty, asttype)) in methods { + let cstr = CString::new(name).expect("invalid function name"); + let function = unsafe { LLVMAddFunction(m, cstr.as_ptr(), ty) }; + ret.push((name, asttype, function, ty)); + } + }; + } + + use crate::types::*; + handle!(VVRTType, VVRTAny, VVRTSeq, VVRTString, VVRTTable); + ret +} diff --git a/src/Rust/vvs_utils/Cargo.toml b/src/Rust/vvs_utils/Cargo.toml index b27c119fe14e52d7e91e34e794d9dcaf1f1cb131..557198c6ce57cb1bd2fa64533ce398ca6936b602 100644 --- a/src/Rust/vvs_utils/Cargo.toml +++ b/src/Rust/vvs_utils/Cargo.toml @@ -1,12 +1,13 @@ [package] -name = "vvs_utils" +name = "vvs_utils" +description = "Utility crate for VVS" version.workspace = true authors.workspace = true edition.workspace = true license.workspace = true -description = "Utility crate for VVS" [dependencies] thiserror.workspace = true -serde.workspace = true -log.workspace = true +anyhow.workspace = true +serde.workspace = true +log.workspace = true diff --git a/src/Rust/vvs_utils/src/angles.rs b/src/Rust/vvs_utils/src/angles.rs index 53424bca73c2b29483bc6bcba1bb6678334b9af6..4a2ecc70577ca6497cc7f7d3ac17c9c0e0e8e6de 100644 --- a/src/Rust/vvs_utils/src/angles.rs +++ b/src/Rust/vvs_utils/src/angles.rs @@ -1,17 +1,21 @@ use core::{f32::consts::PI as PI_32, f64::consts::PI as PI_64}; +#[inline] pub fn f64_randians_clamp(rad: f64) -> f64 { rad % (2.0 * PI_64) } +#[inline] pub fn f64_degres_clamp(rad: f64) -> f64 { rad % 360.0 } +#[inline] pub fn f32_randians_clamp(rad: f32) -> f32 { rad % (2.0 * PI_32) } +#[inline] pub fn f32_degres_clamp(rad: f32) -> f32 { rad % 360.0 } diff --git a/src/Rust/vvs_utils/src/assert.rs b/src/Rust/vvs_utils/src/assert.rs index 2f34f04cd47f83eac41e4a55613b88aec263c874..13f886d0f8aced3f8038d62ce07043c36f45962e 100644 --- a/src/Rust/vvs_utils/src/assert.rs +++ b/src/Rust/vvs_utils/src/assert.rs @@ -33,7 +33,7 @@ macro_rules! assert_ok { ($x: expr) => { match $x { Ok(x) => x, - Err(e) => panic!("failed '{}' with error '{e:?}'", stringify!($x)), + Err(e) => panic!("failed '{}' with error '{e}'", stringify!($x)), } }; } diff --git a/src/Rust/vvs_utils/src/conds.rs b/src/Rust/vvs_utils/src/conds.rs index 98256e0c5a19d2e900f59dc6b6f3c1c68f9c8969..715b6cc216f259a116a1e0e911e3a42712ffd8e1 100644 --- a/src/Rust/vvs_utils/src/conds.rs +++ b/src/Rust/vvs_utils/src/conds.rs @@ -9,10 +9,12 @@ macro_rules! either { }}; } +#[inline] pub fn f64_epsilon_eq(a: f64, b: f64) -> bool { (a - b).abs() <= 10E-10 } +#[inline] pub fn f32_epsilon_eq(a: f32, b: f32) -> bool { (a - b).abs() <= 10E-7 } diff --git a/src/Rust/vvs_utils/src/file/lock.rs b/src/Rust/vvs_utils/src/file/lock.rs index 4dfbdf3336da6f8e88110a5b8f065b8b21a8ed14..9d17fdc9729c443e0af46dad42b24242129ddf47 100644 --- a/src/Rust/vvs_utils/src/file/lock.rs +++ b/src/Rust/vvs_utils/src/file/lock.rs @@ -28,6 +28,7 @@ pub type LockResult<T> = Result<T, LockError>; pub struct LockFile(File); impl LockFile { + #[inline] fn handle_xdg_error(err: XDGError) -> LockError { match err { XDGError::ConfigIO(_, _, err) => Self::handle_io_error(err), @@ -35,6 +36,7 @@ impl LockFile { } } + #[inline] fn handle_io_error(err: IoError) -> LockError { match err.kind() { std::io::ErrorKind::AlreadyExists => LockError::AlreadyLocked, @@ -42,6 +44,7 @@ impl LockFile { } } + #[inline] fn create(app: impl AsRef<str>, file: String) -> LockResult<Self> { match XDGFolder::RuntimeDir .find(app, file, XDGFindBehaviour::NonExistingOnly) @@ -58,6 +61,7 @@ impl LockFile { } /// Create a lock file for another file. + #[inline] pub fn for_file(app: impl AsRef<str>, path: impl AsRef<Path>) -> LockResult<Self> { let mut s = DefaultHasher::new(); path.as_ref().hash(&mut s); @@ -65,6 +69,7 @@ impl LockFile { } /// Create a lock file for an hashable ressource. + #[inline] pub fn for_resource(app: impl AsRef<str>, rsc: impl Hash) -> LockResult<Self> { let mut s = DefaultHasher::new(); rsc.hash(&mut s); @@ -72,12 +77,14 @@ impl LockFile { } /// Create a lock file for an ID. + #[inline] pub fn for_id(app: impl AsRef<str>, id: u64) -> LockResult<Self> { Self::create(app, format!("{id:#X}.id.lock")) } } impl Drop for LockFile { + #[inline] fn drop(&mut self) { todo!("drop {:?}", self.0) } diff --git a/src/Rust/vvs_utils/src/file/temp.rs b/src/Rust/vvs_utils/src/file/temp.rs index 63537b834459f8c4d73abea7ae3b9ff02d762563..0a5dcd0ba2bab984dff3724dc7b9662c2595e679 100644 --- a/src/Rust/vvs_utils/src/file/temp.rs +++ b/src/Rust/vvs_utils/src/file/temp.rs @@ -32,18 +32,21 @@ pub struct TempFile(File); impl Deref for TempFile { type Target = File; + #[inline] fn deref(&self) -> &Self::Target { &self.0 } } impl DerefMut for TempFile { + #[inline] fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } } impl TempFile { + #[inline] fn handle_xdg_error(err: XDGError) -> TempError { match err { XDGError::ConfigIO(_, _, err) => Self::handle_io_error(err), @@ -51,6 +54,7 @@ impl TempFile { } } + #[inline] fn handle_io_error(err: IoError) -> TempError { match err.kind() { std::io::ErrorKind::AlreadyExists => TempError::Duplicate, @@ -59,6 +63,7 @@ impl TempFile { } #[cfg(unix)] + #[inline] fn create(app: impl AsRef<str>, file: impl AsRef<str>) -> TempResult<PathBuf> { let list = XDGFolder::RuntimeDir .find(app, file, XDGFindBehaviour::NonExistingOnly) @@ -83,10 +88,7 @@ impl TempFile { if !folder.is_dir() { Err(IoError::new( IoErrorKind::NotFound, - format!( - "folder doesn't exists or is not a directory: {}", - folder.to_string_lossy() - ), + format!("folder doesn't exists or is not a directory: {}", folder.to_string_lossy()), ) .into()) } else { @@ -98,6 +100,7 @@ impl TempFile { /// Create a new temporary file somewhere. Note that the creation pattern is predictible and /// not secure in any way. Moreover we depend on the fact that PID from dead processes are not /// reused between reboots, and that temp folder are cleared at reboots... + #[inline] pub fn new(app: impl AsRef<str>) -> TempResult<Self> { let (pid, rand) = (std::process::id(), crate::rand()); let file = OpenOptions::new() diff --git a/src/Rust/vvs_utils/src/lib.rs b/src/Rust/vvs_utils/src/lib.rs index 9a351c5015a64094cb67947f3d13930905882e7f..f7dc73802457f9a185e9eb49983d53e3718c36b2 100644 --- a/src/Rust/vvs_utils/src/lib.rs +++ b/src/Rust/vvs_utils/src/lib.rs @@ -8,7 +8,6 @@ pub mod file; pub mod xdg; pub use angles::*; -pub use assert::*; pub use conds::*; pub use minmax::*; pub use rand::*; diff --git a/src/Rust/vvs_utils/src/rand.rs b/src/Rust/vvs_utils/src/rand.rs index 9833b2e57278368b56f5a114d89c2864f8da35c7..8b10f723b7d7e0081548de65cf78d61c98cbeccb 100644 --- a/src/Rust/vvs_utils/src/rand.rs +++ b/src/Rust/vvs_utils/src/rand.rs @@ -11,10 +11,11 @@ struct MersenneTwister { thread_local! { /// We do our things here. - static MERSENNE: OnceLock<RefCell<MersenneTwister>> = OnceLock::new(); + static MERSENNE: OnceLock<RefCell<MersenneTwister>> = const { OnceLock::new() }; } /// Get the seed for the thread. +#[inline] fn get_seed() -> u64 { f64::to_bits( std::time::SystemTime::now() @@ -43,6 +44,7 @@ impl MersenneTwister { const LOWER_MASK: u64 = (1_u64 << MersenneTwister::R).overflowing_sub(1_u64).0; const UPPER_MASK: u64 = !Self::LOWER_MASK; + #[inline] fn twist(&mut self) { (0..Self::N).for_each(|i| { let index = i as usize; @@ -54,6 +56,7 @@ impl MersenneTwister { self.index = 0; } + #[inline] fn extract_number(&mut self) -> u64 { if self.index >= Self::N as usize { self.twist(); @@ -69,6 +72,7 @@ impl MersenneTwister { } /// Get next pseudo random number with our homebrew mersenne twister. +#[inline] pub fn rand() -> u64 { MERSENNE.with(|mt| { mt.get_or_init(|| { diff --git a/src/Rust/vvs_utils/src/xdg/config.rs b/src/Rust/vvs_utils/src/xdg/config.rs index 499ba276644a8d59e198bb3740efd6640d6c4f87..49339f5fcd76828effa3369f9c0d906be9132b5a 100644 --- a/src/Rust/vvs_utils/src/xdg/config.rs +++ b/src/Rust/vvs_utils/src/xdg/config.rs @@ -140,6 +140,7 @@ where const DEFAULT_FILE: &'static str = "config"; /// Create a new [XDGConfig] helper. + #[inline] pub fn new( app: &'a str, deserialize: impl Fn(String) -> Result<Format, Box<dyn std::error::Error>> + 'static, @@ -154,6 +155,7 @@ where } /// Change the file to resolve. + #[inline] pub fn file(&mut self, file: &'a str) -> &mut Self { self.file = Some(file); self @@ -161,6 +163,7 @@ where /// Get the name of the config file that we will try to read. Returns the default if not set by /// the user. + #[inline] pub fn get_file(&self) -> &str { match self.file.as_ref() { Some(file) => file, @@ -169,11 +172,13 @@ where } /// Search all config files in all locations... + #[inline] fn search_files(&self) -> Result<MaybeFolderList, XDGError> { XDGFolder::ConfigDirs.find(self.app, self.get_file(), XDGFindBehaviour::ExistingOnly) } /// Prepare config folders. + #[inline] pub fn prepare_folder(&self) -> impl IntoIterator<Item = <MaybeFolderList as IntoIterator>::Item> { XDGFolder::ConfigDirs.prepare_folder() } @@ -186,10 +191,7 @@ where /// Try to read the config file and deserialize it. pub fn try_read(&self) -> Result<Format, XDGError> { let Some(file) = self.search_files()?.into_first() else { - return Err(XDGError::ConfigNotFound( - self.app.to_string(), - self.get_file().to_string(), - )); + return Err(XDGError::ConfigNotFound(self.app.to_string(), self.get_file().to_string())); }; let file = std::fs::read_to_string(file) .map_err(|err| XDGError::ConfigIO(self.app.to_string(), self.get_file().to_string(), err))?; @@ -205,6 +207,7 @@ where /// Try to read the config file and deserialize it. If an error is encountred at any point, log /// it and return the provided default. If needed the default value is written on the disk, /// note that this operation may fail silently. + #[inline] pub fn read_or( &self, serialize: impl FnOnce(&Format) -> Result<String, Box<dyn std::error::Error>>, @@ -219,6 +222,7 @@ where /// Try to read the config file and deserialize it. If an error is encountred at any point, log /// it and return the provided default. If needed the default value is written on the disk, /// note that this operation may fail silently. + #[inline] pub fn read_or_else( &self, serialize: impl FnOnce(&Format) -> Result<String, Box<dyn std::error::Error>>, @@ -248,16 +252,12 @@ where ) }; - match std::fs::create_dir_all(path.parent().ok_or(XDGError::ConfigFileHasNoParentFolder( - self.app.to_string(), - self.get_file().to_string(), - ))?) { + match std::fs::create_dir_all( + path.parent() + .ok_or(XDGError::ConfigFileHasNoParentFolder(self.app.to_string(), self.get_file().to_string()))?, + ) { Err(err) if !matches!(err.kind(), std::io::ErrorKind::AlreadyExists) => { - return Err(XDGError::ConfigIO( - self.app.to_string(), - self.get_file().to_string(), - err, - )) + return Err(XDGError::ConfigIO(self.app.to_string(), self.get_file().to_string(), err)) } _ => {} } @@ -270,6 +270,7 @@ where /// Same as [XDGConfig::write] but log any error and fail silently, returning the value that /// was attempted to be written to disk. + #[inline] fn write_silent( &self, serialize: impl FnOnce(&Format) -> Result<String, Box<dyn std::error::Error>>, @@ -289,6 +290,7 @@ where /// Try to read the config file and deserialize it. If an error is encountred at any point, log /// it and return the default. If needed the default value is written on the disk, note that /// this operation may fail silently. + #[inline] pub fn read_or_default( &self, serialize: impl FnOnce(&Format) -> Result<String, Box<dyn std::error::Error>>, @@ -310,6 +312,7 @@ where /// When trying to read or write the default, we write the file with the same logic as the /// [XDGConfigFirst] variant, we add this function to reduce the code to write for the write /// logic... + #[inline] fn to_config_first(&self) -> XDGConfig<Format, XDGConfigFirst> { XDGConfig::<Format, XDGConfigFirst> { app: self.app, @@ -325,6 +328,7 @@ where /// the merge was silent. If no config file where found this is an error. All the files are /// merged, this operation can't fail, implementations must fail silently or have sane defaults /// and prefer files with higher priority. + #[inline] pub fn try_read(&self) -> Result<Format, XDGError> { Merged::try_read(self) } @@ -339,6 +343,7 @@ where /// log it and return the provided default if the merge was not silent, skip the file if it was /// silent. If needed the default value is written on the disk, note that this operation may /// fail silently. + #[inline] pub fn read_or( &self, serialize: impl FnOnce(&Format) -> Result<String, Box<dyn std::error::Error>>, @@ -354,6 +359,7 @@ where /// log it and return the provided default if the merge was not silent, skip the file if it was /// silent. If needed the default value is written on the disk, note that this operation may /// fail silently. + #[inline] pub fn read_or_else( &self, serialize: impl FnOnce(&Format) -> Result<String, Box<dyn std::error::Error>>, @@ -375,6 +381,7 @@ where /// log it and return the provided default if the merge was not silent, skip the file if it was /// silent. If needed the default value is written on the disk, note that this operation may /// fail silently. + #[inline] pub fn read_or_default( &self, serialize: impl FnOnce(&Format) -> Result<String, Box<dyn std::error::Error>>, diff --git a/src/Rust/vvs_utils/src/xdg/folders.rs b/src/Rust/vvs_utils/src/xdg/folders.rs index 4552b2c6ec1009c180c1fdc609e9166bfb809ba6..3933ddb5bcd836f5ee8854e8e45cfa4cfc02e9ca 100644 --- a/src/Rust/vvs_utils/src/xdg/folders.rs +++ b/src/Rust/vvs_utils/src/xdg/folders.rs @@ -109,9 +109,11 @@ impl XDGFolder { pub fn get_folder(&self) -> MaybeFolderList { #[cfg(unix)] mod variables { + #[inline] pub fn data_dirs(_: impl AsRef<std::path::Path>) -> super::MaybeFolderList { super::MaybeFolderList::from_iter(["/usr/local/share", "/usr/share"]) } + #[inline] pub fn config_dirs(_: impl AsRef<std::path::Path>) -> super::MaybeFolderList { super::MaybeFolderList::from("/etc/xdg") } @@ -232,27 +234,26 @@ impl XDGFolder { // The list that we want is empty, or all lists are empty, returns nothing -> should it // really be an error? - _ => Err(XDGError::NotFound( - *self, - app.as_ref().to_string(), - file.as_ref().to_string(), - )), + _ => Err(XDGError::NotFound(*self, app.as_ref().to_string(), file.as_ref().to_string())), } } /// Is this variable a folder list? + #[inline] pub fn is_list(&self) -> bool { use XDGFolder::*; matches!(self, DataDirs | ConfigDirs) } /// Get the env variable name associated with the folder or folder list. + #[inline] pub fn env_var_name(&self) -> &str { self.as_ref() } } impl AsRef<str> for XDGFolder { + #[inline] fn as_ref(&self) -> &str { match self { XDGFolder::DataHome => "XDG_DATA_HOME", @@ -268,6 +269,7 @@ impl AsRef<str> for XDGFolder { } impl std::fmt::Display for XDGFolder { + #[inline] fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "${}", self.as_ref()) } diff --git a/src/Rust/vvs_utils/src/xdg/mod.rs b/src/Rust/vvs_utils/src/xdg/mod.rs index bc1e04b27c284e24c064a55742a0f34d74008cec..54ca264481720bfadb95815200a862ca46c014a5 100644 --- a/src/Rust/vvs_utils/src/xdg/mod.rs +++ b/src/Rust/vvs_utils/src/xdg/mod.rs @@ -19,6 +19,7 @@ use thiserror::Error; /// Get the user's home folder. Panics if the env variable was not found or it can't be /// canonicalized. +#[inline] pub fn home_folder() -> PathBuf { PathBuf::from(std::env::var("HOME").expect("failed to get the $HOME env variable")) .canonicalize() diff --git a/src/Rust/vvs_utils/src/xdg/paths.rs b/src/Rust/vvs_utils/src/xdg/paths.rs index a99eb333ec554708af14902c402072946d0e26e8..7eec911df4add0c483c191671f06ac92f02fc4bb 100644 --- a/src/Rust/vvs_utils/src/xdg/paths.rs +++ b/src/Rust/vvs_utils/src/xdg/paths.rs @@ -28,16 +28,19 @@ pub struct MaybeFolderListIterator<'a> { impl MaybeFolderList { /// Is there no folder? + #[inline] pub fn is_none(&self) -> bool { matches!(self, MaybeFolderList::Empty) } /// Is there folders? + #[inline] pub fn is_some(&self) -> bool { !self.is_none() } /// Get the first folder, or the last folder. If no folder is present just returns [None]. + #[inline] pub fn first(&self) -> Option<&Path> { use MaybeFolderList::*; match self { @@ -97,6 +100,7 @@ impl MaybeFolderList { /// Get the first folder, or the last folder. If no folder is present just returns [None]. The /// difference from the [MaybeFolderList::first] function is that this function consumes the /// [MaybeFolderList]. + #[inline] pub fn into_first(self) -> Option<PathBuf> { use MaybeFolderList::*; match self { @@ -106,6 +110,7 @@ impl MaybeFolderList { } /// Get an iterator over the contained folders. + #[inline] pub fn iter(&self) -> MaybeFolderListIterator { let (next, list): (_, &[_]) = match self { MaybeFolderList::Empty => (None, &[]), @@ -116,6 +121,7 @@ impl MaybeFolderList { } /// Create a list of folders from a description string and a separator. + #[inline] pub(super) fn from_str_list(list: &str, separator: char) -> Self { let mut folders = list.split(separator); match folders.next() { @@ -157,6 +163,7 @@ impl<'a, S> From<S> for MaybeFolderList where S: AsRef<str> + 'a, { + #[inline] fn from(value: S) -> Self { MaybeFolderList::Folder(PathBuf::from(value.as_ref())) } @@ -166,14 +173,14 @@ impl<'a, P> FromIterator<P> for MaybeFolderList where P: AsRef<Path> + 'a, { + #[inline] fn from_iter<T: IntoIterator<Item = P>>(iter: T) -> Self { let mut folders = iter.into_iter(); match folders.next() { None => MaybeFolderList::Empty, - Some(first) => MaybeFolderList::Many( - first.as_ref().to_path_buf(), - folders.map(|p| p.as_ref().to_path_buf()).collect(), - ), + Some(first) => { + MaybeFolderList::Many(first.as_ref().to_path_buf(), folders.map(|p| p.as_ref().to_path_buf()).collect()) + } } } } @@ -182,6 +189,7 @@ impl IntoIterator for MaybeFolderList { type Item = PathBuf; type IntoIter = <Vec<PathBuf> as IntoIterator>::IntoIter; + #[inline] fn into_iter(self) -> Self::IntoIter { match self { MaybeFolderList::Empty => vec![].into_iter(), @@ -197,6 +205,7 @@ impl IntoIterator for MaybeFolderList { impl<'a> Iterator for MaybeFolderListIterator<'a> { type Item = &'a PathBuf; + #[inline] fn next(&mut self) -> Option<Self::Item> { let next = self.next?; match self.list.split_first() { diff --git a/utils/lua/sample-spec.module b/utils/lua/sample-spec.module deleted file mode 100644 index b007d97a926900929530b3043f19f42f83e31958..0000000000000000000000000000000000000000 --- a/utils/lua/sample-spec.module +++ /dev/null @@ -1,54 +0,0 @@ ---- Declaration - -local custom_opt = DeclareOption { option1 = false } -local time_opt = DeclareOption { preTime = -900, postTime = 300, } -local color_opt = DeclareOption { color1 = Vivy:newColor("#314159") } - -local module = DeclareModule { - name = "sample-spec", - description = "Sample script used for the specification proposition", - author = "Vivy", - revision = "rev-1254", - imports = { "utils" }, - options = { custom_opt, time_opt, color_opt }, - functions = { - DeclareFunction { "tripleCopySyl" }, - DeclareFunction { "printFoo" }, - ImportFunction { "utils", "prettyPrint" }, - }, - jobs = { - DeclareJob { "set_retime", options = { time_opt } }, - DeclareJob { "demultiply_syllabes" }, - ImportJob { "utils", "color_after_read_3", "utils", options = { color_opt } } - } -} - ---- Implementation - -local utils = module:import { "utils" } -local prettyPrint = module:import { "utils", "prettyPrint" } - -local tripleCopySyl = module:export { "tripleCopySyl", function (syl) - return { syl:copy(), syl:copy(), syl:copy() } -end } - -module:export { "printFoo", function () prettyPrint ("Bar") end } - -module:export { "retime_lines", LINE, function (opt, line) - line.start = line.start + opt.preTime - line.finish = line.start + opt.postTime - if line.start <= Vivy:start() then line.start = Vivy:start() end - if line.finish >= Vivy:finish() then line.finish = Vivy:finish() end - return line -end } - -module:export { "create_syllabes", SYLLABE, function (opt, syl) - local newSyls = tripleCopySyl(syl) - newSyls[1].start = syl.line.start - newSyls[1].finish = syl.start - newSyls[3].finish = syl.line.finish - newSyls[3].start = syl.finish - return newSyls -end } - --- vim: ft=lua diff --git a/utils/lua/simple.module b/utils/lua/simple.module deleted file mode 100644 index 85439d803a08c8f063282d4428d5aa0a61577e04..0000000000000000000000000000000000000000 --- a/utils/lua/simple.module +++ /dev/null @@ -1,48 +0,0 @@ ---- Declaration - -local custom_opt = DeclareOption { option1 = false } -local time_opt = DeclareOption { preTime = -900, postTime = 300, } -local color_opt = DeclareOption { color1 = Vivy:newColor("#314159") } - -local module = DeclareModule { - name = "sample-spec", - description = "Sample script used for the specification proposition", - author = "Vivy", - revision = "rev-1254", - options = { custom_opt, time_opt, color_opt }, - functions = { - DeclareFunction { "tripleCopySyl" }, - DeclareFunction { "printFoo" }, - }, - jobs = { - DeclareJob { "set_retime", options = { time_opt } }, - DeclareJob { "create_syllabes" }, - } -} - ---- Implementation - -local tripleCopySyl = module:export { "tripleCopySyl", function (syl) - return { syl:copy(), syl:copy(), syl:copy() } -end } - -module:export { "printFoo", function () prettyPrint ("Bar") end } - -module:export { "set_retime", LINE, function (opt, line) - line.start = line.start + opt.preTime - line.finish = line.start + opt.postTime - if line.start <= Vivy:start() then line.start = Vivy:start() end - if line.finish >= Vivy:finish() then line.finish = Vivy:finish() end - return line -end } - -module:export { "create_syllabes", SYLLABE, function (opt, syl) - local newSyls = tripleCopySyl(syl) - newSyls[1].start = syl.line.start - newSyls[1].finish = syl.start - newSyls[3].finish = syl.line.finish - newSyls[3].start = syl.finish - return newSyls -end } - --- vim: ft=lua diff --git a/utils/samples/hwlock.rs b/utils/samples/hwlock.rs new file mode 100644 index 0000000000000000000000000000000000000000..316a98cc87cd2e6aa5cf0666b2ee22b920ab32dd --- /dev/null +++ b/utils/samples/hwlock.rs @@ -0,0 +1,64 @@ +#!/usr/bin/env cargo script + +//! ```cargo +//! [package] +//! name = "topo" +//! version = "0.1.0" +//! edition = "2021" +//! +//! [dependencies] +//! hwlocality = { version = "1.0.0-alpha.1", features = ["hwloc-latest", "vendored"] } +//! anyhow = "*" +//! ``` + +use anyhow::{anyhow, Result}; +use hwlocality::{ + cpu::binding::CpuBindingFlags, + object::types::ObjectType, + topology::support::{DiscoverySupport, FeatureSupport}, + Topology, +}; +use std::os::unix::thread::JoinHandleExt; + +fn main() -> Result<()> { + let topology = Topology::new()?; + if !topology.supports(FeatureSupport::discovery, DiscoverySupport::pu_count) { + println!("This example needs accurate reporting of PU objects"); + return Ok(()); + } + let Some(cpu_support) = topology.feature_support().cpu_binding() else { + println!("This example requires CPU binding support"); + return Ok(()); + }; + if !(cpu_support.get_thread() && cpu_support.set_thread()) { + println!("This example needs support for querying and setting thread CPU bindings"); + return Ok(()); + } + + let core_depth = topology.depth_or_below_for_type(ObjectType::Core)?; + let mut handles: Vec<_> = Vec::new(); + + for (idx, core) in topology.objects_at_depth(core_depth).enumerate() { + let handle = std::thread::spawn(move || -> Result<()> { + // Worker thread + std::thread::sleep(std::time::Duration::from_secs_f64(3.0)); + Ok(()) + }); + let tid = handle.as_pthread_t(); + + let mut bind_to = core + .cpuset() + .ok_or_else(|| anyhow!("CPU cores should have CpuSets"))? + .clone_target(); + bind_to.singlify(); + + let before = topology.thread_cpu_binding(tid, CpuBindingFlags::empty())?; + topology.bind_thread_cpu(tid, &bind_to, CpuBindingFlags::empty())?; + let after = topology.thread_cpu_binding(tid, CpuBindingFlags::empty())?; + + println!("- Thread {idx} binding: {before:?} -> {after:?}"); + handles.push(handle); + } + Ok(()) +} + diff --git a/utils/scripts/build-libvivy.bash b/utils/scripts/build-libvivy.bash new file mode 100755 index 0000000000000000000000000000000000000000..f6c321c12b6af81bb217836721512bfa89248ab9 --- /dev/null +++ b/utils/scripts/build-libvivy.bash @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -e +exec 5>&1 +cd "$(git rev-parse --show-toplevel)" + +FILES=$(cargo build --manifest-path src/Rust/Cargo.toml --workspace ${2} --message-format=json \ + | jq -r 'select( .reason == "compiler-artifact" and ((.target.kind | index("staticlib")) or (.target.kind | index("bin"))) ) .filenames[0]' \ + | tee >(cat - >&5)) + +for FILE in ${FILES}; do + FILE=${FILE} + cp -u ${FILE} "${1}/$(basename ${FILE})" +done