From 2eec200f09e78917cbe74f240798ad988ac0248c Mon Sep 17 00:00:00 2001 From: Jan Van Bruggen Date: Sun, 11 Sep 2022 21:46:04 -0600 Subject: [PATCH 01/65] Move helloWorld example up onto cli-platform --- .../test_nightly_macos_apple_silicon.yml | 2 +- .github/workflows/test_nightly_many_os.yml | 2 +- ci/package_release.sh | 2 +- crates/editor/src/editor/main.rs | 2 +- examples/.gitignore | 2 + examples/hello-world/.gitignore | 1 - examples/hello-world/README.md | 16 ---- examples/hello-world/main.roc | 6 -- examples/hello-world/platform/host.c | 89 ------------------- examples/hello-world/platform/main.roc | 9 -- examples/helloWorld.roc | 6 ++ getting_started/README.md | 4 +- 12 files changed, 14 insertions(+), 127 deletions(-) delete mode 100644 examples/hello-world/.gitignore delete mode 100644 examples/hello-world/README.md delete mode 100644 examples/hello-world/main.roc delete mode 100644 examples/hello-world/platform/host.c delete mode 100644 examples/hello-world/platform/main.roc create mode 100644 examples/helloWorld.roc diff --git a/.github/workflows/test_nightly_macos_apple_silicon.yml b/.github/workflows/test_nightly_macos_apple_silicon.yml index 3f2dc315cf..10ec5dbcde 100644 --- a/.github/workflows/test_nightly_macos_apple_silicon.yml +++ b/.github/workflows/test_nightly_macos_apple_silicon.yml @@ -28,7 +28,7 @@ jobs: run: ls | grep "roc_nightly.*tar\.gz" | xargs tar -xzvf - name: test roc hello world - run: ./roc examples/hello-world/main.roc + run: ./roc examples/helloWorld.roc diff --git a/.github/workflows/test_nightly_many_os.yml b/.github/workflows/test_nightly_many_os.yml index 7ff19fcc43..f929c03c6e 100644 --- a/.github/workflows/test_nightly_many_os.yml +++ b/.github/workflows/test_nightly_many_os.yml @@ -41,7 +41,7 @@ jobs: run: ls | grep "roc_nightly.*tar\.gz" | xargs tar -xzvf - name: test roc hello world - run: ./roc examples/hello-world/main.roc + run: ./roc examples/helloWorld.roc diff --git a/ci/package_release.sh b/ci/package_release.sh index 6e17f0d150..4c03da969e 100755 --- a/ci/package_release.sh +++ b/ci/package_release.sh @@ -1,4 +1,4 @@ #!/usr/bin/env bash cp target/release/roc ./roc # to be able to exclude "target" later in the tar command cp -r target/release/lib ./lib -tar -czvf $1 --exclude="target" --exclude="zig-cache" roc lib LICENSE LEGAL_DETAILS examples/hello-world crates/roc_std +tar -czvf $1 --exclude="target" --exclude="zig-cache" roc lib LICENSE LEGAL_DETAILS examples/helloWorld.roc examples/cli crates/roc_std diff --git a/crates/editor/src/editor/main.rs b/crates/editor/src/editor/main.rs index 2478be826a..5e46664b22 100644 --- a/crates/editor/src/editor/main.rs +++ b/crates/editor/src/editor/main.rs @@ -523,7 +523,7 @@ fn read_main_roc_file(project_dir_path_opt: Option<&Path>) -> (PathBuf, String) // returns path and content of app file fn init_new_roc_project(project_dir_path: &Path) -> (PathBuf, String) { - let orig_platform_path = Path::new("./examples/hello-world").join(PLATFORM_DIR_NAME); + let orig_platform_path = Path::new("./examples/interactive").join(PLATFORM_DIR_NAME); let roc_file_path = Path::new("./new-roc-project/main.roc"); diff --git a/examples/.gitignore b/examples/.gitignore index 58cb449bb9..9fb0c881bf 100644 --- a/examples/.gitignore +++ b/examples/.gitignore @@ -4,3 +4,5 @@ libapp.so dynhost preprocessedhost metadata + +helloWorld diff --git a/examples/hello-world/.gitignore b/examples/hello-world/.gitignore deleted file mode 100644 index 7423c81faa..0000000000 --- a/examples/hello-world/.gitignore +++ /dev/null @@ -1 +0,0 @@ -helloWorld diff --git a/examples/hello-world/README.md b/examples/hello-world/README.md deleted file mode 100644 index b736613cd5..0000000000 --- a/examples/hello-world/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# Hello, World! - -To run, `cd` into this directory and run this in your terminal: - -```bash -roc run -``` - -This will run `main.roc` because, unless you explicitly give it a filename, `roc run` -defaults to running a file named `main.roc`. Other `roc` commands (like `roc build`, `roc test`, and so on) also default to `main.roc` unless you explicitly give them a filename. - -## About this example - -This uses a very simple platform which does nothing more than printing the string you give it. - -The line `main = "Hello, World!\n"` sets this string to be `"Hello, World!"` with a newline at the end, and the lines `packages { pf: "platform/main.roc" }` and `provides [main] to pf` specify that the `platform/` directory contains this app's platform. diff --git a/examples/hello-world/main.roc b/examples/hello-world/main.roc deleted file mode 100644 index 9aba749648..0000000000 --- a/examples/hello-world/main.roc +++ /dev/null @@ -1,6 +0,0 @@ -app "helloWorld" - packages { pf: "platform/main.roc" } - imports [] - provides [main] to pf - -main = "Hello, World!\n" diff --git a/examples/hello-world/platform/host.c b/examples/hello-world/platform/host.c deleted file mode 100644 index 3f9a63c2a2..0000000000 --- a/examples/hello-world/platform/host.c +++ /dev/null @@ -1,89 +0,0 @@ -#include -#include -#include -#include -#include -#include - -void* roc_alloc(size_t size, unsigned int alignment) { return malloc(size); } - -void* roc_realloc(void* ptr, size_t new_size, size_t old_size, - unsigned int alignment) { - return realloc(ptr, new_size); -} - -void roc_dealloc(void* ptr, unsigned int alignment) { free(ptr); } - -void roc_panic(void* ptr, unsigned int alignment) { - char* msg = (char*)ptr; - fprintf(stderr, - "Application crashed with message\n\n %s\n\nShutting down\n", msg); - exit(0); -} - -void* roc_memcpy(void* dest, const void* src, size_t n) { - return memcpy(dest, src, n); -} - -void* roc_memset(void* str, int c, size_t n) { return memset(str, c, n); } - -struct RocStr { - char* bytes; - size_t len; - size_t capacity; -}; - -bool is_small_str(struct RocStr str) { return ((ssize_t)str.capacity) < 0; } - -// Determine the length of the string, taking into -// account the small string optimization -size_t roc_str_len(struct RocStr str) { - char* bytes = (char*)&str; - char last_byte = bytes[sizeof(str) - 1]; - char last_byte_xored = last_byte ^ 0b10000000; - size_t small_len = (size_t)(last_byte_xored); - size_t big_len = str.len; - - // Avoid branch misprediction costs by always - // determining both small_len and big_len, - // so this compiles to a cmov instruction. - if (is_small_str(str)) { - return small_len; - } else { - return big_len; - } -} - -extern void roc__mainForHost_1_exposed_generic(struct RocStr *string); - -int main() { - - struct RocStr str; - roc__mainForHost_1_exposed_generic(&str); - - // Determine str_len and the str_bytes pointer, - // taking into account the small string optimization. - size_t str_len = roc_str_len(str); - char* str_bytes; - - if (is_small_str(str)) { - str_bytes = (char*)&str; - } else { - str_bytes = str.bytes; - } - - // Write to stdout - if (write(1, str_bytes, str_len) >= 0) { - // Writing succeeded! - - // NOTE: the string is a static string, read from in the binary - // if you make it a heap-allocated string, it'll be leaked here - return 0; - } else { - printf("Error writing to stdout: %s\n", strerror(errno)); - - // NOTE: the string is a static string, read from in the binary - // if you make it a heap-allocated string, it'll be leaked here - return 1; - } -} diff --git a/examples/hello-world/platform/main.roc b/examples/hello-world/platform/main.roc deleted file mode 100644 index 175f7070d5..0000000000 --- a/examples/hello-world/platform/main.roc +++ /dev/null @@ -1,9 +0,0 @@ -platform "hello-world" - requires {} { main : Str } - exposes [] - packages {} - imports [] - provides [mainForHost] - -mainForHost : Str -mainForHost = main diff --git a/examples/helloWorld.roc b/examples/helloWorld.roc new file mode 100644 index 0000000000..13a8ff24e7 --- /dev/null +++ b/examples/helloWorld.roc @@ -0,0 +1,6 @@ +app "helloWorld" + packages { pf: "interactive/cli-platform/main.roc" } + imports [pf.Stdout] + provides [main] to pf + +main = Stdout.line "Hello, World!" diff --git a/getting_started/README.md b/getting_started/README.md index 3392adf4fc..64992ec650 100644 --- a/getting_started/README.md +++ b/getting_started/README.md @@ -23,8 +23,8 @@ If you have a specific question, the [FAQ](../FAQ.md) might have an answer, alth You can run examples as follows: ```sh -cd examples/hello-world -roc run +cd examples +roc run helloWorld.roc ``` Some examples like `examples/benchmarks/NQueens.roc` require input after running. From 527f39b8f20b03f71a8b58860ac2853c56f01c1f Mon Sep 17 00:00:00 2001 From: Jan Van Bruggen Date: Sun, 11 Sep 2022 21:52:48 -0600 Subject: [PATCH 02/65] Move Roc CLI testing examples to `crates/` --- Cargo.toml | 5 ++-- Earthfile | 8 +++--- TUTORIAL.md | 28 +++++++++---------- ci/bench-runner/src/main.rs | 2 +- crates/cli/tests/cli_run.rs | 2 +- crates/cli/tests/known_bad/TypeError.roc | 2 +- crates/cli_testing_examples/.gitignore | 6 ++++ .../algorithms/.gitignore | 0 .../algorithms/README.md | 0 .../algorithms/fibonacci-platform/host.zig | 0 .../algorithms/fibonacci-platform/main.roc | 0 .../algorithms/fibonacci.roc | 0 .../algorithms/quicksort-platform/host.zig | 0 .../algorithms/quicksort-platform/main.roc | 0 .../algorithms/quicksort.roc | 0 .../benchmarks/.gitignore | 0 .../benchmarks/AStar.roc | 0 .../benchmarks/Base64.roc | 0 .../benchmarks/Base64/Decode.roc | 0 .../benchmarks/Base64/Encode.roc | 0 .../benchmarks/Bytes/Decode.roc | 0 .../benchmarks/Bytes/Encode.roc | 0 .../benchmarks/CFold.roc | 0 .../benchmarks/Closure.roc | 0 .../benchmarks/Deriv.roc | 0 .../benchmarks/Issue2279.roc | 0 .../benchmarks/Issue2279Help.roc | 0 .../benchmarks/NQueens.roc | 0 .../benchmarks/Quicksort.roc | 0 .../benchmarks/QuicksortApp.roc | 0 .../benchmarks/RBTreeCk.roc | 0 .../benchmarks/RBTreeDel.roc | 0 .../benchmarks/RBTreeInsert.roc | 0 .../benchmarks/TestAStar.roc | 0 .../benchmarks/TestBase64.roc | 0 .../benchmarks/platform/Effect.roc | 0 .../benchmarks/platform/Task.roc | 0 .../benchmarks/platform/host.zig | 0 .../benchmarks/platform/main.roc | 0 .../platform-switching/.gitignore | 0 .../platform-switching/README.md | 0 .../platform-switching/c-platform/host.c | 0 .../platform-switching/c-platform/main.roc | 0 .../platform-switching/main.roc | 0 .../platform-switching/rocLovesC.roc | 0 .../platform-switching/rocLovesRust.roc | 0 .../platform-switching/rocLovesSwift.roc | 0 .../rocLovesWebAssembly.roc | 0 .../platform-switching/rocLovesZig.roc | 0 .../rust-platform/Cargo.lock | 0 .../rust-platform/Cargo.toml | 0 .../platform-switching/rust-platform/build.rs | 0 .../platform-switching/rust-platform/host.c | 0 .../platform-switching/rust-platform/main.roc | 0 .../rust-platform/src/lib.rs | 0 .../rust-platform/src/main.rs | 0 .../platform-switching/swift-platform/host.h | 0 .../swift-platform/host.swift | 0 .../swift-platform/main.roc | 0 .../web-assembly-platform/README.md | 12 ++++---- .../web-assembly-platform/host.js | 0 .../web-assembly-platform/host.test.js | 0 .../web-assembly-platform/host.zig | 0 .../web-assembly-platform/index.html | 0 .../web-assembly-platform/main.roc | 0 .../platform-switching/zig-platform/host.zig | 0 .../platform-switching/zig-platform/main.roc | 0 crates/compiler/build/src/link.rs | 4 +-- examples/README.md | 4 +-- getting_started/README.md | 6 ++-- getting_started/linux_x86.md | 6 ++-- getting_started/macos_apple_silicon.md | 6 ++-- getting_started/macos_x86.md | 6 ++-- getting_started/other.md | 6 ++-- www/build.sh | 2 +- 75 files changed, 56 insertions(+), 49 deletions(-) create mode 100644 crates/cli_testing_examples/.gitignore rename {examples => crates/cli_testing_examples}/algorithms/.gitignore (100%) rename {examples => crates/cli_testing_examples}/algorithms/README.md (100%) rename {examples => crates/cli_testing_examples}/algorithms/fibonacci-platform/host.zig (100%) rename {examples => crates/cli_testing_examples}/algorithms/fibonacci-platform/main.roc (100%) rename {examples => crates/cli_testing_examples}/algorithms/fibonacci.roc (100%) rename {examples => crates/cli_testing_examples}/algorithms/quicksort-platform/host.zig (100%) rename {examples => crates/cli_testing_examples}/algorithms/quicksort-platform/main.roc (100%) rename {examples => crates/cli_testing_examples}/algorithms/quicksort.roc (100%) rename {examples => crates/cli_testing_examples}/benchmarks/.gitignore (100%) rename {examples => crates/cli_testing_examples}/benchmarks/AStar.roc (100%) rename {examples => crates/cli_testing_examples}/benchmarks/Base64.roc (100%) rename {examples => crates/cli_testing_examples}/benchmarks/Base64/Decode.roc (100%) rename {examples => crates/cli_testing_examples}/benchmarks/Base64/Encode.roc (100%) rename {examples => crates/cli_testing_examples}/benchmarks/Bytes/Decode.roc (100%) rename {examples => crates/cli_testing_examples}/benchmarks/Bytes/Encode.roc (100%) rename {examples => crates/cli_testing_examples}/benchmarks/CFold.roc (100%) rename {examples => crates/cli_testing_examples}/benchmarks/Closure.roc (100%) rename {examples => crates/cli_testing_examples}/benchmarks/Deriv.roc (100%) rename {examples => crates/cli_testing_examples}/benchmarks/Issue2279.roc (100%) rename {examples => crates/cli_testing_examples}/benchmarks/Issue2279Help.roc (100%) rename {examples => crates/cli_testing_examples}/benchmarks/NQueens.roc (100%) rename {examples => crates/cli_testing_examples}/benchmarks/Quicksort.roc (100%) rename {examples => crates/cli_testing_examples}/benchmarks/QuicksortApp.roc (100%) rename {examples => crates/cli_testing_examples}/benchmarks/RBTreeCk.roc (100%) rename {examples => crates/cli_testing_examples}/benchmarks/RBTreeDel.roc (100%) rename {examples => crates/cli_testing_examples}/benchmarks/RBTreeInsert.roc (100%) rename {examples => crates/cli_testing_examples}/benchmarks/TestAStar.roc (100%) rename {examples => crates/cli_testing_examples}/benchmarks/TestBase64.roc (100%) rename {examples => crates/cli_testing_examples}/benchmarks/platform/Effect.roc (100%) rename {examples => crates/cli_testing_examples}/benchmarks/platform/Task.roc (100%) rename {examples => crates/cli_testing_examples}/benchmarks/platform/host.zig (100%) rename {examples => crates/cli_testing_examples}/benchmarks/platform/main.roc (100%) rename {examples => crates/cli_testing_examples}/platform-switching/.gitignore (100%) rename {examples => crates/cli_testing_examples}/platform-switching/README.md (100%) rename {examples => crates/cli_testing_examples}/platform-switching/c-platform/host.c (100%) rename {examples => crates/cli_testing_examples}/platform-switching/c-platform/main.roc (100%) rename {examples => crates/cli_testing_examples}/platform-switching/main.roc (100%) rename {examples => crates/cli_testing_examples}/platform-switching/rocLovesC.roc (100%) rename {examples => crates/cli_testing_examples}/platform-switching/rocLovesRust.roc (100%) rename {examples => crates/cli_testing_examples}/platform-switching/rocLovesSwift.roc (100%) rename {examples => crates/cli_testing_examples}/platform-switching/rocLovesWebAssembly.roc (100%) rename {examples => crates/cli_testing_examples}/platform-switching/rocLovesZig.roc (100%) rename {examples => crates/cli_testing_examples}/platform-switching/rust-platform/Cargo.lock (100%) rename {examples => crates/cli_testing_examples}/platform-switching/rust-platform/Cargo.toml (100%) rename {examples => crates/cli_testing_examples}/platform-switching/rust-platform/build.rs (100%) rename {examples => crates/cli_testing_examples}/platform-switching/rust-platform/host.c (100%) rename {examples => crates/cli_testing_examples}/platform-switching/rust-platform/main.roc (100%) rename {examples => crates/cli_testing_examples}/platform-switching/rust-platform/src/lib.rs (100%) rename {examples => crates/cli_testing_examples}/platform-switching/rust-platform/src/main.rs (100%) rename {examples => crates/cli_testing_examples}/platform-switching/swift-platform/host.h (100%) rename {examples => crates/cli_testing_examples}/platform-switching/swift-platform/host.swift (100%) rename {examples => crates/cli_testing_examples}/platform-switching/swift-platform/main.roc (100%) rename {examples => crates/cli_testing_examples}/platform-switching/web-assembly-platform/README.md (77%) rename {examples => crates/cli_testing_examples}/platform-switching/web-assembly-platform/host.js (100%) rename {examples => crates/cli_testing_examples}/platform-switching/web-assembly-platform/host.test.js (100%) rename {examples => crates/cli_testing_examples}/platform-switching/web-assembly-platform/host.zig (100%) rename {examples => crates/cli_testing_examples}/platform-switching/web-assembly-platform/index.html (100%) rename {examples => crates/cli_testing_examples}/platform-switching/web-assembly-platform/main.roc (100%) rename {examples => crates/cli_testing_examples}/platform-switching/zig-platform/host.zig (100%) rename {examples => crates/cli_testing_examples}/platform-switching/zig-platform/main.roc (100%) diff --git a/Cargo.toml b/Cargo.toml index e1ce6b2323..ac055aca3e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,9 +57,10 @@ members = [ "crates/wasi-libc-sys", ] exclude = [ - # Examples sometimes have Rust hosts in their platforms. The compiler should ignore those. - "examples", "ci/bench-runner", + # Examples sometimes have Rust hosts in their platforms. The compiler should ignore those. + "crates/cli_testing_examples", + "examples", # Ignore building these normally. They are only imported by tests. # The tests will still correctly build them. "crates/cli_utils", diff --git a/Earthfile b/Earthfile index d67866328b..7c59196695 100644 --- a/Earthfile +++ b/Earthfile @@ -50,7 +50,7 @@ install-zig-llvm-valgrind: copy-dirs: FROM +install-zig-llvm-valgrind - COPY --dir crates examples Cargo.toml Cargo.lock version.txt www ./ + COPY --dir crates Cargo.toml Cargo.lock version.txt www ./ # compile everything needed for benchmarks and output a self-contained dir from which benchmarks can be run. prep-bench-folder: @@ -60,11 +60,11 @@ prep-bench-folder: ARG BENCH_SUFFIX=branch RUN cargo criterion -V RUN --mount=type=cache,target=$SCCACHE_DIR cd crates/cli && cargo criterion --no-run + RUN mkdir -p bench-folder/crates/cli_testing_examples/benchmarks RUN mkdir -p bench-folder/crates/compiler/builtins/bitcode/src RUN mkdir -p bench-folder/target/release/deps - RUN mkdir -p bench-folder/examples/benchmarks - RUN cp examples/benchmarks/*.roc bench-folder/examples/benchmarks/ - RUN cp -r examples/benchmarks/platform bench-folder/examples/benchmarks/ + RUN cp crates/cli_testing_examples/benchmarks/*.roc bench-folder/crates/cli_testing_examples/benchmarks/ + RUN cp -r crates/cli_testing_examples/benchmarks/platform bench-folder/crates/cli_testing_examples/benchmarks/ RUN cp crates/compiler/builtins/bitcode/src/str.zig bench-folder/crates/compiler/builtins/bitcode/src RUN cp target/release/roc bench-folder/target/release # copy the most recent time bench to bench-folder diff --git a/TUTORIAL.md b/TUTORIAL.md index 9376749396..ce7486c3d3 100644 --- a/TUTORIAL.md +++ b/TUTORIAL.md @@ -115,7 +115,7 @@ Create a new file called `Hello.roc` and put this inside it: ```coffee app "hello" - packages { pf: "examples/interactive/cli-platform/main.roc" } + packages { pf: "examples/cli/cli-platform/main.roc" } imports [pf.Stdout] provides [main] to pf @@ -124,8 +124,8 @@ main = Stdout.line "I'm a Roc application!" > **NOTE:** This assumes you've put Hello.roc in the root directory of the Roc > source code. If you'd like to put it somewhere else, you'll need to replace -> `"examples/interactive/cli-platform/main.roc"` with the path to the -> `examples/interactive/cli-platform/main.roc` file in that source code. In the future, +> `"examples/cli/cli-platform/main.roc"` with the path to the +> `examples/cli/cli-platform/main.roc` file in that source code. In the future, > Roc will have the tutorial built in, and this aside will no longer be > necessary! @@ -1257,7 +1257,7 @@ Let's take a closer look at the part of `Hello.roc` above `main`: ```coffee app "hello" - packages { pf: "examples/interactive/cli-platform/main.roc" } + packages { pf: "examples/cli/cli-platform/main.roc" } imports [pf.Stdout] provides main to pf ``` @@ -1275,14 +1275,14 @@ without running it by running `roc build Hello.roc`. The remaining lines all involve the *platform* this application is built on: ```coffee -packages { pf: "examples/interactive/cli-platform/main.roc" } +packages { pf: "examples/cli/cli-platform/main.roc" } imports [pf.Stdout] provides main to pf ``` -The `packages { pf: "examples/interactive/cli-platform/main.roc" }` part says two things: +The `packages { pf: "examples/cli/cli-platform/main.roc" }` part says two things: -- We're going to be using a *package* (that is, a collection of modules) called `"examples/interactive/cli-platform/main.roc"` +- We're going to be using a *package* (that is, a collection of modules) called `"examples/cli/cli-platform/main.roc"` - We're going to name that package `pf` so we can refer to it more concisely in the future. The `imports [pf.Stdout]` line says that we want to import the `Stdout` module @@ -1302,16 +1302,16 @@ calling a function named `line` which is exposed by a module named When we write `imports [pf.Stdout]`, it specifies that the `Stdout` module comes from the `pf` package. -Since `pf` was the name we chose for the `examples/interactive/cli-platform/main.roc` -package (when we wrote `packages { pf: "examples/interactive/cli-platform/main.roc" }`), +Since `pf` was the name we chose for the `examples/cli/cli-platform/main.roc` +package (when we wrote `packages { pf: "examples/cli/cli-platform/main.roc" }`), this `imports` line tells the Roc compiler that when we call `Stdout.line`, it should look for that `line` function in the `Stdout` module of the -`examples/interactive/cli-platform/main.roc` package. +`examples/cli/cli-platform/main.roc` package. ## Tasks Tasks are technically not part of the Roc language, but they're very common in -platforms. Let's use the CLI platform in `examples/interactive/cli-platform/main.roc` as an example! +platforms. Let's use the CLI platform in `examples/cli/cli-platform/main.roc` as an example! In the CLI platform, we have four operations we can do: @@ -1326,7 +1326,7 @@ First, let's do a basic "Hello World" using the tutorial app. ```coffee app "cli-tutorial" - packages { pf: "examples/interactive/cli-platform/main.roc" } + packages { pf: "examples/cli/cli-platform/main.roc" } imports [pf.Stdout] provides [main] to pf @@ -1363,7 +1363,7 @@ Let's change `main` to read a line from `stdin`, and then print it back out agai ```swift app "cli-tutorial" - packages { pf: "examples/interactive/cli-platform/main.roc" } + packages { pf: "examples/cli/cli-platform/main.roc" } imports [pf.Stdout, pf.Stdin, pf.Task] provides [main] to pf @@ -1413,7 +1413,7 @@ This works, but we can make it a little nicer to read. Let's change it to the fo ```haskell app "cli-tutorial" - packages { pf: "examples/interactive/cli-platform/main.roc" } + packages { pf: "examples/cli/cli-platform/main.roc" } imports [pf.Stdout, pf.Stdin, pf.Task.{ await }] provides [main] to pf diff --git a/ci/bench-runner/src/main.rs b/ci/bench-runner/src/main.rs index bb44247ea9..03888e34e5 100644 --- a/ci/bench-runner/src/main.rs +++ b/ci/bench-runner/src/main.rs @@ -227,7 +227,7 @@ fn calc_hashes_for_folder(benches_path_str: &str) -> HashMap { } fn check_if_bench_executables_changed() -> bool { - let bench_folder_str = "/examples/benchmarks/"; + let bench_folder_str = "/crates/cli_testing_examples/benchmarks/"; let main_benches_path_str = [BENCH_FOLDER_MAIN, bench_folder_str].join(""); let main_bench_hashes = calc_hashes_for_folder(&main_benches_path_str); diff --git a/crates/cli/tests/cli_run.rs b/crates/cli/tests/cli_run.rs index deacbfbef5..21a9017261 100644 --- a/crates/cli/tests/cli_run.rs +++ b/crates/cli/tests/cli_run.rs @@ -707,7 +707,7 @@ mod cli_run { all_benchmarks.insert(benchmark.filename, benchmark); )* - check_for_benchmarks("../../examples/benchmarks", &mut all_benchmarks); + check_for_benchmarks("../../crates/cli_testing_examples/benchmarks", &mut all_benchmarks); } } } diff --git a/crates/cli/tests/known_bad/TypeError.roc b/crates/cli/tests/known_bad/TypeError.roc index c1052dd7b3..5f8215e70b 100644 --- a/crates/cli/tests/known_bad/TypeError.roc +++ b/crates/cli/tests/known_bad/TypeError.roc @@ -1,5 +1,5 @@ app "type-error" - packages { pf: "../../../../examples/interactive/cli-platform/main.roc" } + packages { pf: "../../../../examples/cli/cli-platform/main.roc" } imports [pf.Stdout.{ line }, pf.Task.{ await }] provides [main] to pf diff --git a/crates/cli_testing_examples/.gitignore b/crates/cli_testing_examples/.gitignore new file mode 100644 index 0000000000..58cb449bb9 --- /dev/null +++ b/crates/cli_testing_examples/.gitignore @@ -0,0 +1,6 @@ +*.dSYM +libhost.a +libapp.so +dynhost +preprocessedhost +metadata diff --git a/examples/algorithms/.gitignore b/crates/cli_testing_examples/algorithms/.gitignore similarity index 100% rename from examples/algorithms/.gitignore rename to crates/cli_testing_examples/algorithms/.gitignore diff --git a/examples/algorithms/README.md b/crates/cli_testing_examples/algorithms/README.md similarity index 100% rename from examples/algorithms/README.md rename to crates/cli_testing_examples/algorithms/README.md diff --git a/examples/algorithms/fibonacci-platform/host.zig b/crates/cli_testing_examples/algorithms/fibonacci-platform/host.zig similarity index 100% rename from examples/algorithms/fibonacci-platform/host.zig rename to crates/cli_testing_examples/algorithms/fibonacci-platform/host.zig diff --git a/examples/algorithms/fibonacci-platform/main.roc b/crates/cli_testing_examples/algorithms/fibonacci-platform/main.roc similarity index 100% rename from examples/algorithms/fibonacci-platform/main.roc rename to crates/cli_testing_examples/algorithms/fibonacci-platform/main.roc diff --git a/examples/algorithms/fibonacci.roc b/crates/cli_testing_examples/algorithms/fibonacci.roc similarity index 100% rename from examples/algorithms/fibonacci.roc rename to crates/cli_testing_examples/algorithms/fibonacci.roc diff --git a/examples/algorithms/quicksort-platform/host.zig b/crates/cli_testing_examples/algorithms/quicksort-platform/host.zig similarity index 100% rename from examples/algorithms/quicksort-platform/host.zig rename to crates/cli_testing_examples/algorithms/quicksort-platform/host.zig diff --git a/examples/algorithms/quicksort-platform/main.roc b/crates/cli_testing_examples/algorithms/quicksort-platform/main.roc similarity index 100% rename from examples/algorithms/quicksort-platform/main.roc rename to crates/cli_testing_examples/algorithms/quicksort-platform/main.roc diff --git a/examples/algorithms/quicksort.roc b/crates/cli_testing_examples/algorithms/quicksort.roc similarity index 100% rename from examples/algorithms/quicksort.roc rename to crates/cli_testing_examples/algorithms/quicksort.roc diff --git a/examples/benchmarks/.gitignore b/crates/cli_testing_examples/benchmarks/.gitignore similarity index 100% rename from examples/benchmarks/.gitignore rename to crates/cli_testing_examples/benchmarks/.gitignore diff --git a/examples/benchmarks/AStar.roc b/crates/cli_testing_examples/benchmarks/AStar.roc similarity index 100% rename from examples/benchmarks/AStar.roc rename to crates/cli_testing_examples/benchmarks/AStar.roc diff --git a/examples/benchmarks/Base64.roc b/crates/cli_testing_examples/benchmarks/Base64.roc similarity index 100% rename from examples/benchmarks/Base64.roc rename to crates/cli_testing_examples/benchmarks/Base64.roc diff --git a/examples/benchmarks/Base64/Decode.roc b/crates/cli_testing_examples/benchmarks/Base64/Decode.roc similarity index 100% rename from examples/benchmarks/Base64/Decode.roc rename to crates/cli_testing_examples/benchmarks/Base64/Decode.roc diff --git a/examples/benchmarks/Base64/Encode.roc b/crates/cli_testing_examples/benchmarks/Base64/Encode.roc similarity index 100% rename from examples/benchmarks/Base64/Encode.roc rename to crates/cli_testing_examples/benchmarks/Base64/Encode.roc diff --git a/examples/benchmarks/Bytes/Decode.roc b/crates/cli_testing_examples/benchmarks/Bytes/Decode.roc similarity index 100% rename from examples/benchmarks/Bytes/Decode.roc rename to crates/cli_testing_examples/benchmarks/Bytes/Decode.roc diff --git a/examples/benchmarks/Bytes/Encode.roc b/crates/cli_testing_examples/benchmarks/Bytes/Encode.roc similarity index 100% rename from examples/benchmarks/Bytes/Encode.roc rename to crates/cli_testing_examples/benchmarks/Bytes/Encode.roc diff --git a/examples/benchmarks/CFold.roc b/crates/cli_testing_examples/benchmarks/CFold.roc similarity index 100% rename from examples/benchmarks/CFold.roc rename to crates/cli_testing_examples/benchmarks/CFold.roc diff --git a/examples/benchmarks/Closure.roc b/crates/cli_testing_examples/benchmarks/Closure.roc similarity index 100% rename from examples/benchmarks/Closure.roc rename to crates/cli_testing_examples/benchmarks/Closure.roc diff --git a/examples/benchmarks/Deriv.roc b/crates/cli_testing_examples/benchmarks/Deriv.roc similarity index 100% rename from examples/benchmarks/Deriv.roc rename to crates/cli_testing_examples/benchmarks/Deriv.roc diff --git a/examples/benchmarks/Issue2279.roc b/crates/cli_testing_examples/benchmarks/Issue2279.roc similarity index 100% rename from examples/benchmarks/Issue2279.roc rename to crates/cli_testing_examples/benchmarks/Issue2279.roc diff --git a/examples/benchmarks/Issue2279Help.roc b/crates/cli_testing_examples/benchmarks/Issue2279Help.roc similarity index 100% rename from examples/benchmarks/Issue2279Help.roc rename to crates/cli_testing_examples/benchmarks/Issue2279Help.roc diff --git a/examples/benchmarks/NQueens.roc b/crates/cli_testing_examples/benchmarks/NQueens.roc similarity index 100% rename from examples/benchmarks/NQueens.roc rename to crates/cli_testing_examples/benchmarks/NQueens.roc diff --git a/examples/benchmarks/Quicksort.roc b/crates/cli_testing_examples/benchmarks/Quicksort.roc similarity index 100% rename from examples/benchmarks/Quicksort.roc rename to crates/cli_testing_examples/benchmarks/Quicksort.roc diff --git a/examples/benchmarks/QuicksortApp.roc b/crates/cli_testing_examples/benchmarks/QuicksortApp.roc similarity index 100% rename from examples/benchmarks/QuicksortApp.roc rename to crates/cli_testing_examples/benchmarks/QuicksortApp.roc diff --git a/examples/benchmarks/RBTreeCk.roc b/crates/cli_testing_examples/benchmarks/RBTreeCk.roc similarity index 100% rename from examples/benchmarks/RBTreeCk.roc rename to crates/cli_testing_examples/benchmarks/RBTreeCk.roc diff --git a/examples/benchmarks/RBTreeDel.roc b/crates/cli_testing_examples/benchmarks/RBTreeDel.roc similarity index 100% rename from examples/benchmarks/RBTreeDel.roc rename to crates/cli_testing_examples/benchmarks/RBTreeDel.roc diff --git a/examples/benchmarks/RBTreeInsert.roc b/crates/cli_testing_examples/benchmarks/RBTreeInsert.roc similarity index 100% rename from examples/benchmarks/RBTreeInsert.roc rename to crates/cli_testing_examples/benchmarks/RBTreeInsert.roc diff --git a/examples/benchmarks/TestAStar.roc b/crates/cli_testing_examples/benchmarks/TestAStar.roc similarity index 100% rename from examples/benchmarks/TestAStar.roc rename to crates/cli_testing_examples/benchmarks/TestAStar.roc diff --git a/examples/benchmarks/TestBase64.roc b/crates/cli_testing_examples/benchmarks/TestBase64.roc similarity index 100% rename from examples/benchmarks/TestBase64.roc rename to crates/cli_testing_examples/benchmarks/TestBase64.roc diff --git a/examples/benchmarks/platform/Effect.roc b/crates/cli_testing_examples/benchmarks/platform/Effect.roc similarity index 100% rename from examples/benchmarks/platform/Effect.roc rename to crates/cli_testing_examples/benchmarks/platform/Effect.roc diff --git a/examples/benchmarks/platform/Task.roc b/crates/cli_testing_examples/benchmarks/platform/Task.roc similarity index 100% rename from examples/benchmarks/platform/Task.roc rename to crates/cli_testing_examples/benchmarks/platform/Task.roc diff --git a/examples/benchmarks/platform/host.zig b/crates/cli_testing_examples/benchmarks/platform/host.zig similarity index 100% rename from examples/benchmarks/platform/host.zig rename to crates/cli_testing_examples/benchmarks/platform/host.zig diff --git a/examples/benchmarks/platform/main.roc b/crates/cli_testing_examples/benchmarks/platform/main.roc similarity index 100% rename from examples/benchmarks/platform/main.roc rename to crates/cli_testing_examples/benchmarks/platform/main.roc diff --git a/examples/platform-switching/.gitignore b/crates/cli_testing_examples/platform-switching/.gitignore similarity index 100% rename from examples/platform-switching/.gitignore rename to crates/cli_testing_examples/platform-switching/.gitignore diff --git a/examples/platform-switching/README.md b/crates/cli_testing_examples/platform-switching/README.md similarity index 100% rename from examples/platform-switching/README.md rename to crates/cli_testing_examples/platform-switching/README.md diff --git a/examples/platform-switching/c-platform/host.c b/crates/cli_testing_examples/platform-switching/c-platform/host.c similarity index 100% rename from examples/platform-switching/c-platform/host.c rename to crates/cli_testing_examples/platform-switching/c-platform/host.c diff --git a/examples/platform-switching/c-platform/main.roc b/crates/cli_testing_examples/platform-switching/c-platform/main.roc similarity index 100% rename from examples/platform-switching/c-platform/main.roc rename to crates/cli_testing_examples/platform-switching/c-platform/main.roc diff --git a/examples/platform-switching/main.roc b/crates/cli_testing_examples/platform-switching/main.roc similarity index 100% rename from examples/platform-switching/main.roc rename to crates/cli_testing_examples/platform-switching/main.roc diff --git a/examples/platform-switching/rocLovesC.roc b/crates/cli_testing_examples/platform-switching/rocLovesC.roc similarity index 100% rename from examples/platform-switching/rocLovesC.roc rename to crates/cli_testing_examples/platform-switching/rocLovesC.roc diff --git a/examples/platform-switching/rocLovesRust.roc b/crates/cli_testing_examples/platform-switching/rocLovesRust.roc similarity index 100% rename from examples/platform-switching/rocLovesRust.roc rename to crates/cli_testing_examples/platform-switching/rocLovesRust.roc diff --git a/examples/platform-switching/rocLovesSwift.roc b/crates/cli_testing_examples/platform-switching/rocLovesSwift.roc similarity index 100% rename from examples/platform-switching/rocLovesSwift.roc rename to crates/cli_testing_examples/platform-switching/rocLovesSwift.roc diff --git a/examples/platform-switching/rocLovesWebAssembly.roc b/crates/cli_testing_examples/platform-switching/rocLovesWebAssembly.roc similarity index 100% rename from examples/platform-switching/rocLovesWebAssembly.roc rename to crates/cli_testing_examples/platform-switching/rocLovesWebAssembly.roc diff --git a/examples/platform-switching/rocLovesZig.roc b/crates/cli_testing_examples/platform-switching/rocLovesZig.roc similarity index 100% rename from examples/platform-switching/rocLovesZig.roc rename to crates/cli_testing_examples/platform-switching/rocLovesZig.roc diff --git a/examples/platform-switching/rust-platform/Cargo.lock b/crates/cli_testing_examples/platform-switching/rust-platform/Cargo.lock similarity index 100% rename from examples/platform-switching/rust-platform/Cargo.lock rename to crates/cli_testing_examples/platform-switching/rust-platform/Cargo.lock diff --git a/examples/platform-switching/rust-platform/Cargo.toml b/crates/cli_testing_examples/platform-switching/rust-platform/Cargo.toml similarity index 100% rename from examples/platform-switching/rust-platform/Cargo.toml rename to crates/cli_testing_examples/platform-switching/rust-platform/Cargo.toml diff --git a/examples/platform-switching/rust-platform/build.rs b/crates/cli_testing_examples/platform-switching/rust-platform/build.rs similarity index 100% rename from examples/platform-switching/rust-platform/build.rs rename to crates/cli_testing_examples/platform-switching/rust-platform/build.rs diff --git a/examples/platform-switching/rust-platform/host.c b/crates/cli_testing_examples/platform-switching/rust-platform/host.c similarity index 100% rename from examples/platform-switching/rust-platform/host.c rename to crates/cli_testing_examples/platform-switching/rust-platform/host.c diff --git a/examples/platform-switching/rust-platform/main.roc b/crates/cli_testing_examples/platform-switching/rust-platform/main.roc similarity index 100% rename from examples/platform-switching/rust-platform/main.roc rename to crates/cli_testing_examples/platform-switching/rust-platform/main.roc diff --git a/examples/platform-switching/rust-platform/src/lib.rs b/crates/cli_testing_examples/platform-switching/rust-platform/src/lib.rs similarity index 100% rename from examples/platform-switching/rust-platform/src/lib.rs rename to crates/cli_testing_examples/platform-switching/rust-platform/src/lib.rs diff --git a/examples/platform-switching/rust-platform/src/main.rs b/crates/cli_testing_examples/platform-switching/rust-platform/src/main.rs similarity index 100% rename from examples/platform-switching/rust-platform/src/main.rs rename to crates/cli_testing_examples/platform-switching/rust-platform/src/main.rs diff --git a/examples/platform-switching/swift-platform/host.h b/crates/cli_testing_examples/platform-switching/swift-platform/host.h similarity index 100% rename from examples/platform-switching/swift-platform/host.h rename to crates/cli_testing_examples/platform-switching/swift-platform/host.h diff --git a/examples/platform-switching/swift-platform/host.swift b/crates/cli_testing_examples/platform-switching/swift-platform/host.swift similarity index 100% rename from examples/platform-switching/swift-platform/host.swift rename to crates/cli_testing_examples/platform-switching/swift-platform/host.swift diff --git a/examples/platform-switching/swift-platform/main.roc b/crates/cli_testing_examples/platform-switching/swift-platform/main.roc similarity index 100% rename from examples/platform-switching/swift-platform/main.roc rename to crates/cli_testing_examples/platform-switching/swift-platform/main.roc diff --git a/examples/platform-switching/web-assembly-platform/README.md b/crates/cli_testing_examples/platform-switching/web-assembly-platform/README.md similarity index 77% rename from examples/platform-switching/web-assembly-platform/README.md rename to crates/cli_testing_examples/platform-switching/web-assembly-platform/README.md index 76f5720e29..a1dba338dc 100644 --- a/examples/platform-switching/web-assembly-platform/README.md +++ b/crates/cli_testing_examples/platform-switching/web-assembly-platform/README.md @@ -3,12 +3,12 @@ To run this website, first compile either of these identical apps: ```bash -# Option A: Compile examples/platform-switching/rocLovesWebAssembly.roc -cargo run -- build --target=wasm32 examples/platform-switching/rocLovesWebAssembly.roc +# Option A: Compile crates/cli_testing_examples/platform-switching/rocLovesWebAssembly.roc +cargo run -- build --target=wasm32 crates/cli_testing_examples/platform-switching/rocLovesWebAssembly.roc -# Option B: Compile examples/platform-switching/main.roc with `pf: "web-assembly-platform/main.roc"` and move the result -cargo run -- build --target=wasm32 examples/platform-switching/main.roc -(cd examples/platform-switching && mv rocLovesPlatforms.wasm web-assembly-platform/rocLovesWebAssembly.wasm) +# Option B: Compile crates/cli_testing_examples/platform-switching/main.roc with `pf: "web-assembly-platform/main.roc"` and move the result +cargo run -- build --target=wasm32 crates/cli_testing_examples/platform-switching/main.roc +(cd crates/cli_testing_examples/platform-switching && mv rocLovesPlatforms.wasm web-assembly-platform/rocLovesWebAssembly.wasm) ``` Then `cd` into the website directory @@ -16,7 +16,7 @@ and run any web server that can handle WebAssembly. For example, with `http-server`: ```bash -cd examples/platform-switching/web-assembly-platform +cd crates/cli_testing_examples/platform-switching/web-assembly-platform npm install -g http-server http-server ``` diff --git a/examples/platform-switching/web-assembly-platform/host.js b/crates/cli_testing_examples/platform-switching/web-assembly-platform/host.js similarity index 100% rename from examples/platform-switching/web-assembly-platform/host.js rename to crates/cli_testing_examples/platform-switching/web-assembly-platform/host.js diff --git a/examples/platform-switching/web-assembly-platform/host.test.js b/crates/cli_testing_examples/platform-switching/web-assembly-platform/host.test.js similarity index 100% rename from examples/platform-switching/web-assembly-platform/host.test.js rename to crates/cli_testing_examples/platform-switching/web-assembly-platform/host.test.js diff --git a/examples/platform-switching/web-assembly-platform/host.zig b/crates/cli_testing_examples/platform-switching/web-assembly-platform/host.zig similarity index 100% rename from examples/platform-switching/web-assembly-platform/host.zig rename to crates/cli_testing_examples/platform-switching/web-assembly-platform/host.zig diff --git a/examples/platform-switching/web-assembly-platform/index.html b/crates/cli_testing_examples/platform-switching/web-assembly-platform/index.html similarity index 100% rename from examples/platform-switching/web-assembly-platform/index.html rename to crates/cli_testing_examples/platform-switching/web-assembly-platform/index.html diff --git a/examples/platform-switching/web-assembly-platform/main.roc b/crates/cli_testing_examples/platform-switching/web-assembly-platform/main.roc similarity index 100% rename from examples/platform-switching/web-assembly-platform/main.roc rename to crates/cli_testing_examples/platform-switching/web-assembly-platform/main.roc diff --git a/examples/platform-switching/zig-platform/host.zig b/crates/cli_testing_examples/platform-switching/zig-platform/host.zig similarity index 100% rename from examples/platform-switching/zig-platform/host.zig rename to crates/cli_testing_examples/platform-switching/zig-platform/host.zig diff --git a/examples/platform-switching/zig-platform/main.roc b/crates/cli_testing_examples/platform-switching/zig-platform/main.roc similarity index 100% rename from examples/platform-switching/zig-platform/main.roc rename to crates/cli_testing_examples/platform-switching/zig-platform/main.roc diff --git a/crates/compiler/build/src/link.rs b/crates/compiler/build/src/link.rs index 29bfbcf15a..ea89b43e2c 100644 --- a/crates/compiler/build/src/link.rs +++ b/crates/compiler/build/src/link.rs @@ -373,7 +373,7 @@ pub fn build_zig_host_wasm32( "c", "-target", zig_target, - // "-femit-llvm-ir=/home/folkertdev/roc/roc/examples/benchmarks/platform/host.ll", + // "-femit-llvm-ir=/home/folkertdev/roc/roc/crates/cli_testing_examples/benchmarks/platform/host.ll", "-fPIC", "--strip", ]; @@ -1176,7 +1176,7 @@ fn link_wasm32( "-O", "ReleaseSmall", // useful for debugging - // "-femit-llvm-ir=/home/folkertdev/roc/roc/examples/benchmarks/platform/host.ll", + // "-femit-llvm-ir=/home/folkertdev/roc/roc/crates/cli_testing_examples/benchmarks/platform/host.ll", ]) .spawn()?; diff --git a/examples/README.md b/examples/README.md index 7097cb5397..0358683fdc 100644 --- a/examples/README.md +++ b/examples/README.md @@ -14,7 +14,7 @@ Run examples as follows: roc run hello-world/main.roc ``` -`examples/benchmarks/` contains some larger examples. +`crates/cli_testing_examples/benchmarks/` contains some larger examples. -Some examples like `examples/benchmarks/NQueens.roc` require input after running. +Some examples like `crates/cli_testing_examples/benchmarks/NQueens.roc` require input after running. For NQueens, input 10 in the terminal and press enter. diff --git a/getting_started/README.md b/getting_started/README.md index 64992ec650..ef574d9776 100644 --- a/getting_started/README.md +++ b/getting_started/README.md @@ -6,7 +6,7 @@ play around with as long as you have a high tolerance for missing features and c The [tutorial](../TUTORIAL.md) is the best place to learn about how to use the language - it assumes no prior knowledge of Roc or similar languages. (If you already know [Elm](https://elm-lang.org/), then [Roc for Elm Programmers](https://github.com/roc-lang/roc/blob/main/roc-for-elm-programmers.md) may be of interest.) -There's also a folder of [examples](https://github.com/roc-lang/roc/tree/main/examples) - the [CLI form example](https://github.com/roc-lang/roc/tree/main/examples/interactive/form.roc) in particular is a reasonable starting point to build on. +There's also a folder of [examples](https://github.com/roc-lang/roc/tree/main/examples) - the [CLI form example](https://github.com/roc-lang/roc/tree/main/examples/cli/form.roc) in particular is a reasonable starting point to build on. If you have a specific question, the [FAQ](../FAQ.md) might have an answer, although [Roc Zulip chat](https://roc.zulipchat.com) is overall the best place to ask questions and get help! It's also where we discuss [ideas](https://roc.zulipchat.com/#narrow/stream/304641-ideas) for the language. If you want to get involved in contributing to the language, Zulip is also a great place to ask about good first projects. @@ -27,10 +27,10 @@ cd examples roc run helloWorld.roc ``` -Some examples like `examples/benchmarks/NQueens.roc` require input after running. +Some examples like `crates/cli_testing_examples/benchmarks/NQueens.roc` require input after running. For NQueens, input 10 in the terminal and press enter. -[examples/benchmarks](examples/benchmarks) contains larger examples. +[crates/cli_testing_examples/benchmarks](crates/cli_testing_examples/benchmarks) contains larger examples. **Tip:** when programming in roc, we recommend to execute `./roc check myproject/Foo.roc` before `./roc myproject/Foo.roc` or `./roc build myproject/Foo.roc`. `./roc check` can produce clear error messages in cases where building/running may panic. diff --git a/getting_started/linux_x86.md b/getting_started/linux_x86.md index d0f4dff8b2..e3ac639c6f 100644 --- a/getting_started/linux_x86.md +++ b/getting_started/linux_x86.md @@ -44,9 +44,9 @@ you need to install one or more of these platform language compilers, too. ```sh # Note: If you installed Rust in this terminal session, you'll need to open a new one first! - ./roc examples/platform-switching/rocLovesRust.roc + ./roc crates/cli_testing_examples/platform-switching/rocLovesRust.roc - ./roc examples/platform-switching/rocLovesZig.roc + ./roc crates/cli_testing_examples/platform-switching/rocLovesZig.roc - ./roc examples/platform-switching/rocLovesC.roc + ./roc crates/cli_testing_examples/platform-switching/rocLovesC.roc ``` diff --git a/getting_started/macos_apple_silicon.md b/getting_started/macos_apple_silicon.md index 3036c5bcde..386eff24f7 100644 --- a/getting_started/macos_apple_silicon.md +++ b/getting_started/macos_apple_silicon.md @@ -40,9 +40,9 @@ you need to install one or more of these platform language compilers, too. ```sh # Note: If you installed rust in this terminal session, you'll need to open a new one first! - ./roc examples/platform-switching/rocLovesRust.roc + ./roc crates/cli_testing_examples/platform-switching/rocLovesRust.roc - ./roc examples/platform-switching/rocLovesZig.roc + ./roc crates/cli_testing_examples/platform-switching/rocLovesZig.roc - ./roc examples/platform-switching/rocLovesC.roc + ./roc crates/cli_testing_examples/platform-switching/rocLovesC.roc ``` diff --git a/getting_started/macos_x86.md b/getting_started/macos_x86.md index df507c5d36..c5b20e6c5b 100644 --- a/getting_started/macos_x86.md +++ b/getting_started/macos_x86.md @@ -40,9 +40,9 @@ you need to install one or more of these platform language compilers, too. ```sh # Note: If you installed rust in this terminal session, you'll need to open a new one first! - ./roc examples/platform-switching/rocLovesRust.roc + ./roc crates/cli_testing_examples/platform-switching/rocLovesRust.roc - ./roc examples/platform-switching/rocLovesZig.roc + ./roc crates/cli_testing_examples/platform-switching/rocLovesZig.roc - ./roc examples/platform-switching/rocLovesC.roc + ./roc crates/cli_testing_examples/platform-switching/rocLovesC.roc ``` diff --git a/getting_started/other.md b/getting_started/other.md index 70f01dd2e5..13c5c79db7 100644 --- a/getting_started/other.md +++ b/getting_started/other.md @@ -7,11 +7,11 @@ 1. Run examples: ```sh - cargo run examples/platform-switching/rocLovesRust.roc + cargo run crates/cli_testing_examples/platform-switching/rocLovesRust.roc # This requires installing the Zig compiler, too. - cargo run examples/platform-switching/rocLovesZig.roc + cargo run crates/cli_testing_examples/platform-switching/rocLovesZig.roc # This requires installing the `clang` C compiler, too. - cargo run examples/platform-switching/rocLovesC.roc + cargo run crates/cli_testing_examples/platform-switching/rocLovesC.roc ``` diff --git a/www/build.sh b/www/build.sh index b292377034..6797db6467 100755 --- a/www/build.sh +++ b/www/build.sh @@ -45,7 +45,7 @@ export ROC_DOCS_URL_ROOT=/examples/cli # Until https://github.com/roc-lang/roc/issues/3280 is done, # manually exclude the Internal* modules and `main.roc`. -ls examples/interactive/cli-platform/*.roc | grep -v Internal | grep -v main.roc | grep -v Effect.roc | xargs cargo run --bin roc-docs +ls examples/cli/cli-platform/*.roc | grep -v Internal | grep -v main.roc | grep -v Effect.roc | xargs cargo run --bin roc-docs mkdir www/build/examples rm generated-docs/*.* # we already copied over the *.js and *.css files earlier, so just drop these. From d0f5599bd707b71898a141ed260268818d05bb31 Mon Sep 17 00:00:00 2001 From: Jan Van Bruggen Date: Sun, 11 Sep 2022 21:56:23 -0600 Subject: [PATCH 03/65] Categorize breakout game as a GUI --- examples/{ => gui}/breakout/.gitignore | 0 examples/{ => gui}/breakout/breakout.roc | 0 examples/{ => gui}/breakout/hello.roc | 0 examples/{ => gui}/breakout/platform/.gitignore | 0 examples/{ => gui}/breakout/platform/Action.roc | 0 examples/{ => gui}/breakout/platform/Cargo.lock | 0 examples/{ => gui}/breakout/platform/Cargo.toml | 0 examples/{ => gui}/breakout/platform/Elem.roc | 0 examples/{ => gui}/breakout/platform/Game.roc | 0 examples/{ => gui}/breakout/platform/build.rs | 0 examples/{ => gui}/breakout/platform/host.c | 0 examples/{ => gui}/breakout/platform/main.roc | 0 examples/{ => gui}/breakout/platform/src/graphics/colors.rs | 0 .../{ => gui}/breakout/platform/src/graphics/lowlevel/buffer.rs | 0 examples/{ => gui}/breakout/platform/src/graphics/lowlevel/mod.rs | 0 .../{ => gui}/breakout/platform/src/graphics/lowlevel/ortho.rs | 0 .../breakout/platform/src/graphics/lowlevel/pipelines.rs | 0 .../{ => gui}/breakout/platform/src/graphics/lowlevel/quad.rs | 0 .../{ => gui}/breakout/platform/src/graphics/lowlevel/vertex.rs | 0 examples/{ => gui}/breakout/platform/src/graphics/mod.rs | 0 .../{ => gui}/breakout/platform/src/graphics/primitives/mod.rs | 0 .../{ => gui}/breakout/platform/src/graphics/primitives/rect.rs | 0 .../{ => gui}/breakout/platform/src/graphics/primitives/text.rs | 0 .../{ => gui}/breakout/platform/src/graphics/shaders/quad.wgsl | 0 examples/{ => gui}/breakout/platform/src/graphics/style.rs | 0 examples/{ => gui}/breakout/platform/src/gui.rs | 0 examples/{ => gui}/breakout/platform/src/lib.rs | 0 examples/{ => gui}/breakout/platform/src/main.rs | 0 examples/{ => gui}/breakout/platform/src/roc.rs | 0 29 files changed, 0 insertions(+), 0 deletions(-) rename examples/{ => gui}/breakout/.gitignore (100%) rename examples/{ => gui}/breakout/breakout.roc (100%) rename examples/{ => gui}/breakout/hello.roc (100%) rename examples/{ => gui}/breakout/platform/.gitignore (100%) rename examples/{ => gui}/breakout/platform/Action.roc (100%) rename examples/{ => gui}/breakout/platform/Cargo.lock (100%) rename examples/{ => gui}/breakout/platform/Cargo.toml (100%) rename examples/{ => gui}/breakout/platform/Elem.roc (100%) rename examples/{ => gui}/breakout/platform/Game.roc (100%) rename examples/{ => gui}/breakout/platform/build.rs (100%) rename examples/{ => gui}/breakout/platform/host.c (100%) rename examples/{ => gui}/breakout/platform/main.roc (100%) rename examples/{ => gui}/breakout/platform/src/graphics/colors.rs (100%) rename examples/{ => gui}/breakout/platform/src/graphics/lowlevel/buffer.rs (100%) rename examples/{ => gui}/breakout/platform/src/graphics/lowlevel/mod.rs (100%) rename examples/{ => gui}/breakout/platform/src/graphics/lowlevel/ortho.rs (100%) rename examples/{ => gui}/breakout/platform/src/graphics/lowlevel/pipelines.rs (100%) rename examples/{ => gui}/breakout/platform/src/graphics/lowlevel/quad.rs (100%) rename examples/{ => gui}/breakout/platform/src/graphics/lowlevel/vertex.rs (100%) rename examples/{ => gui}/breakout/platform/src/graphics/mod.rs (100%) rename examples/{ => gui}/breakout/platform/src/graphics/primitives/mod.rs (100%) rename examples/{ => gui}/breakout/platform/src/graphics/primitives/rect.rs (100%) rename examples/{ => gui}/breakout/platform/src/graphics/primitives/text.rs (100%) rename examples/{ => gui}/breakout/platform/src/graphics/shaders/quad.wgsl (100%) rename examples/{ => gui}/breakout/platform/src/graphics/style.rs (100%) rename examples/{ => gui}/breakout/platform/src/gui.rs (100%) rename examples/{ => gui}/breakout/platform/src/lib.rs (100%) rename examples/{ => gui}/breakout/platform/src/main.rs (100%) rename examples/{ => gui}/breakout/platform/src/roc.rs (100%) diff --git a/examples/breakout/.gitignore b/examples/gui/breakout/.gitignore similarity index 100% rename from examples/breakout/.gitignore rename to examples/gui/breakout/.gitignore diff --git a/examples/breakout/breakout.roc b/examples/gui/breakout/breakout.roc similarity index 100% rename from examples/breakout/breakout.roc rename to examples/gui/breakout/breakout.roc diff --git a/examples/breakout/hello.roc b/examples/gui/breakout/hello.roc similarity index 100% rename from examples/breakout/hello.roc rename to examples/gui/breakout/hello.roc diff --git a/examples/breakout/platform/.gitignore b/examples/gui/breakout/platform/.gitignore similarity index 100% rename from examples/breakout/platform/.gitignore rename to examples/gui/breakout/platform/.gitignore diff --git a/examples/breakout/platform/Action.roc b/examples/gui/breakout/platform/Action.roc similarity index 100% rename from examples/breakout/platform/Action.roc rename to examples/gui/breakout/platform/Action.roc diff --git a/examples/breakout/platform/Cargo.lock b/examples/gui/breakout/platform/Cargo.lock similarity index 100% rename from examples/breakout/platform/Cargo.lock rename to examples/gui/breakout/platform/Cargo.lock diff --git a/examples/breakout/platform/Cargo.toml b/examples/gui/breakout/platform/Cargo.toml similarity index 100% rename from examples/breakout/platform/Cargo.toml rename to examples/gui/breakout/platform/Cargo.toml diff --git a/examples/breakout/platform/Elem.roc b/examples/gui/breakout/platform/Elem.roc similarity index 100% rename from examples/breakout/platform/Elem.roc rename to examples/gui/breakout/platform/Elem.roc diff --git a/examples/breakout/platform/Game.roc b/examples/gui/breakout/platform/Game.roc similarity index 100% rename from examples/breakout/platform/Game.roc rename to examples/gui/breakout/platform/Game.roc diff --git a/examples/breakout/platform/build.rs b/examples/gui/breakout/platform/build.rs similarity index 100% rename from examples/breakout/platform/build.rs rename to examples/gui/breakout/platform/build.rs diff --git a/examples/breakout/platform/host.c b/examples/gui/breakout/platform/host.c similarity index 100% rename from examples/breakout/platform/host.c rename to examples/gui/breakout/platform/host.c diff --git a/examples/breakout/platform/main.roc b/examples/gui/breakout/platform/main.roc similarity index 100% rename from examples/breakout/platform/main.roc rename to examples/gui/breakout/platform/main.roc diff --git a/examples/breakout/platform/src/graphics/colors.rs b/examples/gui/breakout/platform/src/graphics/colors.rs similarity index 100% rename from examples/breakout/platform/src/graphics/colors.rs rename to examples/gui/breakout/platform/src/graphics/colors.rs diff --git a/examples/breakout/platform/src/graphics/lowlevel/buffer.rs b/examples/gui/breakout/platform/src/graphics/lowlevel/buffer.rs similarity index 100% rename from examples/breakout/platform/src/graphics/lowlevel/buffer.rs rename to examples/gui/breakout/platform/src/graphics/lowlevel/buffer.rs diff --git a/examples/breakout/platform/src/graphics/lowlevel/mod.rs b/examples/gui/breakout/platform/src/graphics/lowlevel/mod.rs similarity index 100% rename from examples/breakout/platform/src/graphics/lowlevel/mod.rs rename to examples/gui/breakout/platform/src/graphics/lowlevel/mod.rs diff --git a/examples/breakout/platform/src/graphics/lowlevel/ortho.rs b/examples/gui/breakout/platform/src/graphics/lowlevel/ortho.rs similarity index 100% rename from examples/breakout/platform/src/graphics/lowlevel/ortho.rs rename to examples/gui/breakout/platform/src/graphics/lowlevel/ortho.rs diff --git a/examples/breakout/platform/src/graphics/lowlevel/pipelines.rs b/examples/gui/breakout/platform/src/graphics/lowlevel/pipelines.rs similarity index 100% rename from examples/breakout/platform/src/graphics/lowlevel/pipelines.rs rename to examples/gui/breakout/platform/src/graphics/lowlevel/pipelines.rs diff --git a/examples/breakout/platform/src/graphics/lowlevel/quad.rs b/examples/gui/breakout/platform/src/graphics/lowlevel/quad.rs similarity index 100% rename from examples/breakout/platform/src/graphics/lowlevel/quad.rs rename to examples/gui/breakout/platform/src/graphics/lowlevel/quad.rs diff --git a/examples/breakout/platform/src/graphics/lowlevel/vertex.rs b/examples/gui/breakout/platform/src/graphics/lowlevel/vertex.rs similarity index 100% rename from examples/breakout/platform/src/graphics/lowlevel/vertex.rs rename to examples/gui/breakout/platform/src/graphics/lowlevel/vertex.rs diff --git a/examples/breakout/platform/src/graphics/mod.rs b/examples/gui/breakout/platform/src/graphics/mod.rs similarity index 100% rename from examples/breakout/platform/src/graphics/mod.rs rename to examples/gui/breakout/platform/src/graphics/mod.rs diff --git a/examples/breakout/platform/src/graphics/primitives/mod.rs b/examples/gui/breakout/platform/src/graphics/primitives/mod.rs similarity index 100% rename from examples/breakout/platform/src/graphics/primitives/mod.rs rename to examples/gui/breakout/platform/src/graphics/primitives/mod.rs diff --git a/examples/breakout/platform/src/graphics/primitives/rect.rs b/examples/gui/breakout/platform/src/graphics/primitives/rect.rs similarity index 100% rename from examples/breakout/platform/src/graphics/primitives/rect.rs rename to examples/gui/breakout/platform/src/graphics/primitives/rect.rs diff --git a/examples/breakout/platform/src/graphics/primitives/text.rs b/examples/gui/breakout/platform/src/graphics/primitives/text.rs similarity index 100% rename from examples/breakout/platform/src/graphics/primitives/text.rs rename to examples/gui/breakout/platform/src/graphics/primitives/text.rs diff --git a/examples/breakout/platform/src/graphics/shaders/quad.wgsl b/examples/gui/breakout/platform/src/graphics/shaders/quad.wgsl similarity index 100% rename from examples/breakout/platform/src/graphics/shaders/quad.wgsl rename to examples/gui/breakout/platform/src/graphics/shaders/quad.wgsl diff --git a/examples/breakout/platform/src/graphics/style.rs b/examples/gui/breakout/platform/src/graphics/style.rs similarity index 100% rename from examples/breakout/platform/src/graphics/style.rs rename to examples/gui/breakout/platform/src/graphics/style.rs diff --git a/examples/breakout/platform/src/gui.rs b/examples/gui/breakout/platform/src/gui.rs similarity index 100% rename from examples/breakout/platform/src/gui.rs rename to examples/gui/breakout/platform/src/gui.rs diff --git a/examples/breakout/platform/src/lib.rs b/examples/gui/breakout/platform/src/lib.rs similarity index 100% rename from examples/breakout/platform/src/lib.rs rename to examples/gui/breakout/platform/src/lib.rs diff --git a/examples/breakout/platform/src/main.rs b/examples/gui/breakout/platform/src/main.rs similarity index 100% rename from examples/breakout/platform/src/main.rs rename to examples/gui/breakout/platform/src/main.rs diff --git a/examples/breakout/platform/src/roc.rs b/examples/gui/breakout/platform/src/roc.rs similarity index 100% rename from examples/breakout/platform/src/roc.rs rename to examples/gui/breakout/platform/src/roc.rs From a9a65fcf4b202b667f57e41de610a5629b7a719b Mon Sep 17 00:00:00 2001 From: Jan Van Bruggen Date: Sun, 11 Sep 2022 21:57:18 -0600 Subject: [PATCH 04/65] Recategorize interactive apps as CLIs --- crates/cli/tests/cli_run.rs | 6 +++--- crates/editor/src/editor/main.rs | 2 +- crates/highlight/tests/peg_grammar.rs | 2 +- examples/{interactive => cli}/.gitignore | 0 examples/{interactive => cli}/README.md | 2 +- examples/{interactive => cli}/cli-platform/Cargo.lock | 0 examples/{interactive => cli}/cli-platform/Cargo.toml | 0 examples/{interactive => cli}/cli-platform/Effect.roc | 0 examples/{interactive => cli}/cli-platform/File.roc | 0 examples/{interactive => cli}/cli-platform/Http.roc | 0 examples/{interactive => cli}/cli-platform/InternalFile.roc | 0 examples/{interactive => cli}/cli-platform/InternalHttp.roc | 0 examples/{interactive => cli}/cli-platform/InternalPath.roc | 0 examples/{interactive => cli}/cli-platform/InternalTask.roc | 0 examples/{interactive => cli}/cli-platform/Path.roc | 0 examples/{interactive => cli}/cli-platform/Stderr.roc | 0 examples/{interactive => cli}/cli-platform/Stdin.roc | 0 examples/{interactive => cli}/cli-platform/Stdout.roc | 0 examples/{interactive => cli}/cli-platform/Task.roc | 0 examples/{interactive => cli}/cli-platform/Url.roc | 0 examples/{interactive => cli}/cli-platform/build.rs | 0 examples/{interactive => cli}/cli-platform/host.c | 0 examples/{interactive => cli}/cli-platform/main.roc | 0 examples/{interactive => cli}/cli-platform/src/file_glue.rs | 0 examples/{interactive => cli}/cli-platform/src/glue.rs | 0 examples/{interactive => cli}/cli-platform/src/lib.rs | 0 examples/{interactive => cli}/cli-platform/src/main.rs | 0 examples/{interactive => cli}/countdown.roc | 0 examples/{interactive => cli}/echo.roc | 0 examples/{interactive => cli}/effects-platform/Effect.roc | 0 examples/{interactive => cli}/effects-platform/host.zig | 0 examples/{interactive => cli}/effects-platform/main.roc | 0 examples/{interactive => cli}/effects.roc | 0 examples/{interactive => cli}/file.roc | 0 examples/{interactive => cli}/form.roc | 0 examples/{interactive => cli}/http-get.roc | 0 examples/{interactive => cli}/tui-platform/Program.roc | 0 examples/{interactive => cli}/tui-platform/host.zig | 0 examples/{interactive => cli}/tui-platform/main.roc | 0 examples/{interactive => cli}/tui.roc | 0 examples/helloWorld.roc | 2 +- 41 files changed, 7 insertions(+), 7 deletions(-) rename examples/{interactive => cli}/.gitignore (100%) rename examples/{interactive => cli}/README.md (96%) rename examples/{interactive => cli}/cli-platform/Cargo.lock (100%) rename examples/{interactive => cli}/cli-platform/Cargo.toml (100%) rename examples/{interactive => cli}/cli-platform/Effect.roc (100%) rename examples/{interactive => cli}/cli-platform/File.roc (100%) rename examples/{interactive => cli}/cli-platform/Http.roc (100%) rename examples/{interactive => cli}/cli-platform/InternalFile.roc (100%) rename examples/{interactive => cli}/cli-platform/InternalHttp.roc (100%) rename examples/{interactive => cli}/cli-platform/InternalPath.roc (100%) rename examples/{interactive => cli}/cli-platform/InternalTask.roc (100%) rename examples/{interactive => cli}/cli-platform/Path.roc (100%) rename examples/{interactive => cli}/cli-platform/Stderr.roc (100%) rename examples/{interactive => cli}/cli-platform/Stdin.roc (100%) rename examples/{interactive => cli}/cli-platform/Stdout.roc (100%) rename examples/{interactive => cli}/cli-platform/Task.roc (100%) rename examples/{interactive => cli}/cli-platform/Url.roc (100%) rename examples/{interactive => cli}/cli-platform/build.rs (100%) rename examples/{interactive => cli}/cli-platform/host.c (100%) rename examples/{interactive => cli}/cli-platform/main.roc (100%) rename examples/{interactive => cli}/cli-platform/src/file_glue.rs (100%) rename examples/{interactive => cli}/cli-platform/src/glue.rs (100%) rename examples/{interactive => cli}/cli-platform/src/lib.rs (100%) rename examples/{interactive => cli}/cli-platform/src/main.rs (100%) rename examples/{interactive => cli}/countdown.roc (100%) rename examples/{interactive => cli}/echo.roc (100%) rename examples/{interactive => cli}/effects-platform/Effect.roc (100%) rename examples/{interactive => cli}/effects-platform/host.zig (100%) rename examples/{interactive => cli}/effects-platform/main.roc (100%) rename examples/{interactive => cli}/effects.roc (100%) rename examples/{interactive => cli}/file.roc (100%) rename examples/{interactive => cli}/form.roc (100%) rename examples/{interactive => cli}/http-get.roc (100%) rename examples/{interactive => cli}/tui-platform/Program.roc (100%) rename examples/{interactive => cli}/tui-platform/host.zig (100%) rename examples/{interactive => cli}/tui-platform/main.roc (100%) rename examples/{interactive => cli}/tui.roc (100%) diff --git a/crates/cli/tests/cli_run.rs b/crates/cli/tests/cli_run.rs index 21a9017261..65836ea9b3 100644 --- a/crates/cli/tests/cli_run.rs +++ b/crates/cli/tests/cli_run.rs @@ -471,7 +471,7 @@ mod cli_run { // expected_ending: "[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2]\n", // use_valgrind: true, // }, - effects:"interactive" => Example { + effects:"cli" => Example { filename: "effects.roc", executable_filename: "effects", stdin: &["hi there!"], @@ -487,7 +487,7 @@ mod cli_run { // expected_ending: "", // use_valgrind: true, // }, - cli:"interactive" => Example { + cli:"cli" => Example { filename: "form.roc", executable_filename: "form", stdin: &["Giovanni\n", "Giorgio\n"], @@ -495,7 +495,7 @@ mod cli_run { expected_ending: "Hi, Giovanni Giorgio! 👋\n", use_valgrind: false, }, - tui:"interactive" => Example { + tui:"cli" => Example { filename: "tui.roc", executable_filename: "tui", stdin: &["foo\n"], // NOTE: adding more lines leads to memory leaks diff --git a/crates/editor/src/editor/main.rs b/crates/editor/src/editor/main.rs index 5e46664b22..9161e45e69 100644 --- a/crates/editor/src/editor/main.rs +++ b/crates/editor/src/editor/main.rs @@ -523,7 +523,7 @@ fn read_main_roc_file(project_dir_path_opt: Option<&Path>) -> (PathBuf, String) // returns path and content of app file fn init_new_roc_project(project_dir_path: &Path) -> (PathBuf, String) { - let orig_platform_path = Path::new("./examples/interactive").join(PLATFORM_DIR_NAME); + let orig_platform_path = Path::new("./examples/cli").join(PLATFORM_DIR_NAME); let roc_file_path = Path::new("./new-roc-project/main.roc"); diff --git a/crates/highlight/tests/peg_grammar.rs b/crates/highlight/tests/peg_grammar.rs index 655088e8cf..b5156a6daa 100644 --- a/crates/highlight/tests/peg_grammar.rs +++ b/crates/highlight/tests/peg_grammar.rs @@ -881,7 +881,7 @@ test1 = #[test] fn test_cli_echo() { - let tokens = tokenize(&example_path("interactive/echo.roc")); + let tokens = tokenize(&example_path("cli/echo.roc")); assert_eq!(tokenparser::module(&tokens), Ok(())); } diff --git a/examples/interactive/.gitignore b/examples/cli/.gitignore similarity index 100% rename from examples/interactive/.gitignore rename to examples/cli/.gitignore diff --git a/examples/interactive/README.md b/examples/cli/README.md similarity index 96% rename from examples/interactive/README.md rename to examples/cli/README.md index 545fd58f53..fd939f8b4e 100644 --- a/examples/interactive/README.md +++ b/examples/cli/README.md @@ -1,4 +1,4 @@ -# Interactive examples +# CLI examples These are examples of how to make basic CLI (command-line interface) and TUI (terminal user interface) apps in Roc. diff --git a/examples/interactive/cli-platform/Cargo.lock b/examples/cli/cli-platform/Cargo.lock similarity index 100% rename from examples/interactive/cli-platform/Cargo.lock rename to examples/cli/cli-platform/Cargo.lock diff --git a/examples/interactive/cli-platform/Cargo.toml b/examples/cli/cli-platform/Cargo.toml similarity index 100% rename from examples/interactive/cli-platform/Cargo.toml rename to examples/cli/cli-platform/Cargo.toml diff --git a/examples/interactive/cli-platform/Effect.roc b/examples/cli/cli-platform/Effect.roc similarity index 100% rename from examples/interactive/cli-platform/Effect.roc rename to examples/cli/cli-platform/Effect.roc diff --git a/examples/interactive/cli-platform/File.roc b/examples/cli/cli-platform/File.roc similarity index 100% rename from examples/interactive/cli-platform/File.roc rename to examples/cli/cli-platform/File.roc diff --git a/examples/interactive/cli-platform/Http.roc b/examples/cli/cli-platform/Http.roc similarity index 100% rename from examples/interactive/cli-platform/Http.roc rename to examples/cli/cli-platform/Http.roc diff --git a/examples/interactive/cli-platform/InternalFile.roc b/examples/cli/cli-platform/InternalFile.roc similarity index 100% rename from examples/interactive/cli-platform/InternalFile.roc rename to examples/cli/cli-platform/InternalFile.roc diff --git a/examples/interactive/cli-platform/InternalHttp.roc b/examples/cli/cli-platform/InternalHttp.roc similarity index 100% rename from examples/interactive/cli-platform/InternalHttp.roc rename to examples/cli/cli-platform/InternalHttp.roc diff --git a/examples/interactive/cli-platform/InternalPath.roc b/examples/cli/cli-platform/InternalPath.roc similarity index 100% rename from examples/interactive/cli-platform/InternalPath.roc rename to examples/cli/cli-platform/InternalPath.roc diff --git a/examples/interactive/cli-platform/InternalTask.roc b/examples/cli/cli-platform/InternalTask.roc similarity index 100% rename from examples/interactive/cli-platform/InternalTask.roc rename to examples/cli/cli-platform/InternalTask.roc diff --git a/examples/interactive/cli-platform/Path.roc b/examples/cli/cli-platform/Path.roc similarity index 100% rename from examples/interactive/cli-platform/Path.roc rename to examples/cli/cli-platform/Path.roc diff --git a/examples/interactive/cli-platform/Stderr.roc b/examples/cli/cli-platform/Stderr.roc similarity index 100% rename from examples/interactive/cli-platform/Stderr.roc rename to examples/cli/cli-platform/Stderr.roc diff --git a/examples/interactive/cli-platform/Stdin.roc b/examples/cli/cli-platform/Stdin.roc similarity index 100% rename from examples/interactive/cli-platform/Stdin.roc rename to examples/cli/cli-platform/Stdin.roc diff --git a/examples/interactive/cli-platform/Stdout.roc b/examples/cli/cli-platform/Stdout.roc similarity index 100% rename from examples/interactive/cli-platform/Stdout.roc rename to examples/cli/cli-platform/Stdout.roc diff --git a/examples/interactive/cli-platform/Task.roc b/examples/cli/cli-platform/Task.roc similarity index 100% rename from examples/interactive/cli-platform/Task.roc rename to examples/cli/cli-platform/Task.roc diff --git a/examples/interactive/cli-platform/Url.roc b/examples/cli/cli-platform/Url.roc similarity index 100% rename from examples/interactive/cli-platform/Url.roc rename to examples/cli/cli-platform/Url.roc diff --git a/examples/interactive/cli-platform/build.rs b/examples/cli/cli-platform/build.rs similarity index 100% rename from examples/interactive/cli-platform/build.rs rename to examples/cli/cli-platform/build.rs diff --git a/examples/interactive/cli-platform/host.c b/examples/cli/cli-platform/host.c similarity index 100% rename from examples/interactive/cli-platform/host.c rename to examples/cli/cli-platform/host.c diff --git a/examples/interactive/cli-platform/main.roc b/examples/cli/cli-platform/main.roc similarity index 100% rename from examples/interactive/cli-platform/main.roc rename to examples/cli/cli-platform/main.roc diff --git a/examples/interactive/cli-platform/src/file_glue.rs b/examples/cli/cli-platform/src/file_glue.rs similarity index 100% rename from examples/interactive/cli-platform/src/file_glue.rs rename to examples/cli/cli-platform/src/file_glue.rs diff --git a/examples/interactive/cli-platform/src/glue.rs b/examples/cli/cli-platform/src/glue.rs similarity index 100% rename from examples/interactive/cli-platform/src/glue.rs rename to examples/cli/cli-platform/src/glue.rs diff --git a/examples/interactive/cli-platform/src/lib.rs b/examples/cli/cli-platform/src/lib.rs similarity index 100% rename from examples/interactive/cli-platform/src/lib.rs rename to examples/cli/cli-platform/src/lib.rs diff --git a/examples/interactive/cli-platform/src/main.rs b/examples/cli/cli-platform/src/main.rs similarity index 100% rename from examples/interactive/cli-platform/src/main.rs rename to examples/cli/cli-platform/src/main.rs diff --git a/examples/interactive/countdown.roc b/examples/cli/countdown.roc similarity index 100% rename from examples/interactive/countdown.roc rename to examples/cli/countdown.roc diff --git a/examples/interactive/echo.roc b/examples/cli/echo.roc similarity index 100% rename from examples/interactive/echo.roc rename to examples/cli/echo.roc diff --git a/examples/interactive/effects-platform/Effect.roc b/examples/cli/effects-platform/Effect.roc similarity index 100% rename from examples/interactive/effects-platform/Effect.roc rename to examples/cli/effects-platform/Effect.roc diff --git a/examples/interactive/effects-platform/host.zig b/examples/cli/effects-platform/host.zig similarity index 100% rename from examples/interactive/effects-platform/host.zig rename to examples/cli/effects-platform/host.zig diff --git a/examples/interactive/effects-platform/main.roc b/examples/cli/effects-platform/main.roc similarity index 100% rename from examples/interactive/effects-platform/main.roc rename to examples/cli/effects-platform/main.roc diff --git a/examples/interactive/effects.roc b/examples/cli/effects.roc similarity index 100% rename from examples/interactive/effects.roc rename to examples/cli/effects.roc diff --git a/examples/interactive/file.roc b/examples/cli/file.roc similarity index 100% rename from examples/interactive/file.roc rename to examples/cli/file.roc diff --git a/examples/interactive/form.roc b/examples/cli/form.roc similarity index 100% rename from examples/interactive/form.roc rename to examples/cli/form.roc diff --git a/examples/interactive/http-get.roc b/examples/cli/http-get.roc similarity index 100% rename from examples/interactive/http-get.roc rename to examples/cli/http-get.roc diff --git a/examples/interactive/tui-platform/Program.roc b/examples/cli/tui-platform/Program.roc similarity index 100% rename from examples/interactive/tui-platform/Program.roc rename to examples/cli/tui-platform/Program.roc diff --git a/examples/interactive/tui-platform/host.zig b/examples/cli/tui-platform/host.zig similarity index 100% rename from examples/interactive/tui-platform/host.zig rename to examples/cli/tui-platform/host.zig diff --git a/examples/interactive/tui-platform/main.roc b/examples/cli/tui-platform/main.roc similarity index 100% rename from examples/interactive/tui-platform/main.roc rename to examples/cli/tui-platform/main.roc diff --git a/examples/interactive/tui.roc b/examples/cli/tui.roc similarity index 100% rename from examples/interactive/tui.roc rename to examples/cli/tui.roc diff --git a/examples/helloWorld.roc b/examples/helloWorld.roc index 13a8ff24e7..1b6c4d7655 100644 --- a/examples/helloWorld.roc +++ b/examples/helloWorld.roc @@ -1,5 +1,5 @@ app "helloWorld" - packages { pf: "interactive/cli-platform/main.roc" } + packages { pf: "cli/cli-platform/main.roc" } imports [pf.Stdout] provides [main] to pf From e84b43ddb6df57d9fa7da0d30c2856514a236e7e Mon Sep 17 00:00:00 2001 From: Jan Van Bruggen Date: Sun, 11 Sep 2022 21:58:09 -0600 Subject: [PATCH 05/65] Categorize FALSE interpreter as a CLI --- examples/{ => cli}/false-interpreter/.gitignore | 0 examples/{ => cli}/false-interpreter/Context.roc | 0 examples/{ => cli}/false-interpreter/False.roc | 0 examples/{ => cli}/false-interpreter/README.md | 0 examples/{ => cli}/false-interpreter/Variable.roc | 0 examples/{ => cli}/false-interpreter/examples/bottles.false | 0 examples/{ => cli}/false-interpreter/examples/cksum.false | 0 examples/{ => cli}/false-interpreter/examples/copy.false | 0 examples/{ => cli}/false-interpreter/examples/crc32.false | 0 examples/{ => cli}/false-interpreter/examples/hello.false | 0 examples/{ => cli}/false-interpreter/examples/in.txt | 0 examples/{ => cli}/false-interpreter/examples/odd_words.false | 0 examples/{ => cli}/false-interpreter/examples/primes.false | 0 examples/{ => cli}/false-interpreter/examples/queens.false | 0 examples/{ => cli}/false-interpreter/examples/sqrt.false | 0 examples/{ => cli}/false-interpreter/examples/test.false | 0 examples/{ => cli}/false-interpreter/platform/Cargo.lock | 0 examples/{ => cli}/false-interpreter/platform/Cargo.toml | 0 examples/{ => cli}/false-interpreter/platform/Effect.roc | 0 examples/{ => cli}/false-interpreter/platform/File.roc | 0 examples/{ => cli}/false-interpreter/platform/Stdin.roc | 0 examples/{ => cli}/false-interpreter/platform/Stdout.roc | 0 examples/{ => cli}/false-interpreter/platform/Task.roc | 0 examples/{ => cli}/false-interpreter/platform/build.rs | 0 examples/{ => cli}/false-interpreter/platform/host.c | 0 examples/{ => cli}/false-interpreter/platform/main.roc | 0 examples/{ => cli}/false-interpreter/platform/src/lib.rs | 0 examples/{ => cli}/false-interpreter/platform/src/main.rs | 0 28 files changed, 0 insertions(+), 0 deletions(-) rename examples/{ => cli}/false-interpreter/.gitignore (100%) rename examples/{ => cli}/false-interpreter/Context.roc (100%) rename examples/{ => cli}/false-interpreter/False.roc (100%) rename examples/{ => cli}/false-interpreter/README.md (100%) rename examples/{ => cli}/false-interpreter/Variable.roc (100%) rename examples/{ => cli}/false-interpreter/examples/bottles.false (100%) rename examples/{ => cli}/false-interpreter/examples/cksum.false (100%) rename examples/{ => cli}/false-interpreter/examples/copy.false (100%) rename examples/{ => cli}/false-interpreter/examples/crc32.false (100%) rename examples/{ => cli}/false-interpreter/examples/hello.false (100%) rename examples/{ => cli}/false-interpreter/examples/in.txt (100%) rename examples/{ => cli}/false-interpreter/examples/odd_words.false (100%) rename examples/{ => cli}/false-interpreter/examples/primes.false (100%) rename examples/{ => cli}/false-interpreter/examples/queens.false (100%) rename examples/{ => cli}/false-interpreter/examples/sqrt.false (100%) rename examples/{ => cli}/false-interpreter/examples/test.false (100%) rename examples/{ => cli}/false-interpreter/platform/Cargo.lock (100%) rename examples/{ => cli}/false-interpreter/platform/Cargo.toml (100%) rename examples/{ => cli}/false-interpreter/platform/Effect.roc (100%) rename examples/{ => cli}/false-interpreter/platform/File.roc (100%) rename examples/{ => cli}/false-interpreter/platform/Stdin.roc (100%) rename examples/{ => cli}/false-interpreter/platform/Stdout.roc (100%) rename examples/{ => cli}/false-interpreter/platform/Task.roc (100%) rename examples/{ => cli}/false-interpreter/platform/build.rs (100%) rename examples/{ => cli}/false-interpreter/platform/host.c (100%) rename examples/{ => cli}/false-interpreter/platform/main.roc (100%) rename examples/{ => cli}/false-interpreter/platform/src/lib.rs (100%) rename examples/{ => cli}/false-interpreter/platform/src/main.rs (100%) diff --git a/examples/false-interpreter/.gitignore b/examples/cli/false-interpreter/.gitignore similarity index 100% rename from examples/false-interpreter/.gitignore rename to examples/cli/false-interpreter/.gitignore diff --git a/examples/false-interpreter/Context.roc b/examples/cli/false-interpreter/Context.roc similarity index 100% rename from examples/false-interpreter/Context.roc rename to examples/cli/false-interpreter/Context.roc diff --git a/examples/false-interpreter/False.roc b/examples/cli/false-interpreter/False.roc similarity index 100% rename from examples/false-interpreter/False.roc rename to examples/cli/false-interpreter/False.roc diff --git a/examples/false-interpreter/README.md b/examples/cli/false-interpreter/README.md similarity index 100% rename from examples/false-interpreter/README.md rename to examples/cli/false-interpreter/README.md diff --git a/examples/false-interpreter/Variable.roc b/examples/cli/false-interpreter/Variable.roc similarity index 100% rename from examples/false-interpreter/Variable.roc rename to examples/cli/false-interpreter/Variable.roc diff --git a/examples/false-interpreter/examples/bottles.false b/examples/cli/false-interpreter/examples/bottles.false similarity index 100% rename from examples/false-interpreter/examples/bottles.false rename to examples/cli/false-interpreter/examples/bottles.false diff --git a/examples/false-interpreter/examples/cksum.false b/examples/cli/false-interpreter/examples/cksum.false similarity index 100% rename from examples/false-interpreter/examples/cksum.false rename to examples/cli/false-interpreter/examples/cksum.false diff --git a/examples/false-interpreter/examples/copy.false b/examples/cli/false-interpreter/examples/copy.false similarity index 100% rename from examples/false-interpreter/examples/copy.false rename to examples/cli/false-interpreter/examples/copy.false diff --git a/examples/false-interpreter/examples/crc32.false b/examples/cli/false-interpreter/examples/crc32.false similarity index 100% rename from examples/false-interpreter/examples/crc32.false rename to examples/cli/false-interpreter/examples/crc32.false diff --git a/examples/false-interpreter/examples/hello.false b/examples/cli/false-interpreter/examples/hello.false similarity index 100% rename from examples/false-interpreter/examples/hello.false rename to examples/cli/false-interpreter/examples/hello.false diff --git a/examples/false-interpreter/examples/in.txt b/examples/cli/false-interpreter/examples/in.txt similarity index 100% rename from examples/false-interpreter/examples/in.txt rename to examples/cli/false-interpreter/examples/in.txt diff --git a/examples/false-interpreter/examples/odd_words.false b/examples/cli/false-interpreter/examples/odd_words.false similarity index 100% rename from examples/false-interpreter/examples/odd_words.false rename to examples/cli/false-interpreter/examples/odd_words.false diff --git a/examples/false-interpreter/examples/primes.false b/examples/cli/false-interpreter/examples/primes.false similarity index 100% rename from examples/false-interpreter/examples/primes.false rename to examples/cli/false-interpreter/examples/primes.false diff --git a/examples/false-interpreter/examples/queens.false b/examples/cli/false-interpreter/examples/queens.false similarity index 100% rename from examples/false-interpreter/examples/queens.false rename to examples/cli/false-interpreter/examples/queens.false diff --git a/examples/false-interpreter/examples/sqrt.false b/examples/cli/false-interpreter/examples/sqrt.false similarity index 100% rename from examples/false-interpreter/examples/sqrt.false rename to examples/cli/false-interpreter/examples/sqrt.false diff --git a/examples/false-interpreter/examples/test.false b/examples/cli/false-interpreter/examples/test.false similarity index 100% rename from examples/false-interpreter/examples/test.false rename to examples/cli/false-interpreter/examples/test.false diff --git a/examples/false-interpreter/platform/Cargo.lock b/examples/cli/false-interpreter/platform/Cargo.lock similarity index 100% rename from examples/false-interpreter/platform/Cargo.lock rename to examples/cli/false-interpreter/platform/Cargo.lock diff --git a/examples/false-interpreter/platform/Cargo.toml b/examples/cli/false-interpreter/platform/Cargo.toml similarity index 100% rename from examples/false-interpreter/platform/Cargo.toml rename to examples/cli/false-interpreter/platform/Cargo.toml diff --git a/examples/false-interpreter/platform/Effect.roc b/examples/cli/false-interpreter/platform/Effect.roc similarity index 100% rename from examples/false-interpreter/platform/Effect.roc rename to examples/cli/false-interpreter/platform/Effect.roc diff --git a/examples/false-interpreter/platform/File.roc b/examples/cli/false-interpreter/platform/File.roc similarity index 100% rename from examples/false-interpreter/platform/File.roc rename to examples/cli/false-interpreter/platform/File.roc diff --git a/examples/false-interpreter/platform/Stdin.roc b/examples/cli/false-interpreter/platform/Stdin.roc similarity index 100% rename from examples/false-interpreter/platform/Stdin.roc rename to examples/cli/false-interpreter/platform/Stdin.roc diff --git a/examples/false-interpreter/platform/Stdout.roc b/examples/cli/false-interpreter/platform/Stdout.roc similarity index 100% rename from examples/false-interpreter/platform/Stdout.roc rename to examples/cli/false-interpreter/platform/Stdout.roc diff --git a/examples/false-interpreter/platform/Task.roc b/examples/cli/false-interpreter/platform/Task.roc similarity index 100% rename from examples/false-interpreter/platform/Task.roc rename to examples/cli/false-interpreter/platform/Task.roc diff --git a/examples/false-interpreter/platform/build.rs b/examples/cli/false-interpreter/platform/build.rs similarity index 100% rename from examples/false-interpreter/platform/build.rs rename to examples/cli/false-interpreter/platform/build.rs diff --git a/examples/false-interpreter/platform/host.c b/examples/cli/false-interpreter/platform/host.c similarity index 100% rename from examples/false-interpreter/platform/host.c rename to examples/cli/false-interpreter/platform/host.c diff --git a/examples/false-interpreter/platform/main.roc b/examples/cli/false-interpreter/platform/main.roc similarity index 100% rename from examples/false-interpreter/platform/main.roc rename to examples/cli/false-interpreter/platform/main.roc diff --git a/examples/false-interpreter/platform/src/lib.rs b/examples/cli/false-interpreter/platform/src/lib.rs similarity index 100% rename from examples/false-interpreter/platform/src/lib.rs rename to examples/cli/false-interpreter/platform/src/lib.rs diff --git a/examples/false-interpreter/platform/src/main.rs b/examples/cli/false-interpreter/platform/src/main.rs similarity index 100% rename from examples/false-interpreter/platform/src/main.rs rename to examples/cli/false-interpreter/platform/src/main.rs From e3c9bf46dbec64e18bb853fc249d5d5acfcc4d15 Mon Sep 17 00:00:00 2001 From: Jan Van Bruggen Date: Sun, 11 Sep 2022 22:27:36 -0600 Subject: [PATCH 06/65] [WIP] How should we test the newly-crated examples? --- crates/cli/tests/cli_run.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/cli/tests/cli_run.rs b/crates/cli/tests/cli_run.rs index 65836ea9b3..a949b1e7bb 100644 --- a/crates/cli/tests/cli_run.rs +++ b/crates/cli/tests/cli_run.rs @@ -348,6 +348,7 @@ mod cli_run { all_examples.insert($name, $example); )* + check_for_tests("../cli_testing_examples", &mut all_examples); check_for_tests("../../examples", &mut all_examples); } } From 84f58f59ff621090c113e4c3b756281308b489ad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Sep 2022 21:08:45 +0000 Subject: [PATCH 07/65] Bump pest_derive from 2.1.0 to 2.3.1 Bumps [pest_derive](https://github.com/pest-parser/pest) from 2.1.0 to 2.3.1. - [Release notes](https://github.com/pest-parser/pest/releases) - [Commits](https://github.com/pest-parser/pest/compare/v2.1.0...v2.3.1) --- updated-dependencies: - dependency-name: pest_derive dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 106 +++++++++------------------------------ crates/editor/Cargo.toml | 2 +- 2 files changed, 25 insertions(+), 83 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1215b83b0b..6bc474ee33 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -253,34 +253,13 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" -[[package]] -name = "block-buffer" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" -dependencies = [ - "block-padding", - "byte-tools", - "byteorder", - "generic-array 0.12.4", -] - [[package]] name = "block-buffer" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" dependencies = [ - "generic-array 0.14.5", -] - -[[package]] -name = "block-padding" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" -dependencies = [ - "byte-tools", + "generic-array", ] [[package]] @@ -301,12 +280,6 @@ version = "3.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" -[[package]] -name = "byte-tools" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" - [[package]] name = "bytecheck" version = "0.6.8" @@ -1023,7 +996,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ccfd8c0ee4cce11e45b3fd6f9d5e69e0cc62912aa6a0cb1bf4617b0eba5a12f" dependencies = [ - "generic-array 0.14.5", + "generic-array", "typenum", ] @@ -1129,22 +1102,13 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" -[[package]] -name = "digest" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" -dependencies = [ - "generic-array 0.12.4", -] - [[package]] name = "digest" version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" dependencies = [ - "block-buffer 0.10.2", + "block-buffer", "crypto-common", ] @@ -1380,12 +1344,6 @@ dependencies = [ "str-buf", ] -[[package]] -name = "fake-simd" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" - [[package]] name = "fallible-iterator" version = "0.2.0" @@ -1577,15 +1535,6 @@ dependencies = [ "cfg-if 0.1.10", ] -[[package]] -name = "generic-array" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" -dependencies = [ - "typenum", -] - [[package]] name = "generic-array" version = "0.14.5" @@ -2625,12 +2574,6 @@ version = "11.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" -[[package]] -name = "opaque-debug" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" - [[package]] name = "ordered-float" version = "3.0.0" @@ -2819,9 +2762,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.1.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0" +checksum = "502b62a6d0245378b04ffe0a7fb4f4419a4815fce813bd8a0ec89a56e07d67b1" dependencies = [ "pest", "pest_generator", @@ -2829,9 +2772,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.1.3" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" +checksum = "451e629bf49b750254da26132f1a5a9d11fd8a95a3df51d15c4abd1ba154cb6c" dependencies = [ "pest", "pest_meta", @@ -2842,13 +2785,13 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.1.3" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d" +checksum = "bcec162c71c45e269dfc3fc2916eaeb97feab22993a21bcce4721d08cd7801a6" dependencies = [ - "maplit", + "once_cell", "pest", - "sha-1", + "sha1 0.10.4", ] [[package]] @@ -4465,18 +4408,6 @@ dependencies = [ "syn", ] -[[package]] -name = "sha-1" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" -dependencies = [ - "block-buffer 0.7.3", - "digest 0.8.1", - "fake-simd", - "opaque-debug", -] - [[package]] name = "sha1" version = "0.6.1" @@ -4486,6 +4417,17 @@ dependencies = [ "sha1_smol", ] +[[package]] +name = "sha1" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "006769ba83e921b3085caa8334186b00cf92b4cb1a6cf4632fbccc8eff5c7549" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest", +] + [[package]] name = "sha1_smol" version = "1.0.0" @@ -4500,7 +4442,7 @@ checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" dependencies = [ "cfg-if 1.0.0", "cpufeatures", - "digest 0.10.3", + "digest", ] [[package]] @@ -4743,7 +4685,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "sha1", + "sha1 0.6.1", "syn", ] diff --git a/crates/editor/Cargo.toml b/crates/editor/Cargo.toml index f81bf54da0..c662e87823 100644 --- a/crates/editor/Cargo.toml +++ b/crates/editor/Cargo.toml @@ -48,7 +48,7 @@ cgmath = "0.18.0" snafu = { version = "0.7.1", features = ["backtraces"] } colored = "2.0.0" pest = "2.3.1" -pest_derive = "2.1.0" +pest_derive = "2.3.1" copypasta = "0.8.1" palette = "0.6.1" confy = { git = 'https://github.com/rust-cli/confy', features = [ From 1d9a751606ff6c1b971534ef3fb17990f3e24895 Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Sat, 24 Sep 2022 20:14:59 +0200 Subject: [PATCH 08/65] cli_run test fixes --- crates/cli/tests/cli_run.rs | 7 ++++--- crates/cli_utils/src/helpers.rs | 13 +++++++++++++ crates/compiler/build/src/link.rs | 1 + examples/cli/false-interpreter/platform/Cargo.toml | 2 +- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/crates/cli/tests/cli_run.rs b/crates/cli/tests/cli_run.rs index 03c3b7c2e7..54dd1bf328 100644 --- a/crates/cli/tests/cli_run.rs +++ b/crates/cli/tests/cli_run.rs @@ -10,7 +10,7 @@ extern crate roc_module; #[cfg(test)] mod cli_run { use cli_utils::helpers::{ - example_file, examples_dir, extract_valgrind_errors, fixture_file, fixtures_dir, + example_file, examples_dir, cli_testing_dir, extract_valgrind_errors, fixture_file, fixtures_dir, known_bad_file, run_cmd, run_roc, run_with_valgrind, strip_colors, Out, ValgrindError, ValgrindErrorXWhat, }; @@ -115,6 +115,7 @@ mod cli_run { stdin: &[&str], app_args: &[String], ) -> Out { + dbg!(file); let compile_out = run_roc( // converting these all to String avoids lifetime issues args.into_iter() @@ -584,7 +585,7 @@ mod cli_run { // expected_ending: "successfully wrote to file\n", // use_valgrind: true, // }, - false_interpreter:"false-interpreter" => { + false_interpreter:"cli/false-interpreter" => { Example { filename: "False.roc", executable_filename: "false", @@ -623,7 +624,7 @@ mod cli_run { #[cfg(all(not(feature = "wasm32-cli-run"), not(feature = "i386-cli-run")))] fn $test_name() { let benchmark = $benchmark; - let file_name = examples_dir("benchmarks").join(benchmark.filename); + let file_name = cli_testing_dir("benchmarks").join(benchmark.filename); // TODO fix QuicksortApp and then remove this! match benchmark.filename { diff --git a/crates/cli_utils/src/helpers.rs b/crates/cli_utils/src/helpers.rs index f2f37bd3cd..1a0b8f1c19 100644 --- a/crates/cli_utils/src/helpers.rs +++ b/crates/cli_utils/src/helpers.rs @@ -359,6 +359,19 @@ pub fn root_dir() -> PathBuf { path } +// start the dir with crates/cli_testing_examples +#[allow(dead_code)] +pub fn cli_testing_dir(dir_name: &str) -> PathBuf { + let mut path = root_dir(); + + // Descend into examples/{dir_name} + path.push("crates"); + path.push("cli_testing_examples"); + path.extend(dir_name.split("/")); // Make slashes cross-target + + path +} + #[allow(dead_code)] pub fn examples_dir(dir_name: &str) -> PathBuf { let mut path = root_dir(); diff --git a/crates/compiler/build/src/link.rs b/crates/compiler/build/src/link.rs index febc70a66a..fa4eb1dfb8 100644 --- a/crates/compiler/build/src/link.rs +++ b/crates/compiler/build/src/link.rs @@ -635,6 +635,7 @@ pub fn rebuild_host( } else if cargo_host_src.exists() { // Compile and link Cargo.toml, if it exists let cargo_dir = host_input_path.parent().unwrap(); + let cargo_out_dir = cargo_dir.join("target").join( if matches!(opt_level, OptLevel::Optimize | OptLevel::Size) { "release" diff --git a/examples/cli/false-interpreter/platform/Cargo.toml b/examples/cli/false-interpreter/platform/Cargo.toml index 9d98cfe0e8..eeeb74f517 100644 --- a/examples/cli/false-interpreter/platform/Cargo.toml +++ b/examples/cli/false-interpreter/platform/Cargo.toml @@ -17,7 +17,7 @@ name = "host" path = "src/main.rs" [dependencies] -roc_std = { path = "../../../crates/roc_std" } +roc_std = { path = "../../../../crates/roc_std" } libc = "0.2" [workspace] From d5dbee57d956cc8dd66f366360e4cf3bce8dedbf Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Tue, 27 Sep 2022 20:25:28 +0200 Subject: [PATCH 09/65] cli_run no macro re-write --- crates/cli/tests/cli_run.rs | 1283 ++++++++--------- .../rust-platform/Cargo.toml | 2 +- crates/cli_utils/src/bench_utils.rs | 14 +- crates/cli_utils/src/helpers.rs | 8 +- examples/gui/breakout/platform/Cargo.toml | 2 +- .../platform/src/graphics/primitives/text.rs | 2 +- examples/gui/{Hello.roc => hello.roc} | 0 examples/helloWorld.roc | 9 +- 8 files changed, 605 insertions(+), 715 deletions(-) rename examples/gui/{Hello.roc => hello.roc} (100%) diff --git a/crates/cli/tests/cli_run.rs b/crates/cli/tests/cli_run.rs index 54dd1bf328..7e418d0124 100644 --- a/crates/cli/tests/cli_run.rs +++ b/crates/cli/tests/cli_run.rs @@ -10,20 +10,16 @@ extern crate roc_module; #[cfg(test)] mod cli_run { use cli_utils::helpers::{ - example_file, examples_dir, cli_testing_dir, extract_valgrind_errors, fixture_file, fixtures_dir, - known_bad_file, run_cmd, run_roc, run_with_valgrind, strip_colors, Out, ValgrindError, - ValgrindErrorXWhat, + extract_valgrind_errors, file_path_from_root, fixture_file, fixtures_dir, known_bad_file, + run_cmd, run_roc, run_with_valgrind, strip_colors, Out, ValgrindError, ValgrindErrorXWhat, }; use const_format::concatcp; use indoc::indoc; - use once_cell::sync::Lazy; - use parking_lot::{Mutex, RwLock}; use roc_cli::{CMD_BUILD, CMD_CHECK, CMD_FORMAT, CMD_RUN}; use roc_test_utils::assert_multiline_str_eq; use serial_test::serial; use std::iter; - use std::path::{Path, PathBuf}; - use std::sync::Once; + use std::path::Path; use strum::IntoEnumIterator; use strum_macros::EnumIter; @@ -34,20 +30,6 @@ mod cli_run { #[allow(dead_code)] const TARGET_FLAG: &str = concatcp!("--", roc_cli::FLAG_TARGET); - static BENCHMARKS_BUILD_PLATFORM: Once = Once::new(); - static POPULATED_EXAMPLE_LOCKS: Once = Once::new(); - - use std::collections::HashMap; - static EXAMPLE_PLATFORM_LOCKS: Lazy>>> = - once_cell::sync::Lazy::new(|| RwLock::new(HashMap::default())); - - fn populate_example_locks(examples: impl Iterator) { - let mut locks = EXAMPLE_PLATFORM_LOCKS.write(); - for example in examples { - locks.insert(example, Default::default()); - } - } - #[derive(Debug, EnumIter)] enum CliMode { RocBuild, @@ -82,7 +64,7 @@ mod cli_run { } #[derive(Debug, PartialEq, Eq)] - struct Example<'a> { + struct CliTest<'a> { filename: &'a str, executable_filename: &'a str, stdin: &'a [&'a str], @@ -113,15 +95,14 @@ mod cli_run { file: &'a Path, args: I, stdin: &[&str], - app_args: &[String], + roc_app_args: &[String], ) -> Out { - dbg!(file); let compile_out = run_roc( // converting these all to String avoids lifetime issues args.into_iter() .map(|arg| arg.to_string()) .chain([file.to_str().unwrap().to_string(), "--".to_string()]) - .chain(app_args.iter().cloned()), + .chain(roc_app_args.iter().cloned()), stdin, ); @@ -142,7 +123,7 @@ mod cli_run { stdin: &[&str], executable_filename: &str, flags: &[&str], - app_args: &[String], + roc_app_args: &[String], expected_ending: &str, use_valgrind: bool, ) { @@ -172,7 +153,7 @@ mod cli_run { .to_str() .unwrap() .to_string()]; - valgrind_args.extend(app_args.iter().cloned()); + valgrind_args.extend(roc_app_args.iter().cloned()); let (valgrind_out, raw_xml) = run_with_valgrind(stdin.iter().copied(), &valgrind_args); if valgrind_out.status.success() { @@ -214,16 +195,16 @@ mod cli_run { run_cmd( file.with_file_name(executable_filename).to_str().unwrap(), stdin.iter().copied(), - app_args, + roc_app_args, ) } } - CliMode::Roc => run_roc_on(file, flags.clone(), stdin, app_args), + CliMode::Roc => run_roc_on(file, flags.clone(), stdin, roc_app_args), CliMode::RocRun => run_roc_on( file, iter::once(CMD_RUN).chain(flags.clone()), stdin, - app_args, + roc_app_args, ), }; @@ -238,716 +219,622 @@ mod cli_run { } } - #[cfg(feature = "wasm32-cli-run")] - fn check_wasm_output_with_stdin( - file: &Path, - stdin: &[&str], + fn test_roc_app( + dir_name: &str, + roc_filename: &str, executable_filename: &str, - flags: &[&str], - args: &[&Arg], + stdin: &[&str], + args: &[Arg], expected_ending: &str, + use_valgrind: bool, ) { - assert!(input_paths.is_empty(), "Wasm does not support input files"); - let mut flags = flags.to_vec(); - flags.push(concatcp!(TARGET_FLAG, "=wasm32")); + let file_name = file_path_from_root(dir_name, roc_filename); - let compile_out = run_roc( - [CMD_BUILD, file.to_str().unwrap()] - .iter() - .chain(flags.as_slice()), - ); - if !compile_out.stderr.is_empty() { - panic!("{}", compile_out.stderr); + let mut roc_app_args: Vec = vec![]; + for arg in args { + match arg { + Arg::ExamplePath(file) => { + roc_app_args.push( + file_path_from_root(dir_name, file) + .to_str() + .unwrap() + .to_string(), + ); + } + Arg::PlainText(arg) => { + roc_app_args.push(arg.to_string()); + } + } } - assert!(compile_out.status.success(), "bad status {:?}", compile_out); + // workaround for surgical linker issue, see PR #3990 + let mut custom_flags: Vec<&str> = vec![]; - let path = file.with_file_name(executable_filename); - let stdout = crate::run_with_wasmer(&path, stdin); + match executable_filename { + "form" | "hello-gui" | "breakout" | "ruby" => { + // Since these require things the build system often doesn't have + // (e.g. GUIs open a window, Ruby needs ruby installed, WASM needs a browser) + // we do `roc build` on them but don't run them. + run_roc_on(&file_name, [CMD_BUILD, OPTIMIZE_FLAG], &[], &[]); + return; + } + "swiftui" | "rocLovesSwift" => { + if cfg!(not(target_os = "macos")) { + eprintln!( + "WARNING: skipping testing example {} because it only works on MacOS.", + roc_filename + ); + return; + } else { + run_roc_on(&file_name, [CMD_BUILD, OPTIMIZE_FLAG], &[], &[]); + return; + } + } + "rocLovesWebAssembly" => { + // this is a web assembly example, but we don't test with JS at the moment + eprintln!( + "WARNING: skipping testing example {} because it only works in a browser!", + roc_filename + ); + return; + } + "args" => { + custom_flags = vec![LINKER_FLAG, "legacy"]; + } + _ => {} + } - if !stdout.ends_with(expected_ending) { - panic!( - "expected output to end with {:?} but instead got {:#?}", - expected_ending, stdout + // Check with and without optimizations + check_output_with_stdin( + &file_name, + stdin, + executable_filename, + &custom_flags, + &roc_app_args, + expected_ending, + use_valgrind, + ); + + custom_flags.push(OPTIMIZE_FLAG); + // This is mostly because the false interpreter is still very slow - + // 25s for the cli tests is just not acceptable during development! + #[cfg(not(debug_assertions))] + check_output_with_stdin( + &file_name, + stdin, + executable_filename, + &custom_flags, + &roc_app_args, + expected_ending, + use_valgrind, + ); + + // Also check with the legacy linker. + + if TEST_LEGACY_LINKER { + check_output_with_stdin( + &file_name, + stdin, + executable_filename, + &[LINKER_FLAG, "legacy"], + &roc_app_args, + expected_ending, + use_valgrind, ); } } - /// This macro does two things. - /// - /// First, it generates and runs a separate test for each of the given - /// Example expressions. Each of these should test a particular .roc file - /// in the examples/ directory. - /// - /// Second, it generates an extra test which (non-recursively) traverses the - /// examples/ directory and verifies that each of the .roc files in there - /// has had a corresponding test generated in the previous step. This test - /// will fail if we ever add a new .roc file to examples/ and forget to - /// add a test for it here! - macro_rules! examples { - ($($test_name:ident:$name:expr => $example:expr,)+) => { - static EXAMPLE_NAMES: &[&str] = &[$($name,)+]; - - $( - #[test] - #[allow(non_snake_case)] - fn $test_name() { - POPULATED_EXAMPLE_LOCKS.call_once( || { - populate_example_locks(EXAMPLE_NAMES.iter().map(|name| examples_dir(name))) - }); - - let dir_name = $name; - let example = $example; - let example_dir = examples_dir(dir_name); - let file_name = example_file(dir_name, example.filename); - - let mut app_args: Vec = vec![]; - for arg in example.arguments { - match arg { - Arg::ExamplePath(file) => { - app_args.push(example_file(dir_name, file).to_str().unwrap().to_string()); - } - Arg::PlainText(arg) => { - app_args.push(arg.to_string()); - } - } - } - - // workaround for surgical linker issue, see PR #3990 - let mut custom_flags : Vec<&str> = vec![]; - - match example.executable_filename { - "form" | "hello-gui" | "breakout" | "ruby" => { - // Since these require things the build system often doesn't have - // (e.g. GUIs open a window, Ruby needs ruby installed, WASM needs a browser) - // we do `roc build` on them but don't run them. - run_roc_on(&file_name, [CMD_BUILD, OPTIMIZE_FLAG], &[], &[]); - return; - } - "swiftui" | "rocLovesSwift" => { - if cfg!(not(target_os = "macos")) { - eprintln!("WARNING: skipping testing example {} because it only works on MacOS.", example.filename); - return; - } else { - run_roc_on(&file_name, [CMD_BUILD, OPTIMIZE_FLAG], &[], &[]); - return; - } - } - "rocLovesWebAssembly" => { - // this is a web assembly example, but we don't test with JS at the moment - eprintln!("WARNING: skipping testing example {} because it only works in a browser!", example.filename); - return; - } - "args" => { - custom_flags = vec![LINKER_FLAG, "legacy"]; - } - _ => {} - } - - // To avoid concurrent examples tests overwriting produced host binaries, lock - // on the example's directory, so that only one example per directory runs at a - // time. - // NOTE: we are assuming that each example corresponds to one platform, under - // the subdirectory. This is not necessarily true, and moreover is too - // restrictive. To increase throughput we only need to lock the produced host - // file, however, it is not trivial to recover what that file is today (without - // enumerating all examples and their platforms). - let locks = EXAMPLE_PLATFORM_LOCKS.read(); - let _example_guard = locks.get(&example_dir).unwrap().lock(); - - // Check with and without optimizations - check_output_with_stdin( - &file_name, - example.stdin, - example.executable_filename, - &custom_flags, - &app_args, - example.expected_ending, - example.use_valgrind, - ); - - custom_flags.push(OPTIMIZE_FLAG); - // This is mostly because the false interpreter is still very slow - - // 25s for the cli tests is just not acceptable during development! - #[cfg(not(debug_assertions))] - check_output_with_stdin( - &file_name, - example.stdin, - example.executable_filename, - &custom_flags, - &app_args, - example.expected_ending, - example.use_valgrind, - ); - - // Also check with the legacy linker. - - if TEST_LEGACY_LINKER { - check_output_with_stdin( - &file_name, - example.stdin, - example.executable_filename, - &[LINKER_FLAG, "legacy"], - &app_args, - example.expected_ending, - example.use_valgrind, - ); - } - } - )* - - #[test] - #[cfg(not(debug_assertions))] - fn all_examples_have_tests() { - let mut all_examples: MutMap<&str, Example<'_>> = MutMap::default(); - - $( - all_examples.insert($name, $example); - )* - - check_for_tests("../cli_testing_examples", &mut all_examples); - check_for_tests("../../examples", &mut all_examples); - } - } + #[test] + fn hello_world() { + test_roc_app( + "examples", + "helloWorld.roc", + "helloWorld", + &[], + &[], + "Hello, World!\n", + true, + ) } - // examples! macro format: - // - // "name-of-subdirectory-inside-examples-dir" => [ - // test_name_1: Example { - // ... - // }, - // test_name_2: Example { - // ... - // }, - // ] - examples! { - helloWorld:"hello-world" => Example { - filename: "main.roc", - executable_filename: "helloWorld", - stdin: &[], - arguments: &[], - expected_ending:"Hello, World!\n", - use_valgrind: true, - }, - platformSwitching:"platform-switching" => Example { - filename: "main.roc", - executable_filename: "rocLovesPlatforms", - stdin: &[], - arguments: &[], - expected_ending:"Which platform am I running on now?\n", - use_valgrind: true, - }, - // We exclude the C platforming switching example - // because the main platform switching example runs the c platform. - // If we don't a race condition leads to test flakiness. - // platformSwitchingC:"platform-switching" => Example { - // filename: "rocLovesC.roc", - // executable_filename: "rocLovesC", - // stdin: &[], - // arguments: &[], - // expected_ending:"Roc <3 C!\n", - // use_valgrind: true, - // }, - platformSwitchingRust:"platform-switching" => Example { - filename: "rocLovesRust.roc", - executable_filename: "rocLovesRust", - stdin: &[], - arguments: &[], - expected_ending:"Roc <3 Rust!\n", - use_valgrind: true, - }, - platformSwitchingSwift:"platform-switching" => Example { - filename: "rocLovesSwift.roc", - executable_filename: "rocLovesSwift", - stdin: &[], - arguments: &[], - expected_ending:"Roc <3 Swift!\n", - use_valgrind: true, - }, - platformSwitchingWebAssembly:"platform-switching" => Example { - filename: "rocLovesWebAssembly.roc", - executable_filename: "rocLovesWebAssembly", - stdin: &[], - arguments: &[], - expected_ending:"Roc <3 Web Assembly!\n", - use_valgrind: true, - }, - platformSwitchingZig:"platform-switching" => Example { - filename: "rocLovesZig.roc", - executable_filename: "rocLovesZig", - stdin: &[], - arguments: &[], - expected_ending:"Roc <3 Zig!\n", - use_valgrind: true, - }, - ruby:"ruby-interop" => Example { - filename: "main.roc", - executable_filename: "libhello", - stdin: &[], - arguments: &[], - expected_ending:"", - use_valgrind: true, - }, - fib:"algorithms" => Example { - filename: "fibonacci.roc", - executable_filename: "fibonacci", - stdin: &[], - arguments: &[], - expected_ending:"55\n", - use_valgrind: true, - }, - gui:"gui" => Example { - filename: "Hello.roc", - executable_filename: "hello-gui", - stdin: &[], - arguments: &[], - expected_ending: "", - use_valgrind: false, - }, - breakout:"breakout" => Example { - filename: "breakout.roc", - executable_filename: "breakout", - stdin: &[], - arguments: &[], - expected_ending: "", - use_valgrind: false, - }, - quicksort:"algorithms" => Example { - filename: "quicksort.roc", - executable_filename: "quicksort", - stdin: &[], - arguments: &[], - expected_ending: "[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2]\n", - use_valgrind: true, - }, - // shared_quicksort:"shared-quicksort" => Example { - // filename: "Quicksort.roc", - // executable_filename: "quicksort", - // stdin: &[], - // arguments: &[], - // expected_ending: "[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2]\n", - // use_valgrind: true, - // }, - cli_args:"interactive" => Example { - filename: "args.roc", - executable_filename: "args", - stdin: &[], - arguments: &[Arg::PlainText("log"), Arg::PlainText("-b"), Arg::PlainText("3"), Arg::PlainText("--num"), Arg::PlainText("81")], - expected_ending: "4\n", - use_valgrind: false, - }, - effects:"interactive" => Example { - filename: "effects.roc", - executable_filename: "effects", - stdin: &["hi there!"], - arguments: &[], - expected_ending: "hi there!\nIt is known\n", - use_valgrind: true, - }, - // tui_tea:"tea" => Example { - // filename: "Main.roc", - // executable_filename: "tea-example", - // stdin: &[], - // arguments: &[], - // expected_ending: "", - // use_valgrind: true, - // }, - cli_form:"interactive" => Example { - filename: "form.roc", - executable_filename: "form", - stdin: &["Giovanni\n", "Giorgio\n"], - arguments: &[], - expected_ending: "Hi, Giovanni Giorgio! 👋\n", - use_valgrind: false, - }, - tui:"cli" => Example { - filename: "tui.roc", - executable_filename: "tui", - stdin: &["foo\n"], // NOTE: adding more lines leads to memory leaks - arguments: &[], - expected_ending: "Hello Worldfoo!\n", - use_valgrind: true, - }, - // custom_malloc:"custom-malloc" => Example { - // filename: "Main.roc", - // executable_filename: "custom-malloc-example", - // stdin: &[], - // arguments: &[], - // expected_ending: "ms!\nThe list was small!\n", - // use_valgrind: true, - // }, - // task:"task" => Example { - // filename: "Main.roc", - // executable_filename: "task-example", - // stdin: &[], - // arguments: &[], - // expected_ending: "successfully wrote to file\n", - // use_valgrind: true, - // }, - false_interpreter:"cli/false-interpreter" => { - Example { - filename: "False.roc", - executable_filename: "false", - stdin: &[], - arguments: &[Arg::ExamplePath("examples/hello.false")], - expected_ending:"Hello, World!\n", - use_valgrind: false, - } - }, - swiftui:"swiftui" => Example { - filename: "main.roc", - executable_filename: "swiftui", - stdin: &[], - arguments: &[], - expected_ending: "", - use_valgrind: false, - }, - static_site_gen: "static-site-gen" => { - Example { - filename: "static-site.roc", - executable_filename: "static-site", - stdin: &[], - arguments: &[Arg::ExamplePath("input"), Arg::ExamplePath("output")], - expected_ending: "Processed 3 files with 3 successes and 0 errors\n", - use_valgrind: false, - } - }, + #[test] + // uses C platform + fn platform_switching_main() { + test_roc_app( + "crates/cli_testing_examples/platform-switching", + "main.roc", + "rocLovesPlatforms", + &[], + &[], + "Which platform am I running on now?\n", + true, + ) } - macro_rules! benchmarks { - ($($test_name:ident => $benchmark:expr,)+) => { + // We exclude the C platforming switching example + // because the main platform switching example runs the c platform. + // If we don't, a race condition leads to test flakiness. - $( - #[test] - #[cfg_attr(not(debug_assertions), serial(benchmark))] - #[cfg(all(not(feature = "wasm32-cli-run"), not(feature = "i386-cli-run")))] - fn $test_name() { - let benchmark = $benchmark; - let file_name = cli_testing_dir("benchmarks").join(benchmark.filename); + #[test] + fn platform_switching_rust() { + test_roc_app( + "crates/cli_testing_examples/platform-switching", + "rocLovesRust.roc", + "rocLovesRust", + &[], + &[], + "Roc <3 Rust!\n", + true, + ) + } - // TODO fix QuicksortApp and then remove this! - match benchmark.filename { - "QuicksortApp.roc" => { - eprintln!("WARNING: skipping testing benchmark {} because the test is broken right now!", benchmark.filename); - return; - } - _ => {} - } + #[test] + fn platform_switching_zig() { + test_roc_app( + "crates/cli_testing_examples/platform-switching", + "rocLovesZig.roc", + "rocLovesZig", + &[], + &[], + "Roc <3 Zig!\n", + true, + ) + } - let mut ran_without_optimizations = false; + #[test] + fn platform_switching_wasm() { + test_roc_app( + "crates/cli_testing_examples/platform-switching", + "rocLovesWebAssembly.roc", + "rocLovesWebAssembly", + &[], + &[], + "Roc <3 Web Assembly!\n", + true, + ) + } - let mut app_args: Vec = vec![]; - for arg in benchmark.arguments { - match arg { - Arg::ExamplePath(file) => { - app_args.push(examples_dir("benchmarks").join(file).to_str().unwrap().to_string()); - } - Arg::PlainText(arg) => { - app_args.push(arg.to_string()); - } - } - } + #[test] + fn platform_switching_swift() { + test_roc_app( + "crates/cli_testing_examples/platform-switching", + "rocLovesSwift.roc", + "rocLovesSwift", + &[], + &[], + "Roc <3 Swift!\n", + true, + ) + } - BENCHMARKS_BUILD_PLATFORM.call_once( || { - // Check with and without optimizations - check_output_with_stdin( - &file_name, - benchmark.stdin, - benchmark.executable_filename, - &[], - &app_args, - benchmark.expected_ending, - benchmark.use_valgrind, - ); + #[test] + fn ruby_interop() { + test_roc_app( + "examples/ruby-interop", + "main.roc", + "libhello", + &[], + &[], + "", + true, + ) + } - ran_without_optimizations = true; - }); + #[test] + fn fibonacci() { + test_roc_app( + "crates/cli_testing_examples/algorithms", + "fibonacci.roc", + "fibonacci", + &[], + &[], + "", + true, + ) + } - // now we can pass the `PREBUILT_PLATFORM` flag, because the - // `call_once` will have built the platform + #[test] + fn hello_gui() { + test_roc_app( + "examples/gui", + "hello.roc", + "hello-gui", + &[], + &[], + "", + false, + ) + } - if !ran_without_optimizations { - // Check with and without optimizations - check_output_with_stdin( - &file_name, - benchmark.stdin, - benchmark.executable_filename, - &[PREBUILT_PLATFORM], - &app_args, - benchmark.expected_ending, - benchmark.use_valgrind, - ); - } + #[test] + fn breakout() { + test_roc_app( + "examples/gui/breakout", + "breakout.roc", + "breakout", + &[], + &[], + "", + false, + ) + } - check_output_with_stdin( - &file_name, - benchmark.stdin, - benchmark.executable_filename, - &[PREBUILT_PLATFORM, OPTIMIZE_FLAG], - &app_args, - benchmark.expected_ending, - benchmark.use_valgrind, - ); - } + #[test] + fn quicksort() { + test_roc_app( + "crates/cli_testing_examples/algorithms", + "quicksort.roc", + "quicksort", + &[], + &[], + "[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2]\n", + true, + ) + } - )* + #[test] + fn cli_args() { + test_roc_app( + "examples/cli", + "args.roc", + "args", + &[], + &[ + Arg::PlainText("log"), + Arg::PlainText("-b"), + Arg::PlainText("3"), + Arg::PlainText("--num"), + Arg::PlainText("81"), + ], + "4\n", + false, + ) + } + + #[test] + fn interactive_effects() { + test_roc_app( + "examples/cli", + "effects.roc", + "effects", + &["hi there!"], + &[], + "hi there!\nIt is known\n", + true, + ) + } + + #[test] + // tea = The Elm Architecture + fn terminal_ui_tea() { + test_roc_app( + "examples/cli", + "tui.roc", + "tui", + &["foo\n"], // NOTE: adding more lines leads to memory leaks + &[], + "Hello Worldfoo!\n", + true, + ) + } + + #[test] + fn false_interpreter() { + test_roc_app( + "examples/cli/false-interpreter", + "False.roc", + "false", + &[], + &[Arg::ExamplePath("examples/hello.false")], + "Hello, World!\n", + false, + ) + } + + #[test] + fn swift_ui() { + test_roc_app( + "examples/swiftui", + "main.roc", + "swiftui", + &[], + &[], + "", + false, + ) + } + + #[test] + fn static_site_gen() { + test_roc_app( + "examples/static-site-gen", + "static-site.roc", + "static-site", + &[], + &[Arg::ExamplePath("input"), Arg::ExamplePath("output")], + "Processed 3 files with 3 successes and 0 errors\n", + false, + ) + } + + // TODO not sure if this cfg should still be here: #[cfg(not(debug_assertions))] + // this is for testing the benchmarks, to perform proper benchmarks see crates/cli/benches/README.md + mod test_benchmarks { + use cli_utils::helpers::cli_testing_dir; + + use super::{check_output_with_stdin, OPTIMIZE_FLAG, PREBUILT_PLATFORM}; + + use std::{path::Path, sync::Once}; + + static BENCHMARKS_BUILD_PLATFORM: Once = Once::new(); + + fn test_benchmark( + roc_filename: &str, + executable_filename: &str, + stdin: &[&str], + expected_ending: &str, + use_valgrind: bool, + ) { + let file_name = cli_testing_dir("benchmarks").join(roc_filename); + + // TODO fix QuicksortApp and then remove this! + if roc_filename == "QuicksortApp.roc" { + eprintln!( + "WARNING: skipping testing benchmark {} because the test is broken right now!", + roc_filename + ); + return; + } + + #[cfg(all(not(feature = "wasm32-cli-run"), not(feature = "i386-cli-run")))] + check_output_regular( + &file_name, + stdin, + executable_filename, + expected_ending, + use_valgrind, + ); #[cfg(feature = "wasm32-cli-run")] - mod wasm32 { - use super::*; - $( - #[test] - #[cfg_attr(not(debug_assertions), serial(benchmark))] - fn $test_name() { - let benchmark = $benchmark; - let file_name = examples_dir("benchmarks").join(benchmark.filename); - - // TODO fix QuicksortApp and then remove this! - match benchmark.filename { - "QuicksortApp.roc" => { - eprintln!("WARNING: skipping testing benchmark {} because the test is broken right now!", benchmark.filename); - return; - } - _ => {} - } - - // Check with and without optimizations - check_wasm_output_with_stdin( - &file_name, - benchmark.stdin, - benchmark.executable_filename, - &[], - benchmark.input_paths.iter().map(|file| examples_dir("benchmarks").join(file)), - benchmark.expected_ending, - ); - - check_wasm_output_with_stdin( - &file_name, - benchmark.stdin, - benchmark.executable_filename, - &[OPTIMIZE_FLAG], - benchmark.input_paths.iter().map(|file| examples_dir("benchmarks").join(file)), - benchmark.expected_ending, - ); - } - )* - } + check_output_wasm(&file_name, stdin, executable_filename, expected_ending); #[cfg(feature = "i386-cli-run")] - mod i386 { - use super::*; - $( - #[test] - #[cfg_attr(not(debug_assertions), serial(benchmark))] - fn $test_name() { - let benchmark = $benchmark; - let file_name = examples_dir("benchmarks").join(benchmark.filename); - - // TODO fix QuicksortApp and then remove this! - match benchmark.filename { - "QuicksortApp.roc" => { - eprintln!("WARNING: skipping testing benchmark {} because the test is broken right now!", benchmark.filename); - return; - } - _ => {} - } - - // Check with and without optimizations - check_output_with_stdin( - &file_name, - benchmark.stdin, - benchmark.executable_filename, - [concatcp!(TARGET_FLAG, "=x86_32")], - benchmark.input_paths.iter().map(|file| Some(examples_dir("benchmarks").join(file))), - benchmark.expected_ending, - benchmark.use_valgrind, - ); - - check_output_with_stdin( - &file_name, - benchmark.stdin, - benchmark.executable_filename, - [concatcp!(TARGET_FLAG, "=x86_32"), OPTIMIZE_FLAG], - benchmark.input_paths.iter().map(|file| Some(examples_dir("benchmarks").join(file))), - benchmark.expected_ending, - benchmark.use_valgrind, - ); - } - )* - } - - #[test] - #[cfg(not(debug_assertions))] - fn all_benchmarks_have_tests() { - let mut all_benchmarks: MutMap<&str, Example<'_>> = MutMap::default(); - - $( - let benchmark = $benchmark; - - all_benchmarks.insert(benchmark.filename, benchmark); - )* - - check_for_benchmarks("../../crates/cli_testing_examples/benchmarks", &mut all_benchmarks); - } - } - } - - benchmarks! { - nqueens => Example { - filename: "NQueens.roc", - executable_filename: "nqueens", - stdin: &["6"], - arguments: &[], - expected_ending: "4\n", - use_valgrind: true, - }, - cfold => Example { - filename: "CFold.roc", - executable_filename: "cfold", - stdin: &["3"], - arguments: &[], - expected_ending: "11 & 11\n", - use_valgrind: true, - }, - deriv => Example { - filename: "Deriv.roc", - executable_filename: "deriv", - stdin: &["2"], - arguments: &[], - expected_ending: "1 count: 6\n2 count: 22\n", - use_valgrind: true, - }, - rbtree_ck => Example { - filename: "RBTreeCk.roc", - executable_filename: "rbtree-ck", - stdin: &["100"], - arguments: &[], - expected_ending: "10\n", - use_valgrind: true, - }, - rbtree_insert => Example { - filename: "RBTreeInsert.roc", - executable_filename: "rbtree-insert", - stdin: &[], - arguments: &[], - expected_ending: "Node Black 0 {} Empty Empty\n", - use_valgrind: true, - }, - // rbtree_del => Example { - // filename: "RBTreeDel.roc", - // executable_filename: "rbtree-del", - // stdin: &["420"], - // arguments: &[], - // expected_ending: "30\n", - // use_valgrind: true, - // }, - astar => Example { - filename: "TestAStar.roc", - executable_filename: "test-astar", - stdin: &[], - arguments: &[], - expected_ending: "True\n", - use_valgrind: false, - }, - base64 => Example { - filename: "TestBase64.roc", - executable_filename: "test-base64", - stdin: &[], - arguments: &[], - expected_ending: "encoded: SGVsbG8gV29ybGQ=\ndecoded: Hello World\n", - use_valgrind: true, - }, - closure => Example { - filename: "Closure.roc", - executable_filename: "closure", - stdin: &[], - arguments: &[], - expected_ending: "", - use_valgrind: false, - }, - issue2279 => Example { - filename: "Issue2279.roc", - executable_filename: "issue2279", - stdin: &[], - arguments: &[], - expected_ending: "Hello, world!\n", - use_valgrind: true, - }, - quicksort_app => Example { - filename: "QuicksortApp.roc", - executable_filename: "quicksortapp", - stdin: &[], - arguments: &[], - expected_ending: "todo put the correct quicksort answer here", - use_valgrind: true, - }, - } - - #[cfg(not(debug_assertions))] - fn check_for_tests(examples_dir: &str, all_examples: &mut MutMap<&str, Example<'_>>) { - let entries = std::fs::read_dir(examples_dir).unwrap_or_else(|err| { - panic!( - "Error trying to read {} as an examples directory: {}", - examples_dir, err + check_output_i386( + &file_name, + stdin, + executable_filename, + expected_ending, + use_valgrind, ); - }); - - for entry in entries { - let entry = entry.unwrap(); - - if entry.file_type().unwrap().is_dir() { - let example_dir_name = entry.file_name().into_string().unwrap(); - - // We test benchmarks separately - if example_dir_name != "benchmarks" { - all_examples.remove(example_dir_name.as_str()).unwrap_or_else(|| { - panic!("The example directory {}/{} does not have any corresponding tests in cli_run. Please add one, so if it ever stops working, we'll know about it right away!", examples_dir, example_dir_name); - }); - } - } } - assert_eq!(all_examples, &mut MutMap::default()); - } + #[cfg(all(not(feature = "wasm32-cli-run"), not(feature = "i386-cli-run")))] + fn check_output_regular( + file_name: &Path, + stdin: &[&str], + executable_filename: &str, + expected_ending: &str, + use_valgrind: bool, + ) { + let mut ran_without_optimizations = false; - #[cfg(not(debug_assertions))] - fn check_for_benchmarks(benchmarks_dir: &str, all_benchmarks: &mut MutMap<&str, Example<'_>>) { - use std::ffi::OsStr; - use std::fs::File; - use std::io::Read; + BENCHMARKS_BUILD_PLATFORM.call_once(|| { + // Check with and without optimizations + check_output_with_stdin( + file_name, + stdin, + executable_filename, + &[], + &[], + expected_ending, + use_valgrind, + ); - let entries = std::fs::read_dir(benchmarks_dir).unwrap_or_else(|err| { - panic!( - "Error trying to read {} as a benchmark directory: {}", - benchmarks_dir, err + ran_without_optimizations = true; + }); + + // now we can pass the `PREBUILT_PLATFORM` flag, because the + // `call_once` will have built the platform + + if !ran_without_optimizations { + // Check with and without optimizations + check_output_with_stdin( + file_name, + stdin, + executable_filename, + &[PREBUILT_PLATFORM], + &[], + expected_ending, + use_valgrind, + ); + } + + check_output_with_stdin( + file_name, + stdin, + executable_filename, + &[PREBUILT_PLATFORM, OPTIMIZE_FLAG], + &[], + expected_ending, + use_valgrind, ); - }); + } - for entry in entries { - let entry = entry.unwrap(); - let path = entry.path(); + #[cfg(feature = "wasm32-cli-run")] + fn check_output_wasm( + file_name: &Path, + stdin: &[&str], + executable_filename: &str, + expected_ending: &str, + ) { + // Check with and without optimizations + check_wasm_output_with_stdin( + file_name, + stdin, + executable_filename, + &[], + expected_ending, + ); - if let Some("roc") = path.extension().and_then(OsStr::to_str) { - let benchmark_file_name = entry.file_name().into_string().unwrap(); + check_wasm_output_with_stdin( + file_name, + stdin, + executable_filename, + &[OPTIMIZE_FLAG], + expected_ending, + ); + } - // Verify that this is an app module by reading the first 3 - // bytes of the file. - let buf: &mut [u8] = &mut [0, 0, 0]; - let mut file = File::open(path).unwrap(); + #[cfg(feature = "wasm32-cli-run")] + fn check_wasm_output_with_stdin( + file: &Path, + stdin: &[&str], + executable_filename: &str, + flags: &[&str], + expected_ending: &str, + ) { + let mut flags = flags.to_vec(); + flags.push(concatcp!(TARGET_FLAG, "=wasm32")); - file.read_exact(buf).unwrap(); + let compile_out = run_roc( + [CMD_BUILD, file.to_str().unwrap()] + .iter() + .chain(flags.as_slice()), + &[], + ); + if !compile_out.stderr.is_empty() { + panic!("{}", compile_out.stderr); + } - // Only app modules in this directory are considered benchmarks. - if "app".as_bytes() == buf && !benchmark_file_name.contains("RBTreeDel") { - all_benchmarks.remove(benchmark_file_name.as_str()).unwrap_or_else(|| { - panic!("The benchmark {}/{} does not have any corresponding tests in cli_run. Please add one, so if it ever stops working, we'll know about it right away!", benchmarks_dir, benchmark_file_name); - }); - } + assert!(compile_out.status.success(), "bad status {:?}", compile_out); + + let path = file.with_file_name(executable_filename); + let stdout = crate::run_with_wasmer(&path, stdin); + + if !stdout.ends_with(expected_ending) { + panic!( + "expected output to end with {:?} but instead got {:#?}", + expected_ending, stdout + ); } } - assert_eq!(all_benchmarks, &mut MutMap::default()); + #[cfg(feature = "i386-cli-run")] + fn check_output_i386( + file_name: &Path, + stdin: &[&str], + executable_filename: &str, + expected_ending: &str, + use_valgrind: bool, + ) { + check_output_with_stdin( + &file_name, + stdin, + executable_filename, + &[concatcp!(TARGET_FLAG, "=x86_32")], + &[], + expected_ending, + use_valgrind, + ); + + check_output_with_stdin( + &file_name, + stdin, + executable_filename, + &[concatcp!(TARGET_FLAG, "=x86_32"), OPTIMIZE_FLAG], + &[], + expected_ending, + use_valgrind, + ); + } + + #[test] + fn nqueens() { + test_benchmark("NQueens.roc", "nqueens", &["6"], "4\n", true) + } + + #[test] + fn cfold() { + test_benchmark("CFold.roc", "cfold", &["3"], "11 & 11\n", true) + } + + #[test] + fn deriv() { + test_benchmark( + "Deriv.roc", + "deriv", + &["2"], + "1 count: 6\n2 count: 22\n", + true, + ) + } + + #[test] + fn rbtree_ck() { + test_benchmark("RBTreeCk.roc", "rbtree-ck", &["100"], "10\n", true) + } + + #[test] + fn rbtree_insert() { + test_benchmark( + "RBTreeInsert.roc", + "rbtree-insert", + &[], + "Node Black 0 {} Empty Empty\n", + true, + ) + } + + /* + // rbtree_del does not work + #[test] + fn rbtree_del() { + test_benchmark( + "RBTreeDel.roc", + "rbtree-del", + &["420"], + &[], + "30\n", + true + ) + }*/ + + #[test] + fn astar() { + test_benchmark("TestAStar.roc", "test-astar", &[], "True\n", false) + } + + #[test] + fn base64() { + test_benchmark( + "TestBase64.roc", + "test-base64", + &[], + "encoded: SGVsbG8gV29ybGQ=\ndecoded: Hello World\n", + true, + ) + } + + #[test] + fn closure() { + test_benchmark("Closure.roc", "closure", &[], "", false) + } + + #[test] + fn issue2279() { + test_benchmark("Issue2279.roc", "issue2279", &[], "Hello, world!\n", true) + } + + #[test] + fn quicksort_app() { + test_benchmark( + "QuicksortApp.roc", + "quicksortapp", + &[], + "todo put the correct quicksort answer here", + true, + ) + } } #[test] @@ -1013,7 +900,7 @@ mod cli_run { &[], indoc!( r#" - ── TYPE MISMATCH ─ ...d/../../../../examples/interactive/cli-platform/main.roc ─ + ── TYPE MISMATCH ─ ...known_bad/../../../../examples/cli/cli-platform/main.roc ─ Something is off with the type annotation of the main required symbol: @@ -1034,7 +921,7 @@ mod cli_run { an instance of this opaque type by doing @Age 23. - ── TYPE MISMATCH ─ ...d/../../../../examples/interactive/cli-platform/main.roc ─ + ── TYPE MISMATCH ─ ...known_bad/../../../../examples/cli/cli-platform/main.roc ─ This 1st argument to toEffect has an unexpected type: diff --git a/crates/cli_testing_examples/platform-switching/rust-platform/Cargo.toml b/crates/cli_testing_examples/platform-switching/rust-platform/Cargo.toml index 8d10ce6eea..29083ca183 100644 --- a/crates/cli_testing_examples/platform-switching/rust-platform/Cargo.toml +++ b/crates/cli_testing_examples/platform-switching/rust-platform/Cargo.toml @@ -16,7 +16,7 @@ name = "host" path = "src/main.rs" [dependencies] -roc_std = { path = "../../../crates/roc_std" } +roc_std = { path = "../../../../crates/roc_std" } libc = "0.2" [workspace] diff --git a/crates/cli_utils/src/bench_utils.rs b/crates/cli_utils/src/bench_utils.rs index c9f971266d..9bcce31025 100644 --- a/crates/cli_utils/src/bench_utils.rs +++ b/crates/cli_utils/src/bench_utils.rs @@ -1,4 +1,4 @@ -use crate::helpers::{example_file, run_cmd, run_roc}; +use crate::helpers::{file_path_from_root, run_cmd, run_roc}; use criterion::{black_box, measurement::Measurement, BenchmarkGroup}; use std::{path::Path, thread}; @@ -109,7 +109,7 @@ fn bench_cmd( pub fn bench_nqueens(bench_group_opt: Option<&mut BenchmarkGroup>) { exec_bench_w_input( - &example_file("benchmarks", "NQueens.roc"), + &file_path_from_root("crates/cli_testing_examples/benchmarks", "NQueens.roc"), "11", "nqueens", "2680\n", //2680-14200 @@ -119,7 +119,7 @@ pub fn bench_nqueens(bench_group_opt: Option<&mut BenchmarkGroup pub fn bench_cfold(bench_group_opt: Option<&mut BenchmarkGroup>) { exec_bench_w_input( - &example_file("benchmarks", "CFold.roc"), + &file_path_from_root("crates/cli_testing_examples/benchmarks", "CFold.roc"), "17", "cfold", "396354 & 396354\n", @@ -129,7 +129,7 @@ pub fn bench_cfold(bench_group_opt: Option<&mut BenchmarkGroup(bench_group_opt: Option<&mut BenchmarkGroup>) { exec_bench_w_input( - &example_file("benchmarks", "Deriv.roc"), + &file_path_from_root("crates/cli_testing_examples/benchmarks", "Deriv.roc"), "8", "deriv", "1 count: 6\n2 count: 22\n3 count: 90\n4 count: 420\n5 count: 2202\n6 count: 12886\n7 count: 83648\n8 count: 598592\n", @@ -139,7 +139,7 @@ pub fn bench_deriv(bench_group_opt: Option<&mut BenchmarkGroup(bench_group_opt: Option<&mut BenchmarkGroup>) { exec_bench_w_input( - &example_file("benchmarks", "RBTreeCk.roc"), + &file_path_from_root("crates/cli_testing_examples/benchmarks", "RBTreeCk.roc"), "80000", "rbtree-ck", "8000\n", @@ -150,7 +150,7 @@ pub fn bench_rbtree_ck(bench_group_opt: Option<&mut BenchmarkGro #[allow(dead_code)] pub fn bench_rbtree_delete(bench_group_opt: Option<&mut BenchmarkGroup>) { exec_bench_w_input( - &example_file("benchmarks", "RBTreeDel.roc"), + &file_path_from_root("crates/cli_testing_examples/benchmarks", "RBTreeDel.roc"), "100000", "rbtree-del", "7000\n", @@ -160,7 +160,7 @@ pub fn bench_rbtree_delete(bench_group_opt: Option<&mut Benchmar pub fn bench_quicksort(bench_group_opt: Option<&mut BenchmarkGroup>) { exec_bench_w_input( - &example_file("benchmarks", "QuicksortApp.roc"), + &file_path_from_root("crates/cli_testing_examples/benchmarks", "QuicksortApp.roc"), "1", // 1 for sorting large list, 0 for a small list "quicksortapp", "[0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 18, 18, 19, 19, 19, 20, 21, 21, 21, 21, 22, 23, 23, 23, 25, 26, 27, 27, 28, 28, 28, 29, 29, 29, 29, 30, 31, 32, 33, 34, 35, 35, 35, 36, 36, 36, 37, 38, 38, 39, 39, 39, 39, 39, 39, 40, 40, 41, 42, 42, 42, 42, 42, 43, 43, 44, 46, 47, 47, 47, 48, 50, 51, 51, 52, 52, 52, 53, 54, 54, 55, 55, 55, 56, 57, 57, 58, 58, 58, 58, 58, 59, 59, 60, 60, 61, 62, 63, 63, 63, 63, 64, 65, 65, 65, 66, 66, 66, 66, 67, 67, 68, 69, 69, 70, 70, 71, 71, 71, 72, 72, 73, 73, 73, 74, 75, 75, 75, 76, 78, 79, 79, 80, 81, 81, 82, 82, 83, 83, 84, 84, 86, 86, 87, 87, 88, 88, 88, 89, 89, 90, 90, 90, 91, 92, 92, 92, 93, 93, 93, 94, 95, 95, 96, 97, 98, 99, 100, 100, 101, 102, 102, 102, 104, 104, 105, 106, 106, 106, 106, 106, 106, 107, 107, 108, 108, 108, 109, 109, 109, 109, 110, 112, 112, 112, 113, 113, 113, 113, 113, 114, 115, 117, 117, 117, 118, 119, 119, 119, 120, 120, 121, 123, 124, 125, 125, 126, 126, 126, 126, 127, 129, 131, 131, 131, 131, 131, 131, 131, 132, 133, 133, 134, 134, 134, 135, 135, 135, 135, 135, 137, 138, 138, 138, 139, 139, 140, 141, 142, 142, 142, 144, 144, 145, 145, 145, 147, 147, 147, 147, 148, 149, 149, 149, 150, 150, 151, 151, 151, 151, 153, 155, 156, 159, 160, 160, 160, 161, 161, 162, 162, 162, 162, 162, 162, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, 165, 165, 165, 165, 165, 166, 166, 166, 166, 166, 167, 167, 167, 167, 168, 169, 170, 170, 170, 170, 172, 172, 172, 173, 173, 173, 174, 175, 176, 177, 177, 178, 178, 178, 178, 179, 179, 180, 180, 181, 181, 182, 183, 183, 185, 186, 186, 186, 186, 186, 186, 186, 187, 187, 187, 188, 188, 188, 190, 190, 190, 190, 190, 192, 193, 194, 194, 194, 195, 195, 196, 197, 198, 198, 198, 199, 199, 199, 200, 200, 201, 201, 201, 204, 205, 205, 205, 207, 207, 207, 208, 208, 208, 208, 210, 210, 210, 210, 211, 211, 213, 214, 214, 214, 218, 218, 218, 218, 218, 218, 219, 221, 222, 223, 223, 223, 224, 224, 224, 224, 224, 224, 224, 225, 226, 226, 226, 226, 226, 227, 227, 228, 228, 229, 229, 229, 229, 230, 230, 230, 230, 232, 233, 233, 234, 235, 236, 236, 237, 237, 238, 240, 240, 242, 242, 243, 244, 246, 247, 247, 247, 247, 248, 248, 248, 249, 249, 249, 249, 249, 250, 250, 250, 251, 251, 252, 252, 253, 255, 255, 256, 256, 256, 257, 257, 257, 258, 258, 258, 258, 258, 259, 259, 260, 260, 260, 261, 261, 261, 262, 263, 265, 265, 266, 267, 267, 267, 268, 268, 268, 270, 270, 270, 271, 271, 273, 274, 274, 274, 275, 277, 277, 279, 279, 280, 281, 281, 282, 283, 283, 285, 286, 288, 288, 289, 289, 290, 290, 290, 290, 290, 291, 291, 291, 291, 292, 292, 292, 293, 294, 294, 295, 295, 295, 295, 295, 298, 298, 301, 301, 301, 302, 302, 303, 304, 305, 305, 306, 307, 307, 308, 308, 309, 309, 309, 309, 310, 310, 311, 311, 311, 312, 313, 313, 313, 314, 315, 316, 316, 316, 316, 317, 318, 318, 319, 319, 319, 320, 321, 321, 322, 322, 322, 322, 323, 323, 323, 324, 324, 324, 325, 326, 326, 328, 329, 329, 330, 330, 330, 331, 331, 331, 331, 332, 332, 333, 333, 333, 333, 334, 334, 334, 335, 336, 336, 337, 337, 337, 337, 339, 339, 340, 341, 341, 343, 344, 344, 345, 345, 345, 346, 346, 347, 348, 348, 348, 349, 350, 351, 351, 351, 352, 353, 354, 354, 354, 355, 356, 356, 357, 358, 358, 358, 359, 359, 360, 361, 361, 362, 362, 363, 364, 364, 365, 365, 365, 366, 366, 367, 367, 368, 368, 369, 369, 369, 370, 370, 370, 370, 370, 371, 372, 373, 373, 374, 374, 375, 375, 376, 377, 377, 378, 379, 381, 381, 383, 384, 385, 385, 385, 385, 386, 386, 387, 388, 388, 388, 389, 389, 390, 391, 391, 391, 392, 392, 393, 393, 394, 394, 394, 395, 395, 396, 396, 397, 397, 398, 399, 400, 400, 401, 401, 402, 402, 403, 404, 404, 405, 406, 406, 407, 407, 407, 408, 408, 408, 408, 408, 409, 409, 409, 411, 411, 412, 412, 413, 413, 413, 413, 413, 414, 414, 414, 415, 416, 416, 416, 416, 417, 417, 418, 418, 418, 418, 419, 420, 420, 420, 421, 421, 422, 422, 423, 423, 423, 424, 424, 424, 424, 425, 425, 425, 426, 426, 427, 427, 427, 428, 428, 429, 429, 429, 430, 430, 431, 432, 433, 433, 433, 434, 434, 434, 434, 437, 438, 438, 438, 438, 438, 439, 440, 441, 441, 442, 442, 443, 444, 444, 444, 445, 445, 445, 447, 447, 447, 448, 448, 449, 449, 450, 450, 450, 451, 452, 453, 453, 453, 453, 455, 455, 456, 456, 457, 458, 459, 459, 460, 460, 461, 461, 464, 465, 465, 465, 466, 466, 467, 467, 467, 467, 468, 469, 469, 470, 470, 471, 471, 471, 472, 473, 473, 473, 473, 474, 475, 475, 475, 476, 476, 476, 477, 477, 477, 478, 478, 479, 481, 481, 481, 482, 482, 482, 483, 483, 483, 484, 484, 485, 488, 488, 488, 488, 489, 490, 491, 491, 491, 492, 492, 493, 493, 493, 493, 493, 495, 495, 496, 496, 496, 496, 496, 496, 497, 497, 498, 498, 498, 498, 498, 499, 500, 500, 501, 501, 501, 502, 502, 502, 502, 503, 503, 503, 505, 505, 506, 507, 507, 507, 507, 508, 508, 510, 510, 510, 511, 511, 512, 512, 513, 513, 513, 513, 514, 514, 515, 516, 517, 518, 519, 519, 519, 520, 521, 521, 522, 522, 523, 523, 523, 525, 525, 526, 527, 527, 527, 528, 528, 528, 530, 531, 532, 532, 532, 532, 532, 535, 535, 537, 538, 538, 538, 540, 540, 540, 541, 541, 541, 541, 541, 542, 543, 543, 543, 543, 544, 544, 545, 545, 545, 546, 547, 547, 547, 548, 549, 549, 551, 552, 552, 553, 553, 553, 554, 554, 554, 555, 556, 557, 557, 557, 558, 558, 558, 559, 559, 559, 560, 560, 560, 561, 561, 561, 561, 562, 562, 562, 563, 563, 565, 566, 566, 567, 568, 569, 570, 570, 571, 571, 571, 571, 572, 572, 572, 574, 575, 576, 576, 577, 580, 581, 581, 582, 582, 582, 583, 583, 584, 585, 585, 585, 586, 587, 587, 588, 588, 588, 589, 591, 591, 591, 592, 592, 592, 593, 593, 593, 594, 594, 594, 594, 595, 595, 595, 596, 596, 596, 596, 596, 597, 597, 599, 599, 600, 600, 601, 601, 601, 602, 602, 603, 603, 604, 605, 605, 605, 606, 607, 608, 610, 612, 612, 613, 613, 614, 614, 615, 615, 615, 616, 616, 616, 617, 617, 619, 619, 619, 619, 620, 621, 621, 622, 624, 624, 624, 624, 625, 625, 628, 628, 628, 629, 629, 630, 630, 630, 630, 632, 633, 633, 634, 635, 638, 638, 639, 640, 641, 641, 643, 643, 644, 644, 644, 645, 645, 645, 646, 646, 646, 647, 647, 647, 647, 648, 648, 649, 650, 650, 650, 650, 650, 650, 651, 652, 652, 652, 653, 653, 653, 653, 654, 655, 655, 655, 655, 656, 657, 657, 657, 658, 658, 659, 659, 659, 659, 659, 660, 660, 661, 662, 663, 664, 665, 666, 666, 666, 667, 667, 667, 667, 667, 668, 668, 669, 670, 670, 670, 671, 672, 672, 672, 672, 672, 673, 673, 674, 674, 674, 675, 676, 676, 677, 678, 678, 679, 679, 680, 681, 681, 682, 683, 683, 684, 684, 685, 686, 686, 686, 686, 687, 687, 688, 690, 690, 691, 691, 693, 693, 694, 694, 697, 697, 698, 700, 701, 702, 702, 703, 703, 703, 704, 705, 706, 706, 707, 708, 708, 709, 709, 710, 710, 711, 712, 712, 712, 712, 712, 712, 713, 713, 714, 714, 716, 716, 716, 717, 717, 717, 718, 718, 718, 718, 719, 719, 719, 720, 720, 721, 721, 722, 723, 724, 725, 726, 726, 727, 729, 729, 729, 730, 730, 731, 731, 732, 732, 734, 734, 734, 735, 735, 736, 736, 736, 737, 737, 738, 739, 740, 740, 740, 741, 741, 742, 742, 742, 742, 744, 744, 744, 744, 745, 745, 745, 745, 746, 748, 749, 749, 749, 750, 750, 751, 751, 751, 752, 752, 753, 753, 754, 755, 756, 756, 756, 757, 757, 757, 757, 757, 761, 761, 762, 762, 762, 763, 763, 763, 763, 763, 764, 764, 764, 764, 765, 765, 766, 766, 766, 766, 767, 767, 767, 770, 770, 770, 770, 770, 771, 772, 772, 772, 773, 774, 775, 775, 775, 775, 776, 778, 778, 779, 779, 780, 780, 780, 781, 784, 784, 784, 786, 786, 786, 786, 787, 788, 789, 789, 789, 790, 791, 791, 792, 793, 793, 793, 794, 794, 795, 796, 797, 797, 798, 799, 799, 799, 800, 800, 800, 800, 801, 802, 802, 802, 802, 804, 806, 806, 806, 807, 807, 807, 807, 808, 809, 810, 810, 811, 812, 812, 812, 812, 812, 813, 813, 813, 814, 814, 814, 815, 816, 816, 817, 817, 817, 818, 818, 818, 819, 820, 820, 820, 820, 820, 821, 821, 823, 824, 824, 824, 825, 826, 826, 826, 826, 828, 828, 829, 829, 829, 829, 829, 830, 831, 831, 831, 831, 831, 832, 832, 833, 833, 833, 834, 834, 835, 835, 835, 835, 835, 836, 836, 836, 837, 839, 839, 839, 839, 839, 840, 840, 840, 841, 841, 842, 843, 844, 844, 844, 845, 845, 845, 845, 845, 846, 846, 846, 847, 847, 848, 848, 848, 849, 849, 850, 850, 851, 852, 852, 852, 852, 853, 855, 856, 857, 857, 858, 858, 858, 859, 860, 861, 861, 861, 861, 862, 863, 863, 863, 865, 865, 865, 866, 867, 867, 867, 868, 868, 870, 871, 872, 872, 873, 873, 873, 874, 874, 874, 875, 875, 875, 876, 877, 878, 878, 878, 878, 878, 879, 879, 879, 879, 880, 881, 881, 881, 882, 883, 885, 886, 886, 887, 887, 888, 888, 889, 889, 890, 890, 890, 892, 892, 892, 892, 893, 893, 894, 894, 894, 895, 896, 896, 896, 897, 899, 899, 900, 901, 901, 901, 901, 905, 905, 905, 905, 906, 907, 907, 907, 908, 908, 908, 908, 908, 908, 909, 909, 910, 910, 910, 912, 913, 913, 914, 914, 914, 915, 916, 916, 916, 916, 917, 917, 918, 919, 919, 919, 920, 920, 920, 920, 921, 921, 922, 923, 923, 923, 923, 923, 924, 925, 927, 927, 927, 928, 928, 929, 929, 929, 929, 930, 930, 931, 932, 932, 932, 933, 933, 934, 934, 935, 935, 936, 937, 937, 937, 939, 940, 940, 941, 941, 941, 941, 942, 942, 943, 943, 945, 946, 946, 946, 948, 949, 949, 951, 953, 953, 954, 954, 954, 954, 954, 955, 956, 956, 956, 957, 957, 957, 957, 959, 960, 960, 961, 961, 963, 963, 963, 964, 964, 964, 964, 965, 966, 967, 968, 969, 969, 970, 972, 972, 973, 973, 974, 975, 975, 975, 976, 977, 978, 978, 979, 979, 980, 980, 980, 980, 981, 982, 982, 984, 986, 986, 986, 986, 986, 987, 988, 988, 990, 990, 990, 990, 990, 991, 991, 991, 991, 991, 991, 992, 992, 992, 992, 992, 993, 993, 993, 993, 995, 996, 996, 996, 997, 997, 997, 997, 997, 998, 998, 998, 999, 999, 1000, 1001, 1001, 1002, 1003, 1003, 1004, 1004, 1004, 1006, 1007, 1007, 1007, 1008, 1008, 1008, 1009, 1010, 1010, 1011, 1011, 1012, 1012, 1012, 1013, 1013, 1013, 1014, 1014, 1014, 1016, 1016, 1016, 1017, 1017, 1017, 1018, 1018, 1018, 1019, 1019, 1020, 1020, 1021, 1021, 1021, 1022, 1023, 1023, 1023, 1024, 1024, 1024, 1025, 1026, 1026, 1027, 1028, 1028, 1028, 1028, 1029, 1029, 1029, 1030, 1031, 1031, 1032, 1033, 1034, 1034, 1035, 1035, 1036, 1038, 1039, 1039, 1040, 1040, 1040, 1040, 1040, 1040, 1042, 1042, 1043, 1043, 1043, 1043, 1044, 1045, 1045, 1045, 1045, 1047, 1047, 1048, 1048, 1049, 1049, 1050, 1050, 1051, 1051, 1053, 1053, 1053, 1054, 1054, 1055, 1055, 1056, 1056, 1057, 1057, 1058, 1058, 1058, 1058, 1059, 1059, 1059, 1061, 1061, 1061, 1061, 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1064, 1064, 1064, 1064, 1064, 1065, 1065, 1066, 1066, 1067, 1067, 1069, 1069, 1069, 1070, 1071, 1071, 1072, 1072, 1072, 1073, 1073, 1074, 1074, 1074, 1075, 1076, 1077, 1077, 1078, 1078, 1078, 1079, 1079, 1079, 1081, 1082, 1082, 1083, 1084, 1084, 1084, 1084, 1085, 1085, 1086, 1086, 1087, 1087, 1088, 1088, 1089, 1089, 1090, 1090, 1090, 1091, 1093, 1093, 1093, 1094, 1094, 1094, 1094, 1095, 1095, 1095, 1095, 1095, 1095, 1096, 1097, 1098, 1098, 1098, 1098, 1100, 1102, 1102, 1103, 1103, 1103, 1104, 1104, 1105, 1105, 1105, 1105, 1106, 1106, 1106, 1106, 1107, 1107, 1107, 1108, 1110, 1111, 1111, 1112, 1113, 1113, 1113, 1113, 1115, 1115, 1115, 1115, 1115, 1116, 1116, 1117, 1117, 1119, 1119, 1119, 1121, 1122, 1122, 1122, 1122, 1123, 1124, 1124, 1125, 1125, 1127, 1127, 1127, 1128, 1129, 1129, 1129, 1130, 1130, 1131, 1131, 1132, 1132, 1132, 1132, 1134, 1135, 1137, 1137, 1138, 1138, 1138, 1138, 1139, 1140, 1140, 1140, 1140, 1142, 1142, 1142, 1142, 1142, 1142, 1143, 1143, 1145, 1145, 1148, 1148, 1150, 1150, 1151, 1151, 1151, 1152, 1152, 1152, 1153, 1153, 1154, 1155, 1156, 1156, 1156, 1156, 1157, 1158, 1158, 1158, 1159, 1159, 1159, 1160, 1160, 1161, 1161, 1161, 1162, 1162, 1163, 1163, 1163, 1164, 1164, 1165, 1165, 1167, 1167, 1167, 1168, 1168, 1168, 1169, 1170, 1170, 1171, 1171, 1171, 1172, 1172, 1172, 1173, 1173, 1173, 1174, 1174, 1174, 1174, 1176, 1176, 1176, 1176, 1176, 1177, 1178, 1178, 1178, 1179, 1179, 1179, 1180, 1180, 1181, 1181, 1182, 1182, 1182, 1183, 1183, 1184, 1184, 1184, 1184, 1184, 1185, 1186, 1186, 1188, 1188, 1189, 1189, 1190, 1190, 1191, 1191, 1191, 1192, 1192, 1193, 1193, 1195, 1197, 1197, 1198, 1198, 1198, 1199, 1199, 1199, 1200, 1201, 1201, 1201, 1202, 1202, 1202, 1202, 1204, 1204, 1205, 1205, 1205, 1205, 1205, 1206, 1206, 1206, 1207, 1207, 1207, 1207, 1207, 1207, 1209, 1210, 1210, 1211, 1212, 1213, 1213, 1214, 1214, 1215, 1215, 1216, 1216, 1217, 1217, 1217, 1219, 1219, 1219, 1219, 1220, 1220, 1222, 1222, 1223, 1224, 1224, 1225, 1225, 1226, 1226, 1226, 1227, 1227, 1227, 1227, 1227, 1227, 1228, 1228, 1228, 1229, 1230, 1230, 1232, 1232, 1232, 1232, 1232, 1232, 1233, 1234, 1235, 1235, 1235, 1236, 1237, 1238, 1239, 1240, 1240, 1240, 1240, 1240, 1240, 1241, 1241, 1242, 1243, 1243, 1243, 1243, 1244, 1244, 1246, 1246, 1247, 1247, 1249, 1250, 1251, 1251, 1252, 1252, 1252, 1252, 1252, 1252, 1253, 1253, 1253, 1253, 1254, 1254, 1255, 1256, 1257, 1257, 1257, 1259, 1259, 1261, 1261, 1262, 1263, 1263, 1264, 1265, 1265, 1265, 1266, 1266, 1268, 1268, 1269, 1270, 1270, 1270, 1270, 1271, 1271, 1271, 1271, 1272, 1272, 1273, 1273, 1274, 1274, 1274, 1274, 1275, 1275, 1275, 1275, 1276, 1276, 1276, 1276, 1276, 1277, 1278, 1279, 1279, 1280, 1280, 1281, 1282, 1282, 1283, 1283, 1284, 1284, 1284, 1286, 1286, 1289, 1290, 1290, 1290, 1291, 1292, 1292, 1293, 1293, 1294, 1296, 1296, 1296, 1296, 1297, 1297, 1297, 1298, 1299, 1300, 1300, 1301, 1302, 1303, 1304, 1304, 1305, 1305, 1306, 1306, 1307, 1307, 1307, 1307, 1307, 1308, 1308, 1308, 1308, 1309, 1309, 1310, 1311, 1312, 1312, 1313, 1313, 1313, 1314, 1315, 1316, 1316, 1316, 1317, 1319, 1320, 1320, 1320, 1320, 1321, 1322, 1322, 1323, 1323, 1323, 1324, 1324, 1325, 1327, 1328, 1329, 1329, 1330, 1330, 1330, 1330, 1332, 1332, 1332, 1333, 1333, 1334, 1335, 1335, 1336, 1336, 1336, 1338, 1338, 1338, 1339, 1339, 1340, 1340, 1340, 1341, 1341, 1341, 1342, 1343, 1343, 1345, 1345, 1345, 1346, 1346, 1346, 1346, 1346, 1346, 1347, 1348, 1349, 1349, 1349, 1349, 1351, 1352, 1353, 1353, 1353, 1354, 1354, 1355, 1355, 1356, 1356, 1356, 1356, 1358, 1358, 1359, 1359, 1359, 1359, 1359, 1360, 1360, 1360, 1361, 1361, 1361, 1362, 1362, 1363, 1363, 1363, 1365, 1365, 1366, 1367, 1367, 1370, 1371, 1371, 1372, 1372, 1373, 1373, 1373, 1374, 1375, 1375, 1375, 1377, 1377, 1378, 1378, 1378, 1380, 1380, 1381, 1381, 1381, 1382, 1382, 1382, 1382, 1382, 1382, 1383, 1383, 1383, 1384, 1384, 1384, 1385, 1385, 1385, 1385, 1386, 1386, 1387, 1387, 1388, 1388, 1388, 1389, 1389, 1389, 1392, 1393, 1393, 1394, 1394, 1395, 1395, 1395, 1396, 1397, 1398, 1398, 1398, 1399, 1399, 1399, 1400, 1401, 1402, 1402, 1402, 1403, 1404, 1405, 1406, 1406, 1406, 1406, 1407, 1407, 1407, 1407, 1409, 1409, 1409, 1410, 1410, 1410, 1410, 1410, 1411, 1411, 1412, 1413, 1413, 1413, 1414, 1414, 1415, 1415, 1415, 1416, 1416, 1416, 1417, 1417, 1417, 1417, 1417, 1419, 1420, 1420, 1420, 1421, 1422, 1422, 1422, 1422, 1425, 1426, 1427, 1427, 1428, 1428, 1430, 1431, 1431, 1432, 1432, 1432, 1433, 1433, 1434, 1434, 1434, 1434, 1434, 1435, 1436, 1436, 1436, 1436, 1436, 1437, 1438, 1438, 1438, 1438, 1439, 1439, 1440, 1440, 1440, 1440, 1441, 1441, 1442, 1443, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1444, 1445, 1446, 1446, 1446, 1447, 1448, 1449, 1449, 1450, 1450, 1450, 1451, 1451, 1452, 1452, 1452, 1453, 1454, 1455, 1456, 1458, 1459, 1459, 1459, 1459, 1460, 1460, 1461, 1461, 1461, 1462, 1462, 1462, 1462, 1462, 1462, 1463, 1463, 1465, 1465, 1465, 1466, 1467, 1468, 1469, 1470, 1472, 1472, 1473, 1474, 1474, 1474, 1474, 1475, 1476, 1477, 1477, 1477, 1477, 1478, 1478, 1480, 1481, 1481, 1481, 1481, 1481, 1481, 1482, 1482, 1482, 1483, 1484, 1485, 1485, 1486, 1486, 1486, 1488, 1488, 1489, 1489, 1489, 1491, 1491, 1492, 1492, 1493, 1495, 1495, 1495, 1496, 1496, 1497, 1497, 1497, 1497, 1497, 1498, 1498, 1499, 1500, 1500, 1501, 1501, 1501, 1501, 1502, 1503, 1503, 1503, 1503, 1503, 1503, 1504, 1505, 1505, 1505, 1506, 1506, 1506, 1506, 1509, 1509, 1509, 1510, 1510, 1511, 1511, 1511, 1511, 1512, 1513, 1513, 1513, 1514, 1514, 1515, 1516, 1516, 1517, 1517, 1518, 1518, 1519, 1519, 1520, 1521, 1522, 1522, 1524, 1525, 1525, 1525, 1525, 1526, 1526, 1526, 1526, 1526, 1526, 1528, 1528, 1528, 1529, 1532, 1532, 1532, 1534, 1534, 1535, 1536, 1536, 1536, 1537, 1537, 1538, 1538, 1538, 1539, 1539, 1539, 1539, 1540, 1541, 1542, 1542, 1543, 1544, 1544, 1544, 1545, 1545, 1545, 1546, 1547, 1547, 1547, 1547, 1547, 1548, 1550, 1551, 1551, 1551, 1551, 1552, 1552, 1552, 1552, 1553, 1554, 1554, 1554, 1555, 1555, 1555, 1555, 1556, 1556, 1557, 1558, 1559, 1559, 1559, 1560, 1560, 1560, 1560, 1561, 1561, 1562, 1562, 1563, 1564, 1564, 1565, 1565, 1565, 1566, 1567, 1567, 1568, 1568, 1569, 1569, 1570, 1570, 1570, 1571, 1571, 1571, 1571, 1572, 1572, 1572, 1573, 1573, 1573, 1573, 1574, 1574, 1575, 1575, 1575, 1575, 1575, 1576, 1576, 1576, 1576, 1576, 1578, 1578, 1578, 1579, 1579, 1579, 1580, 1581, 1581, 1581, 1581, 1581, 1582, 1582, 1582, 1582, 1583, 1583, 1586, 1586, 1586, 1586, 1586, 1587, 1588, 1589, 1590, 1591, 1591, 1591, 1594, 1595, 1595, 1595, 1596, 1598, 1598, 1599, 1600, 1600, 1601, 1601, 1601, 1602, 1602, 1602, 1603, 1603, 1605, 1605, 1606, 1607, 1608, 1608, 1608, 1609, 1609, 1609, 1609, 1611, 1611, 1612, 1612, 1612, 1612, 1612, 1612, 1614, 1615, 1615, 1615, 1615, 1616, 1618, 1618, 1619, 1620, 1621, 1621, 1621, 1622, 1623, 1623, 1624, 1624, 1624, 1624, 1625, 1625, 1625, 1626, 1626, 1627, 1627, 1627, 1629, 1629, 1630, 1630, 1631, 1631, 1634, 1634, 1634, 1634, 1634, 1634, 1635, 1636, 1639, 1639, 1640, 1641, 1641, 1641, 1642, 1642, 1643, 1645, 1645, 1645, 1646, 1647, 1647, 1647, 1648, 1649, 1649, 1649, 1649, 1649, 1651, 1652, 1653, 1653, 1655, 1655, 1655, 1655, 1655, 1655, 1657, 1657, 1657, 1658, 1658, 1659, 1659, 1659, 1659, 1660, 1660, 1660, 1660, 1662, 1663, 1663, 1664, 1664, 1666, 1666, 1666, 1666, 1668, 1669, 1669, 1669, 1671, 1671, 1672, 1672, 1673, 1673, 1673, 1673, 1674, 1674, 1675, 1675, 1675, 1677, 1677, 1677, 1677, 1678, 1678, 1678, 1679, 1679, 1679, 1679, 1680, 1680, 1680, 1681, 1681, 1681, 1682, 1682, 1682, 1683, 1683, 1683, 1684, 1684, 1684, 1685, 1685, 1686, 1687, 1688, 1688, 1688, 1689, 1689, 1691, 1691, 1691, 1692, 1693, 1693, 1693, 1696, 1697, 1697, 1698, 1699, 1700, 1700, 1701, 1702, 1703, 1703, 1705, 1705, 1705, 1707, 1708, 1708, 1708, 1709, 1711, 1712, 1712, 1712, 1714, 1714, 1714, 1714, 1715, 1716, 1716, 1717, 1718, 1718, 1719, 1719, 1719, 1720, 1720, 1720, 1721, 1721, 1722, 1722, 1722, 1722, 1722, 1723, 1723, 1724, 1724, 1725, 1726, 1726, 1727, 1727, 1728, 1728, 1730, 1731, 1731, 1734, 1735, 1735, 1735, 1736, 1737, 1737, 1738, 1738, 1738, 1739, 1739, 1739, 1739, 1739, 1740, 1740, 1740, 1740, 1740, 1741, 1741, 1741, 1741, 1741, 1742, 1743, 1744, 1744, 1744, 1745, 1746, 1746, 1747, 1748, 1749, 1749, 1749, 1749, 1751, 1751, 1751, 1752, 1752, 1752, 1752, 1753, 1754, 1755, 1755, 1755, 1756, 1756, 1757, 1757, 1757, 1757, 1758, 1759, 1759, 1759, 1760, 1760, 1762, 1764, 1766, 1766, 1767, 1767, 1768, 1769, 1769, 1770, 1770, 1770, 1771, 1772, 1773, 1774, 1775, 1775, 1775, 1776, 1776, 1776, 1777, 1777, 1778, 1778, 1779, 1779, 1780, 1780, 1781, 1782, 1784, 1784, 1784, 1785, 1785, 1785, 1785, 1787, 1788, 1789, 1789, 1789, 1790, 1790, 1790, 1791, 1791, 1791, 1791, 1791, 1792, 1792, 1793, 1793, 1793, 1793, 1794, 1794, 1795, 1795, 1796, 1796, 1797, 1797, 1798, 1798, 1798, 1799, 1799, 1800, 1800, 1800, 1801, 1801, 1802, 1802, 1804, 1804, 1804, 1806, 1806, 1808, 1809, 1810, 1810, 1811, 1811, 1814, 1814, 1814, 1815, 1815, 1816, 1816, 1816, 1816, 1817, 1817, 1818, 1819, 1819, 1819, 1820, 1820, 1820, 1821, 1821, 1822, 1823, 1823, 1824, 1824, 1824, 1825, 1825, 1825, 1826, 1826, 1826, 1827, 1827, 1827, 1828, 1828, 1830, 1831, 1832, 1832, 1832, 1832, 1833, 1833, 1833, 1833, 1835, 1837, 1838, 1839, 1840, 1840, 1840, 1840, 1840, 1840, 1841, 1842, 1842, 1843, 1843, 1844, 1844, 1844, 1844, 1844, 1845, 1846, 1847, 1847, 1847, 1848, 1849, 1849, 1849, 1850, 1850, 1850, 1851, 1851, 1851, 1852, 1852, 1853, 1853, 1853, 1854, 1854, 1855, 1855, 1855, 1855, 1855, 1855, 1856, 1856, 1856, 1856, 1857, 1857, 1857, 1857, 1858, 1859, 1859, 1860, 1860, 1860, 1860, 1861, 1861, 1863, 1863, 1865, 1865, 1866, 1866, 1866, 1866, 1866, 1867, 1867, 1867, 1867, 1867, 1868, 1869, 1869, 1869, 1869, 1869, 1869, 1870, 1870, 1870, 1870, 1871, 1872, 1873, 1874, 1875, 1875, 1876, 1876, 1876, 1876, 1877, 1877, 1878, 1878, 1878, 1879, 1879, 1880, 1880, 1880, 1881, 1881, 1883, 1883, 1885, 1885, 1885, 1885, 1885, 1885, 1886, 1886, 1886, 1887, 1887, 1887, 1887, 1888, 1888, 1890, 1891, 1891, 1891, 1892, 1894, 1894, 1894, 1894, 1896, 1896, 1896, 1896, 1897, 1899, 1899, 1900, 1900, 1901, 1901, 1902, 1903, 1904, 1905, 1905, 1905, 1906, 1906, 1906, 1907, 1907, 1908, 1908, 1909, 1910, 1910, 1911, 1912, 1912, 1912, 1913, 1914, 1914, 1914, 1915, 1915, 1915, 1916, 1916, 1916, 1917, 1918, 1918, 1919, 1919, 1920, 1920, 1920, 1920, 1921, 1921, 1922, 1923, 1925, 1925, 1925, 1925, 1926, 1928, 1929, 1929, 1930, 1930, 1931, 1931, 1931, 1931, 1932, 1932, 1932, 1932, 1932, 1933, 1933, 1933, 1933, 1934, 1934, 1934, 1934, 1934, 1935, 1935, 1935, 1936, 1937, 1938, 1938, 1938, 1938, 1940, 1941, 1941, 1941, 1942, 1942, 1943, 1943, 1944, 1944, 1944, 1944, 1945, 1946, 1946, 1947, 1948, 1948, 1948, 1949, 1949, 1949, 1949, 1949, 1950, 1950, 1950, 1951, 1951, 1951, 1951, 1951, 1952, 1953, 1955, 1955, 1956, 1956, 1956, 1957, 1957, 1957, 1958, 1958, 1960, 1960, 1960, 1960, 1961, 1963, 1965, 1965, 1965, 1967, 1967, 1968, 1968, 1969, 1969, 1969, 1969, 1970, 1970, 1971, 1971, 1971, 1972, 1972, 1973, 1973, 1973, 1973, 1973, 1974, 1974, 1975, 1975, 1976, 1976, 1976, 1976, 1977, 1978, 1978, 1979, 1979, 1979, 1980, 1980, 1981, 1981, 1982, 1982, 1982, 1983, 1983, 1983, 1984, 1984, 1986, 1986, 1987, 1989, 1989, 1989, 1989, 1989, 1990, 1990, 1990, 1991, 1991, 1991, 1991, 1992, 1992, 1994, 1994, 1994, 1995, 1995, 1995, 1995, 1995, 1996, 1996, 1996, 1997, 1997, 1998, 1998, 1998, 1998, 1999, 1999, 2000, 2000, 2002, 2003, 2003, 2005, 2009, 2010, 2010, 2011, 2012, 2013, 2014, 2014, 2015, 2016, 2016, 2016, 2016, 2016, 2017, 2018, 2019, 2020, 2020, 2021, 2021, 2021, 2021, 2024, 2026, 2027, 2027, 2028, 2028, 2029, 2029, 2030, 2031, 2032, 2032, 2033, 2034, 2035, 2035, 2036, 2036, 2036, 2036, 2036, 2037, 2037, 2037, 2037, 2038, 2038, 2039, 2039, 2039, 2040, 2041, 2041, 2042, 2042, 2042, 2042, 2042, 2042, 2042, 2043, 2044, 2044, 2045, 2045, 2045, 2046, 2047, 2047, 2048, 2048, 2049, 2051, 2051, 2052, 2052, 2054, 2054, 2054, 2054, 2055, 2056, 2056, 2057, 2058, 2058, 2059, 2059, 2062, 2063, 2063, 2063, 2063, 2063, 2063, 2064, 2064, 2065, 2065, 2065, 2065, 2066, 2066, 2067, 2067, 2068, 2068, 2068, 2068, 2068, 2069, 2070, 2070, 2071, 2071, 2071, 2072, 2073, 2073, 2073, 2075, 2075, 2075, 2076, 2077, 2077, 2078, 2078, 2079, 2079, 2079, 2079, 2080, 2080, 2080, 2081, 2082, 2082, 2082, 2082, 2083, 2083, 2083, 2084, 2084, 2084, 2085, 2085, 2086, 2086, 2086, 2087, 2087, 2087, 2088, 2088, 2088, 2088, 2088, 2089, 2089, 2089, 2089, 2089, 2089, 2089, 2090, 2091, 2091, 2091, 2091, 2092, 2093, 2093, 2094, 2094, 2095, 2096, 2096, 2097, 2097, 2097, 2097, 2098, 2098, 2098, 2098, 2099, 2100, 2102, 2102, 2102, 2102, 2102, 2104, 2104, 2104, 2105, 2105, 2106, 2106, 2107, 2108, 2109, 2109, 2110, 2110, 2111, 2111, 2112, 2114, 2115, 2115, 2116, 2117, 2117, 2118, 2119, 2119, 2119, 2120, 2121, 2121, 2121, 2122, 2122, 2122, 2123, 2124, 2124, 2125, 2125, 2125, 2125, 2127, 2127, 2127, 2127, 2128, 2128, 2128, 2128, 2128, 2129, 2129, 2130, 2131, 2131, 2131, 2132, 2132, 2132, 2133, 2133, 2133, 2133, 2133, 2133, 2133, 2133, 2134, 2135, 2136, 2137, 2137, 2137, 2138, 2138, 2139, 2140, 2140, 2140, 2140, 2142, 2143, 2144, 2144, 2145, 2145, 2145, 2145, 2146, 2146, 2146, 2147, 2147, 2147, 2147, 2147, 2148, 2148, 2148, 2148, 2149, 2149, 2149, 2150, 2151, 2151, 2153, 2153, 2153, 2153, 2154, 2154, 2154, 2155, 2155, 2156, 2157, 2157, 2157, 2157, 2158, 2158, 2158, 2158, 2158, 2159, 2159, 2160, 2160, 2160, 2160, 2161, 2162, 2162, 2162, 2162, 2162, 2163, 2164, 2164, 2167, 2168, 2169, 2169, 2169, 2170, 2172, 2172, 2172, 2172, 2172, 2173, 2173, 2174, 2174, 2175, 2175, 2176, 2176, 2176, 2176, 2177, 2177, 2179, 2179, 2180, 2180, 2180, 2183, 2183, 2183, 2183, 2184, 2185, 2185, 2185, 2185, 2186, 2186, 2186, 2187, 2187, 2188, 2189, 2189, 2189, 2190, 2190, 2191, 2191, 2191, 2191, 2191, 2192, 2193, 2194, 2194, 2195, 2195, 2195, 2195, 2196, 2196, 2197, 2197, 2197, 2198, 2198, 2198, 2199, 2199, 2199, 2200, 2200, 2201, 2201, 2202, 2202, 2202, 2203, 2203, 2204, 2205, 2205, 2205, 2205, 2205, 2206, 2206, 2206, 2207, 2207, 2207, 2210, 2210, 2212, 2213, 2214, 2214, 2215, 2216, 2216, 2216, 2217, 2217, 2219, 2219, 2219, 2219, 2220, 2220, 2221, 2221, 2222, 2222, 2223, 2223, 2224, 2224, 2225, 2225, 2226, 2226, 2226, 2226, 2227, 2228, 2228, 2228, 2229, 2229, 2229, 2230, 2230, 2231, 2231, 2232, 2232, 2232, 2234, 2234, 2234, 2235, 2235, 2236, 2237, 2237, 2238, 2238, 2239, 2239, 2239, 2240, 2240, 2241, 2241, 2241, 2242, 2244, 2244, 2245, 2245, 2245, 2245, 2246, 2248, 2249, 2250, 2251, 2251, 2251, 2251, 2252, 2252, 2253, 2254, 2254, 2255, 2256, 2256, 2256, 2258, 2258, 2258, 2259, 2259, 2259, 2259, 2260, 2260, 2261, 2261, 2262, 2262, 2262, 2263, 2265, 2265, 2265, 2265, 2266, 2266, 2267, 2268, 2269, 2269, 2270, 2270, 2271, 2271, 2272, 2273, 2273, 2273, 2275, 2275, 2276, 2276, 2277, 2277, 2278, 2278, 2280, 2280, 2281, 2282, 2282, 2282, 2282, 2284, 2284, 2284, 2284, 2285, 2285, 2286, 2287, 2287, 2288, 2288, 2289, 2291, 2292, 2292, 2293, 2294, 2295, 2296, 2296, 2297, 2298, 2298, 2299, 2299, 2299, 2300, 2300, 2301, 2301, 2301, 2302, 2302, 2302, 2302, 2303, 2303, 2303, 2304, 2304, 2306, 2306, 2307, 2307, 2307, 2307, 2309, 2309, 2309, 2310, 2310, 2310, 2310, 2311, 2311, 2311, 2312, 2312, 2312, 2313, 2313, 2316, 2317, 2317, 2317, 2317, 2317, 2317, 2317, 2318, 2318, 2319, 2319, 2319, 2320, 2322, 2323, 2323, 2324, 2324, 2324, 2325, 2326, 2327, 2327, 2328, 2329, 2330, 2331, 2332, 2333, 2333, 2334, 2334, 2336, 2336, 2337, 2337, 2338, 2338, 2339, 2339, 2339, 2340, 2340, 2340, 2341, 2342, 2343, 2344, 2345, 2345, 2345, 2345, 2346, 2346, 2347, 2347, 2347, 2347, 2349, 2349, 2349, 2350, 2350, 2351, 2351, 2351, 2351, 2352, 2352, 2353, 2354, 2355, 2356, 2356, 2358, 2359, 2360, 2361, 2362, 2362, 2362, 2363, 2363, 2363, 2364, 2365, 2365, 2365, 2365, 2366, 2367, 2367, 2367, 2367, 2368, 2370, 2370, 2370, 2372, 2372, 2372, 2372, 2372, 2373, 2373, 2373, 2374, 2374, 2375, 2375, 2375, 2376, 2376, 2377, 2377, 2377, 2377, 2378, 2379, 2379, 2380, 2380, 2380, 2381, 2382, 2382, 2382, 2382, 2384, 2384, 2384, 2385, 2387, 2387, 2387, 2388, 2389, 2389, 2389, 2389, 2389, 2390, 2391, 2391, 2392, 2392, 2392, 2394, 2394, 2395, 2395, 2395, 2396, 2396, 2397, 2397, 2397, 2397, 2398, 2398, 2398, 2399, 2400, 2401, 2402, 2404, 2404, 2405, 2405, 2405, 2407, 2408, 2409, 2409, 2409, 2409, 2410, 2410, 2410, 2410, 2410, 2410, 2410, 2411, 2411, 2412, 2412, 2414, 2414, 2415, 2415, 2416, 2416, 2417, 2417, 2418, 2418, 2420, 2421, 2422, 2424, 2424, 2424, 2425, 2425, 2426, 2426, 2426, 2426, 2427, 2427, 2427, 2427, 2427, 2428, 2430, 2432, 2432, 2432, 2432, 2433, 2433, 2433, 2433, 2433, 2434, 2435, 2435, 2435, 2435, 2436, 2437, 2437, 2437, 2437, 2438, 2438, 2439, 2439, 2439, 2440, 2440, 2441, 2441, 2441, 2442, 2443, 2443, 2444, 2444, 2444, 2444, 2447, 2447, 2448, 2448, 2448, 2449, 2449, 2449, 2450, 2451, 2451, 2451, 2453, 2453, 2454, 2454, 2454, 2454, 2455, 2456, 2456, 2457, 2457, 2457, 2458, 2458, 2458, 2459, 2459, 2459, 2459, 2460, 2460, 2461, 2461, 2462, 2463, 2463, 2463, 2463, 2464, 2464, 2464, 2464, 2464, 2465, 2465, 2465, 2466, 2467, 2467, 2467, 2467, 2469, 2470, 2471, 2471, 2472, 2472, 2473, 2473, 2473, 2474, 2474, 2474, 2474, 2475, 2475, 2476, 2476, 2477, 2478, 2479, 2482, 2482, 2483, 2483, 2485, 2485, 2485, 2485, 2486, 2487, 2488, 2489, 2489, 2490, 2490, 2491, 2491, 2491, 2493, 2494, 2494, 2495, 2495, 2495, 2495, 2495, 2495, 2496, 2496, 2496, 2496, 2497, 2497, 2497, 2498, 2498, 2499, 2501, 2502, 2503, 2504, 2504, 2505, 2506, 2506, 2507, 2508, 2508, 2508, 2509, 2509, 2513, 2513, 2513, 2513, 2514, 2514, 2515, 2515, 2516, 2516, 2516, 2518, 2518, 2519, 2519, 2519, 2519, 2520, 2520, 2520, 2520, 2521, 2521, 2521, 2522, 2523, 2523, 2523, 2524, 2524, 2524, 2524, 2525, 2525, 2527, 2527, 2527, 2527, 2527, 2528, 2528, 2529, 2531, 2531, 2532, 2532, 2532, 2533, 2534, 2534, 2535, 2535, 2535, 2536, 2537, 2537, 2537, 2538, 2538, 2539, 2539, 2539, 2539, 2539, 2541, 2541, 2541, 2542, 2542, 2543, 2544, 2544, 2544, 2544, 2545, 2545, 2545, 2546, 2546, 2546, 2546, 2547, 2547, 2547, 2548, 2548, 2548, 2550, 2550, 2550, 2550, 2550, 2551, 2552, 2552, 2553, 2554, 2554, 2554, 2555, 2555, 2556, 2556, 2557, 2557, 2557, 2558, 2560, 2561, 2561, 2561, 2561, 2562, 2563, 2563, 2564, 2564, 2564, 2566, 2566, 2566, 2566, 2566, 2566, 2567, 2567, 2567, 2568, 2569, 2569, 2569, 2571, 2572, 2573, 2573, 2574, 2574, 2576, 2576, 2577, 2577, 2578, 2580, 2580, 2581, 2581, 2581, 2581, 2584, 2584, 2585, 2586, 2587, 2587, 2588, 2588, 2588, 2589, 2589, 2590, 2590, 2591, 2591, 2591, 2592, 2592, 2592, 2593, 2593, 2593, 2594, 2594, 2594, 2596, 2596, 2597, 2598, 2599, 2599, 2599, 2600, 2601, 2601, 2602, 2603, 2603, 2604, 2604, 2604, 2605, 2607, 2608, 2608, 2609, 2609, 2609, 2609, 2611, 2611, 2612, 2612, 2613, 2613, 2613, 2613, 2613, 2614, 2614, 2615, 2615, 2615, 2615, 2615, 2616, 2616, 2617, 2617, 2617, 2618, 2619, 2619, 2620, 2621, 2622, 2622, 2622, 2623, 2624, 2625, 2627, 2628, 2628, 2628, 2628, 2629, 2630, 2630, 2630, 2630, 2631, 2632, 2632, 2632, 2632, 2633, 2633, 2633, 2633, 2633, 2634, 2634, 2635, 2636, 2636, 2636, 2636, 2637, 2637, 2637, 2637, 2637, 2638, 2638, 2638, 2638, 2640, 2640, 2644, 2646, 2646, 2647, 2648, 2649, 2650, 2650, 2650, 2651, 2651, 2651, 2651, 2652, 2652, 2653, 2654, 2654, 2654, 2654, 2655, 2655, 2656, 2656, 2657, 2657, 2657, 2659, 2659, 2660, 2660, 2660, 2660, 2661, 2661, 2662, 2662, 2663, 2663, 2663, 2664, 2665, 2665, 2665, 2666, 2667, 2668, 2670, 2670, 2670, 2670, 2672, 2672, 2673, 2673, 2674, 2674, 2675, 2676, 2676, 2676, 2676, 2677, 2677, 2677, 2677, 2677, 2677, 2679, 2680, 2681, 2683, 2683, 2684, 2684, 2684, 2684, 2685, 2686, 2687, 2688, 2688, 2688, 2689, 2689, 2689, 2689, 2690, 2690, 2690, 2690, 2691, 2691, 2692, 2692, 2692, 2692, 2693, 2693, 2694, 2694, 2694, 2694, 2694, 2695, 2695, 2695, 2696, 2697, 2698, 2699, 2700, 2700, 2701, 2702, 2702, 2704, 2704, 2704, 2705, 2705, 2705, 2705, 2706, 2707, 2707, 2708, 2708, 2710, 2710, 2710, 2711, 2711, 2711, 2711, 2711, 2711, 2712, 2713, 2713, 2714, 2715, 2716, 2717, 2717, 2718, 2718, 2718, 2718, 2719, 2719, 2720, 2722, 2723, 2723, 2724, 2724, 2725, 2726, 2726, 2727, 2728, 2729, 2729, 2729, 2729, 2730, 2731, 2732, 2733, 2734, 2734, 2734, 2735, 2735, 2736, 2736, 2736, 2737, 2738, 2739, 2739, 2740, 2740, 2741, 2741, 2742, 2742, 2743, 2743, 2743, 2744, 2744, 2746, 2747, 2748, 2748, 2748, 2748, 2749, 2749, 2749, 2750, 2750, 2750, 2752, 2752, 2754, 2754, 2754, 2755, 2755, 2756, 2756, 2757, 2757, 2758, 2758, 2759, 2759, 2759, 2759, 2761, 2762, 2762, 2762, 2762, 2762, 2763, 2763, 2763, 2764, 2764, 2764, 2765, 2766, 2766, 2766, 2766, 2767, 2767, 2768, 2769, 2770, 2770, 2770, 2770, 2771, 2771, 2771, 2772, 2772, 2772, 2772, 2774, 2776, 2776, 2776, 2776, 2776, 2777, 2778, 2779, 2779, 2779, 2780, 2780, 2780, 2781, 2781, 2782, 2783, 2783, 2784, 2784, 2784, 2785, 2785, 2786, 2786, 2786, 2787, 2787, 2787, 2787, 2788, 2788, 2789, 2789, 2789, 2789, 2790, 2790, 2790, 2790, 2791, 2791, 2791, 2791, 2792, 2792, 2792, 2792, 2792, 2793, 2793, 2794, 2795, 2795, 2796, 2796, 2797, 2797, 2798, 2800, 2800, 2801, 2801, 2801, 2802, 2802, 2803, 2803, 2804, 2804, 2805, 2805, 2805, 2805, 2805, 2805, 2806, 2806, 2806, 2807, 2808, 2809, 2809, 2809, 2809, 2809, 2809, 2810, 2810, 2811, 2811, 2811, 2812, 2812, 2812, 2813, 2816, 2816, 2816, 2817, 2817, 2818, 2818, 2818, 2818, 2818, 2819, 2819, 2819, 2820, 2820, 2820, 2821, 2821, 2821, 2822, 2823, 2823, 2823, 2824, 2824, 2824, 2825, 2826, 2826, 2826, 2827, 2827, 2827, 2827, 2827, 2827, 2828, 2828, 2830, 2830, 2830, 2831, 2831, 2833, 2833, 2833, 2833, 2835, 2836, 2838, 2838, 2838, 2839, 2839, 2840, 2840, 2841, 2842, 2842, 2843, 2844, 2845, 2845, 2846, 2846, 2848, 2848, 2848, 2849, 2850, 2851, 2852, 2852, 2852, 2853, 2853, 2853, 2854, 2854, 2855, 2855, 2856, 2856, 2857, 2857, 2857, 2857, 2858, 2858, 2859, 2859, 2859, 2860, 2861, 2861, 2861, 2862, 2862, 2863, 2863, 2863, 2864, 2865, 2868, 2868, 2868, 2868, 2868, 2869, 2869, 2870, 2870, 2870, 2871, 2871, 2871, 2872, 2873, 2874, 2875, 2875, 2876, 2876, 2877, 2877, 2878, 2879, 2880, 2880, 2881, 2882, 2884, 2884, 2884, 2885, 2885, 2886, 2887, 2887, 2887, 2887, 2887, 2888, 2888, 2888, 2888, 2889, 2889, 2889, 2890, 2890, 2890, 2891, 2893, 2894, 2895, 2896, 2896, 2897, 2897, 2898, 2898, 2898, 2900, 2900, 2901, 2901, 2902, 2902, 2902, 2902, 2903, 2904, 2904, 2904, 2904, 2905, 2905, 2905, 2906, 2907, 2907, 2908, 2908, 2908, 2908, 2909, 2909, 2910, 2911, 2911, 2911, 2912, 2913, 2914, 2915, 2916, 2916, 2918, 2918, 2919, 2919, 2919, 2920, 2921, 2921, 2922, 2922, 2922, 2923, 2923, 2923, 2924, 2925, 2926, 2926, 2926, 2927, 2927, 2927, 2928, 2929, 2930, 2931, 2931, 2932, 2932, 2932, 2934, 2934, 2934, 2935, 2935, 2935, 2936, 2937, 2938, 2939, 2940, 2940, 2941, 2942, 2942, 2943, 2943, 2943, 2944, 2944, 2944, 2944, 2944, 2945, 2946, 2946, 2947, 2947, 2948, 2949, 2950, 2950, 2951, 2952, 2954, 2954, 2954, 2955, 2955, 2956, 2957, 2958, 2958, 2959, 2959, 2960, 2960, 2960, 2962, 2962, 2964, 2964, 2965, 2965, 2965, 2966, 2966, 2967, 2967, 2968, 2969, 2969, 2969, 2970, 2970, 2971, 2972, 2972, 2972, 2972, 2972, 2974, 2974, 2974, 2976, 2976, 2977, 2978, 2979, 2980, 2980, 2980, 2980, 2981, 2981, 2982, 2982, 2983, 2984, 2984, 2986, 2987, 2987, 2988, 2988, 2988, 2989, 2989, 2989, 2990, 2990, 2991, 2991, 2991, 2992, 2993, 2994, 2995, 2995, 2995, 2995, 2996, 2996, 2997, 2997, 2997, 2998, 2999, 2999, 2999, 2999, 2999, 2999, 3000, 3000, 3000, 3000, 3001, 3001, 3002, 3003, 3003, 3004, 3005, 3005, 3005, 3007, 3007, 3008, 3008, 3009, 3009, 3009, 3010, 3010, 3010, 3010, 3011, 3011, 3013, 3013, 3014, 3015, 3015, 3016, 3016, 3016, 3016, 3017, 3018, 3018, 3018, 3018, 3019, 3020, 3020, 3021, 3021, 3021, 3022, 3024, 3026, 3026, 3026, 3026, 3027, 3028, 3028, 3028, 3028, 3030, 3030, 3031, 3035, 3036, 3036, 3036, 3037, 3037, 3038, 3038, 3039, 3039, 3041, 3041, 3041, 3042, 3043, 3043, 3044, 3044, 3045, 3045, 3045, 3045, 3045, 3046, 3047, 3048, 3048, 3048, 3049, 3049, 3049, 3050, 3050, 3051, 3051, 3051, 3051, 3052, 3052, 3052, 3053, 3054, 3054, 3054, 3054, 3055, 3055, 3055, 3055, 3057, 3057, 3057, 3058, 3059, 3060, 3060, 3060, 3060, 3061, 3062, 3063, 3063, 3063, 3064, 3065, 3065, 3066, 3068, 3068, 3068, 3068, 3068, 3068, 3069, 3071, 3072, 3072, 3072, 3073, 3074, 3074, 3074, 3075, 3077, 3077, 3078, 3078, 3079, 3079, 3079, 3079, 3081, 3081, 3081, 3082, 3082, 3082, 3082, 3083, 3083, 3084, 3084, 3084, 3086, 3086, 3087, 3087, 3087, 3087, 3088, 3089, 3089, 3090, 3091, 3092, 3092, 3093, 3093, 3094, 3094, 3094, 3095, 3095, 3096, 3097, 3097, 3098, 3099, 3100, 3101, 3101, 3102, 3102, 3104, 3104, 3105, 3107, 3108, 3108, 3109, 3109, 3109, 3110, 3110, 3111, 3111, 3111, 3112, 3112, 3112, 3112, 3112, 3113, 3113, 3113, 3113, 3113, 3114, 3115, 3116, 3116, 3116, 3117, 3117, 3117, 3118, 3118, 3119, 3119, 3119, 3120, 3120, 3120, 3121, 3121, 3121, 3122, 3122, 3122, 3122, 3123, 3123, 3124, 3126, 3127, 3127, 3127, 3127, 3128, 3128, 3128, 3128, 3129, 3130, 3130, 3131, 3131, 3131, 3131, 3131, 3132, 3132, 3132, 3133, 3133, 3134, 3135, 3136, 3136, 3136, 3137, 3138, 3140, 3140, 3141, 3142, 3142, 3143, 3143, 3143, 3143, 3143, 3144, 3145, 3146, 3146, 3146, 3147, 3148, 3149, 3149, 3150, 3150, 3150, 3150, 3150, 3150, 3151, 3151, 3152, 3152, 3154, 3154, 3155, 3155, 3155, 3156, 3156, 3157, 3158, 3158, 3159, 3160, 3160, 3161, 3161, 3161, 3162, 3162, 3163, 3164, 3164, 3165, 3165, 3166, 3166, 3166, 3167, 3167, 3168, 3168, 3168, 3169, 3169, 3170, 3170, 3170, 3170, 3171, 3172, 3172, 3173, 3175, 3175, 3177, 3177, 3178, 3178, 3179, 3180, 3180, 3180, 3181, 3182, 3182, 3182, 3183, 3184, 3184, 3184, 3185, 3186, 3187, 3187, 3188, 3189, 3189, 3189, 3190, 3190, 3191, 3192, 3192, 3193, 3193, 3193, 3194, 3194, 3194, 3194, 3195, 3195, 3196, 3196, 3196, 3196, 3198, 3198, 3198, 3198, 3198, 3199, 3199, 3199, 3200, 3200, 3202, 3202, 3203, 3203, 3203, 3205, 3206, 3207, 3207, 3207, 3208, 3208, 3208, 3208, 3209, 3209, 3210, 3210, 3211, 3211, 3211, 3212, 3212, 3213, 3213, 3213, 3214, 3214, 3215, 3216, 3216, 3217, 3218, 3218, 3219, 3219, 3220, 3222, 3223, 3223, 3223, 3224, 3224, 3224, 3224, 3225, 3225, 3225, 3225, 3226, 3227, 3228, 3228, 3228, 3228, 3228, 3228, 3229, 3230, 3230, 3231, 3233, 3234, 3234, 3234, 3235, 3235, 3236, 3236, 3237, 3237, 3239, 3239, 3239, 3240, 3240, 3241, 3241, 3241, 3241, 3243, 3243, 3243, 3243, 3243, 3243, 3243, 3243, 3245, 3245, 3246, 3246, 3246, 3247, 3247, 3247, 3247, 3248, 3248, 3249, 3250, 3250, 3251, 3251, 3252, 3252, 3253, 3253, 3254, 3254, 3255, 3256, 3257, 3257, 3257, 3259, 3259, 3260, 3260, 3261, 3262, 3263, 3263, 3263, 3264, 3266, 3266, 3266, 3267, 3267, 3267, 3267, 3267, 3268, 3268, 3268, 3269, 3269, 3269, 3270, 3270, 3270, 3270, 3271, 3272, 3272, 3272, 3272, 3273, 3273, 3273, 3274, 3274, 3275, 3275, 3276, 3276, 3276, 3278, 3278, 3279, 3280, 3280, 3280, 3280, 3281, 3282, 3284, 3284, 3284, 3285, 3285, 3285, 3285, 3286, 3286, 3287, 3288, 3288, 3289, 3289, 3289, 3289, 3290, 3292, 3292, 3292, 3293, 3293, 3293, 3293, 3294, 3294, 3297, 3297, 3298, 3299, 3301, 3301, 3302, 3302, 3302, 3302, 3303, 3304, 3305, 3305, 3305, 3305, 3306, 3306, 3306, 3306, 3306, 3306, 3308, 3308, 3308, 3308, 3309, 3309, 3310, 3310, 3311, 3311, 3311, 3311, 3312, 3313, 3313, 3313, 3314, 3314, 3315, 3315, 3316, 3318, 3320, 3320, 3321, 3321, 3321, 3322, 3322, 3323, 3323, 3323, 3324, 3324, 3327, 3329, 3329, 3330, 3330, 3330, 3331, 3331, 3331, 3331, 3331, 3333, 3334, 3335, 3336, 3336, 3336, 3337, 3337, 3337, 3338, 3338, 3339, 3339, 3339, 3339, 3340, 3340, 3340, 3340, 3341, 3341, 3341, 3344, 3345, 3345, 3346, 3347, 3347, 3347, 3347, 3347, 3348, 3348, 3348, 3348, 3349, 3349, 3349, 3350, 3350, 3351, 3351, 3352, 3352, 3352, 3352, 3353, 3354, 3357, 3358, 3358, 3358, 3358, 3359, 3359, 3359, 3360, 3360, 3361, 3361, 3361, 3362, 3363, 3363, 3363, 3365, 3365, 3367, 3367, 3367, 3368, 3369, 3369, 3369, 3370, 3370, 3371, 3372, 3372, 3373, 3374, 3374, 3377, 3377, 3377, 3377, 3378, 3379, 3379, 3380, 3380, 3381, 3381, 3382, 3383, 3383, 3383, 3384, 3384, 3385, 3385, 3385, 3386, 3386, 3387, 3387, 3388, 3388, 3388, 3389, 3389, 3389, 3390, 3392, 3393, 3394, 3394, 3394, 3395, 3396, 3397, 3397, 3397, 3398, 3398, 3398, 3398, 3399, 3399, 3400, 3400, 3400, 3401, 3401, 3402, 3402, 3402, 3402, 3403, 3403, 3405, 3405, 3405, 3405, 3405, 3406, 3407, 3407, 3408, 3410, 3410, 3411, 3411, 3411, 3412, 3412, 3412, 3413, 3414, 3414, 3414, 3414, 3415, 3415, 3417, 3419, 3419, 3420, 3420, 3420, 3421, 3421, 3421, 3422, 3422, 3423, 3423, 3423, 3423, 3424, 3425, 3425, 3425, 3426, 3427, 3427, 3428, 3428, 3429, 3429, 3430, 3431, 3431, 3431, 3432, 3432, 3432, 3434, 3435, 3435, 3435, 3436, 3437, 3438, 3438, 3438, 3439, 3439, 3439, 3440, 3440, 3441, 3441, 3442, 3443, 3443, 3443, 3444, 3444, 3444, 3445, 3445, 3445, 3446, 3446, 3447, 3447, 3447, 3448, 3448, 3449, 3449, 3449, 3450, 3450, 3450, 3451, 3452, 3452, 3453, 3453, 3454, 3454, 3454, 3454, 3455, 3456, 3456, 3456, 3457, 3457, 3460, 3461, 3461, 3461, 3462, 3462, 3462, 3463, 3463, 3463, 3463, 3463, 3464, 3464, 3464, 3466, 3467, 3467, 3467, 3468, 3468, 3469, 3470, 3471, 3472, 3473, 3473, 3473, 3474, 3475, 3475, 3475, 3476, 3476, 3476, 3478, 3479, 3479, 3480, 3481, 3481, 3481, 3482, 3483, 3484, 3484, 3485, 3485, 3486, 3486, 3486, 3486, 3487, 3487, 3487, 3487, 3489, 3489, 3490, 3490, 3490, 3491, 3491, 3491, 3492, 3492, 3493, 3493, 3494, 3494, 3494, 3495, 3495, 3495, 3495, 3495, 3495, 3495, 3496, 3497, 3497, 3498, 3498, 3499, 3499, 3499, 3499, 3500, 3501, 3501, 3503, 3503, 3503, 3504, 3504, 3504, 3504, 3504, 3505, 3505, 3505, 3506, 3507, 3508, 3508, 3508, 3511, 3511, 3511, 3511, 3511, 3511, 3511, 3512, 3512, 3512, 3512, 3513, 3514, 3514, 3514, 3515, 3515, 3516, 3517, 3517, 3518, 3518, 3518, 3518, 3519, 3520, 3520, 3520, 3520, 3521, 3521, 3521, 3521, 3521, 3524, 3525, 3527, 3528, 3528, 3530, 3530, 3531, 3532, 3532, 3533, 3534, 3534, 3534, 3535, 3535, 3535, 3535, 3536, 3537, 3537, 3538, 3539, 3539, 3539, 3539, 3540, 3540, 3540, 3541, 3541, 3541, 3543, 3544, 3544, 3547, 3548, 3548, 3549, 3549, 3550, 3551, 3551, 3551, 3551, 3552, 3553, 3553, 3553, 3553, 3554, 3554, 3554, 3554, 3555, 3555, 3556, 3556, 3557, 3558, 3558, 3558, 3558, 3559, 3559, 3560, 3560, 3560, 3561, 3561, 3562, 3562, 3563, 3565, 3566, 3566, 3566, 3566, 3567, 3567, 3567, 3567, 3568, 3569, 3569, 3570, 3570, 3571, 3572, 3572, 3573, 3573, 3573, 3574, 3574, 3575, 3575, 3576, 3577, 3578, 3579, 3581, 3581, 3582, 3582, 3582, 3583, 3583, 3583, 3583, 3583, 3584, 3584, 3585, 3586, 3586, 3587, 3587, 3588, 3588, 3588, 3589, 3591, 3591, 3593, 3594, 3594, 3595, 3596, 3596, 3597, 3599, 3599, 3599, 3600, 3600, 3600, 3601, 3601, 3602, 3602, 3602, 3603, 3604, 3605, 3607, 3608, 3609, 3609, 3609, 3609, 3610, 3610, 3611, 3612, 3612, 3613, 3614, 3614, 3615, 3615, 3615, 3615, 3615, 3616, 3617, 3617, 3617, 3617, 3619, 3619, 3619, 3621, 3621, 3621, 3622, 3623, 3624, 3624, 3625, 3627, 3628, 3628, 3628, 3628, 3629, 3630, 3630, 3630, 3631, 3631, 3631, 3631, 3632, 3633, 3633, 3633, 3634, 3634, 3634, 3636, 3637, 3638, 3638, 3638, 3639, 3639, 3639, 3639, 3641, 3642, 3642, 3642, 3643, 3643, 3643, 3643, 3644, 3644, 3645, 3646, 3646, 3647, 3647, 3647, 3647, 3648, 3648, 3649, 3649, 3650, 3650, 3651, 3652, 3652, 3653, 3653, 3654, 3655, 3656, 3656, 3657, 3658, 3659, 3660, 3661, 3662, 3663, 3664, 3664, 3664, 3665, 3666, 3667, 3667, 3668, 3669, 3669, 3669, 3670, 3670, 3671, 3671, 3672, 3672, 3673, 3677, 3678, 3678, 3678, 3678, 3679, 3679, 3679, 3681, 3681, 3681, 3682, 3682, 3683, 3683, 3684, 3684, 3685, 3685, 3685, 3687, 3687, 3687, 3688, 3688, 3688, 3688, 3688, 3689, 3690, 3690, 3690, 3693, 3693, 3694, 3694, 3695, 3695, 3696, 3698, 3698, 3699, 3699, 3700, 3702, 3703, 3704, 3705, 3705, 3705, 3705, 3706, 3706, 3706, 3706, 3706, 3707, 3707, 3707, 3708, 3708, 3710, 3710, 3710, 3711, 3712, 3713, 3713, 3713, 3713, 3714, 3714, 3714, 3715, 3715, 3716, 3716, 3717, 3717, 3717, 3717, 3718, 3718, 3718, 3718, 3719, 3719, 3719, 3720, 3720, 3721, 3721, 3722, 3722, 3722, 3722, 3722, 3723, 3724, 3725, 3726, 3727, 3727, 3728, 3728, 3729, 3729, 3731, 3731, 3731, 3731, 3731, 3732, 3734, 3734, 3734, 3734, 3735, 3735, 3736, 3736, 3736, 3736, 3737, 3738, 3739, 3739, 3739, 3740, 3740, 3740, 3741, 3741, 3741, 3742, 3742, 3743, 3744, 3744, 3744, 3745, 3745, 3745, 3746, 3746, 3747, 3747, 3747, 3748, 3748, 3749, 3751, 3751, 3751, 3751, 3751, 3752, 3753, 3753, 3753, 3753, 3754, 3755, 3756, 3757, 3757, 3758, 3758, 3758, 3759, 3759, 3759, 3762, 3763, 3763, 3763, 3763, 3764, 3765, 3765, 3766, 3766, 3766, 3766, 3767, 3767, 3768, 3768, 3769, 3769, 3770, 3770, 3770, 3770, 3771, 3771, 3772, 3772, 3773, 3773, 3774, 3775, 3775, 3776, 3776, 3776, 3776, 3776, 3777, 3777, 3779, 3779, 3779, 3779, 3780, 3780, 3781, 3781, 3782, 3783, 3783, 3784, 3785, 3785, 3787, 3787, 3787, 3788, 3788, 3788, 3788, 3789, 3789, 3790, 3790, 3791, 3792, 3792, 3792, 3793, 3793, 3794, 3794, 3795, 3795, 3796, 3797, 3797, 3797, 3797, 3798, 3798, 3799, 3800, 3800, 3800, 3800, 3801, 3801, 3801, 3802, 3802, 3802, 3802, 3803, 3804, 3805, 3806, 3806, 3807, 3808, 3808, 3809, 3809, 3811, 3813, 3814, 3814, 3816, 3816, 3816, 3817, 3818, 3819, 3820, 3820, 3821, 3821, 3821, 3822, 3822, 3822, 3825, 3825, 3825, 3825, 3826, 3828, 3828, 3828, 3829, 3830, 3830, 3830, 3830, 3831, 3831, 3831, 3832, 3832, 3833, 3833, 3833, 3833, 3834, 3835, 3835, 3836, 3837, 3837, 3837, 3837, 3838, 3838, 3838, 3839, 3841, 3841, 3842, 3842, 3842, 3842, 3843, 3843, 3843, 3843, 3843, 3844, 3844, 3844, 3845, 3846, 3847, 3847, 3848, 3849, 3850, 3850, 3851, 3851, 3851, 3854, 3854, 3854, 3855, 3855, 3856, 3857, 3858, 3858, 3858, 3859, 3859, 3859, 3859, 3860, 3860, 3861, 3861, 3861, 3861, 3862, 3862, 3862, 3862, 3863, 3863, 3865, 3865, 3865, 3865, 3866, 3866, 3867, 3867, 3867, 3867, 3868, 3868, 3869, 3869, 3870, 3871, 3871, 3871, 3872, 3873, 3873, 3873, 3874, 3874, 3874, 3875, 3875, 3876, 3877, 3878, 3878, 3878, 3879, 3879, 3879, 3880, 3880, 3881, 3881, 3881, 3881, 3883, 3883, 3884, 3884, 3884, 3884, 3884, 3886, 3887, 3887, 3887, 3887, 3888, 3888, 3889, 3890, 3890, 3891, 3891, 3891, 3891, 3892, 3892, 3892, 3892, 3893, 3893, 3893, 3893, 3894, 3894, 3894, 3895, 3895, 3895, 3895, 3897, 3897, 3897, 3899, 3899, 3900, 3901, 3902, 3904, 3904, 3905, 3905, 3906, 3906, 3906, 3907, 3907, 3907, 3908, 3909, 3910, 3911, 3911, 3912, 3913, 3914, 3915, 3915, 3915, 3915, 3916, 3917, 3917, 3917, 3919, 3919, 3919, 3920, 3921, 3921, 3922, 3922, 3923, 3923, 3923, 3924, 3924, 3925, 3925, 3926, 3926, 3926, 3928, 3928, 3928, 3929, 3929, 3930, 3930, 3930, 3931, 3931, 3931, 3932, 3932, 3932, 3932, 3932, 3933, 3933, 3933, 3934, 3934, 3934, 3935, 3935, 3935, 3935, 3936, 3937, 3937, 3937, 3938, 3938, 3939, 3942, 3942, 3943, 3943, 3943, 3945, 3945, 3945, 3946, 3947, 3947, 3948, 3948, 3948, 3948, 3948, 3951, 3952, 3952, 3952, 3952, 3953, 3954, 3954, 3956, 3957, 3957, 3957, 3957, 3958, 3958, 3958, 3959, 3960, 3961, 3961, 3961, 3962, 3963, 3964, 3964, 3964, 3965, 3965, 3965, 3965, 3967, 3968, 3969, 3969, 3970, 3970, 3971, 3972, 3972, 3973, 3973, 3974, 3974, 3975, 3975, 3976, 3976, 3977, 3977, 3977, 3977, 3978, 3978, 3979, 3979, 3979, 3979, 3979, 3980, 3980, 3981, 3981, 3981, 3981, 3982, 3982, 3982, 3982, 3983, 3984, 3984, 3984, 3984, 3984, 3984, 3986, 3986, 3986, 3987, 3988, 3988, 3988, 3988, 3989, 3989, 3989, 3990, 3990, 3991, 3992, 3993, 3994, 3995, 3996, 3996, 3998, 3998, 3998, 3999, 4000, 4000, 4000, 4001, 4001, 4001, 4001, 4002, 4002, 4002, 4002, 4003, 4004, 4004, 4004, 4005, 4006, 4006, 4007, 4007, 4008, 4008, 4008, 4009, 4010, 4010, 4010, 4010, 4011, 4011, 4013, 4014, 4015, 4016, 4017, 4018, 4018, 4019, 4020, 4020, 4020, 4021, 4021, 4022, 4022, 4022, 4023, 4023, 4023, 4024, 4024, 4025, 4025, 4025, 4026, 4026, 4027, 4027, 4028, 4028, 4028, 4029, 4030, 4031, 4031, 4031, 4031, 4032, 4032, 4032, 4032, 4033, 4033, 4033, 4033, 4035, 4035, 4035, 4035, 4035, 4037, 4038, 4038, 4038, 4038, 4038, 4039, 4039, 4039, 4040, 4040, 4040, 4041, 4041, 4041, 4041, 4041, 4041, 4041, 4042, 4042, 4043, 4043, 4043, 4043, 4044, 4044, 4045, 4045, 4045, 4047, 4047, 4048, 4048, 4049, 4050, 4050, 4050, 4051, 4052, 4052, 4053, 4053, 4054, 4055, 4055, 4056, 4056, 4057, 4058, 4058, 4059, 4059, 4060, 4060, 4060, 4061, 4061, 4061, 4062, 4063, 4063, 4064, 4065, 4065, 4065, 4066, 4067, 4068, 4068, 4068, 4069, 4069, 4069, 4070, 4070, 4070, 4071, 4071, 4072, 4072, 4072, 4072, 4072, 4073, 4073, 4074, 4074, 4075, 4076, 4076, 4076, 4076, 4077, 4077, 4078, 4078, 4078, 4080, 4081, 4081, 4082, 4082, 4082, 4083, 4083, 4085, 4085, 4085, 4085, 4085, 4086, 4086, 4086, 4087, 4087, 4087, 4088, 4088, 4089, 4089, 4090, 4090, 4091, 4091, 4092, 4093, 4093, 4093, 4094, 4095, 4096, 4096, 4096, 4097, 4097, 4098, 4099, 4099, 4099, 4099, 4100, 4100, 4101, 4101, 4102, 4102, 4103, 4104, 4104, 4104, 4104, 4104, 4105, 4106, 4106, 4106, 4106, 4107, 4108, 4108, 4109, 4109, 4109, 4109, 4110, 4111, 4112, 4112, 4112, 4112, 4112, 4113, 4113, 4114, 4114, 4114, 4115, 4115, 4116, 4116, 4117, 4117, 4117, 4118, 4118, 4118, 4119, 4119, 4121, 4121, 4122, 4122, 4122, 4123, 4124, 4125, 4125, 4126, 4127, 4129, 4129, 4130, 4131, 4131, 4132, 4132, 4132, 4134, 4134, 4134, 4135, 4135, 4135, 4135, 4135, 4135, 4135, 4135, 4136, 4136, 4136, 4136, 4136, 4136, 4137, 4137, 4137, 4139, 4140, 4140, 4140, 4141, 4141, 4142, 4142, 4142, 4143, 4144, 4144, 4144, 4144, 4145, 4145, 4145, 4145, 4146, 4147, 4147, 4147, 4148, 4148, 4148, 4149, 4149, 4149, 4149, 4149, 4150, 4150, 4151, 4153, 4153, 4154, 4155, 4155, 4156, 4156, 4156, 4157, 4158, 4158, 4159, 4159, 4160, 4160, 4161, 4161, 4161, 4161, 4163, 4163, 4163, 4164, 4164, 4164, 4164, 4165, 4165, 4165, 4166, 4166, 4166, 4167, 4168, 4169, 4170, 4170, 4170, 4171, 4171, 4172, 4173, 4173, 4173, 4173, 4174, 4175, 4175, 4176, 4176, 4176, 4177, 4177, 4177, 4177, 4178, 4178, 4179, 4179, 4179, 4179, 4179, 4179, 4179, 4180, 4180, 4180, 4181, 4181, 4181, 4181, 4182, 4182, 4183, 4184, 4185, 4186, 4187, 4187, 4187, 4188, 4188, 4188, 4189, 4189, 4189, 4189, 4190, 4190, 4190, 4190, 4190, 4191, 4192, 4192, 4192, 4192, 4194, 4195, 4196, 4196, 4196, 4196, 4197, 4197, 4198, 4198, 4198, 4198, 4200, 4200, 4201, 4202, 4202, 4203, 4203, 4204, 4205, 4205, 4207, 4210, 4210, 4210, 4210, 4211, 4211, 4213, 4214, 4214, 4215, 4215, 4215, 4216, 4216, 4216, 4217, 4217, 4218, 4218, 4218, 4218, 4218, 4219, 4220, 4220, 4220, 4221, 4222, 4223, 4223, 4223, 4225, 4225, 4226, 4226, 4227, 4227, 4228, 4228, 4228, 4228, 4229, 4230, 4230, 4232, 4233, 4233, 4233, 4233, 4234, 4235, 4235, 4235, 4235, 4236, 4236, 4236, 4237, 4238, 4238, 4238, 4238, 4238, 4239, 4239, 4239, 4239, 4239, 4240, 4240, 4241, 4243, 4243, 4243, 4243, 4243, 4243, 4244, 4244, 4244, 4244, 4244, 4245, 4245, 4245, 4247, 4247, 4247, 4248, 4248, 4249, 4249, 4249, 4250, 4250, 4250, 4251, 4251, 4252, 4252, 4253, 4253, 4253, 4253, 4253, 4254, 4255, 4255, 4255, 4256, 4256, 4257, 4257, 4257, 4258, 4258, 4258, 4258, 4259, 4259, 4260, 4260, 4261, 4261, 4261, 4261, 4261, 4261, 4262, 4262, 4262, 4263, 4264, 4265, 4265, 4265, 4266, 4267, 4268, 4269, 4269, 4269, 4270, 4270, 4271, 4271, 4271, 4272, 4272, 4273, 4273, 4273, 4273, 4274, 4274, 4274, 4275, 4275, 4277, 4279, 4279, 4280, 4280, 4280, 4281, 4281, 4282, 4282, 4282, 4282, 4282, 4283, 4283, 4283, 4283, 4284, 4285, 4285, 4285, 4285, 4285, 4286, 4286, 4287, 4287, 4287, 4287, 4288, 4289, 4290, 4290, 4291, 4291, 4291, 4292, 4293, 4293, 4293, 4293, 4294, 4294, 4295, 4296, 4297, 4297, 4297, 4297, 4297, 4297, 4298, 4299, 4299, 4299, 4299, 4300, 4300, 4301, 4301, 4302, 4302, 4302, 4302, 4303, 4304, 4305, 4306, 4306, 4306, 4307, 4307, 4308, 4308, 4309, 4309, 4309, 4309, 4310, 4311, 4311, 4312, 4312, 4312, 4312, 4312, 4313, 4314, 4315, 4315, 4316, 4316, 4317, 4317, 4317, 4318, 4318, 4319, 4319, 4320, 4320, 4321, 4322, 4322, 4323, 4325, 4327, 4327, 4327, 4327, 4327, 4328, 4328, 4330, 4330, 4330, 4331, 4331, 4332, 4332, 4334, 4335, 4335, 4336, 4336, 4337, 4337, 4338, 4338, 4338, 4338, 4339, 4339, 4339, 4340, 4340, 4340, 4340, 4340, 4340, 4341, 4341, 4341, 4343, 4343, 4344, 4344, 4344, 4345, 4346, 4347, 4347, 4348, 4348, 4348, 4352, 4353, 4355, 4356, 4356, 4357, 4357, 4358, 4358, 4358, 4358, 4359, 4360, 4360, 4360, 4361, 4361, 4361, 4361, 4362, 4362, 4363, 4363, 4364, 4365, 4365, 4365, 4368, 4370, 4370, 4370, 4371, 4371, 4371, 4372, 4372, 4372, 4372, 4374, 4374, 4374, 4375, 4375, 4376, 4376, 4377, 4377, 4380, 4380, 4381, 4381, 4381, 4382, 4382, 4384, 4386, 4386, 4387, 4387, 4389, 4389, 4389, 4389, 4389, 4389, 4390, 4391, 4391, 4392, 4393, 4393, 4394, 4394, 4394, 4394, 4395, 4395, 4396, 4398, 4398, 4398, 4399, 4400, 4400, 4400, 4401, 4401, 4402, 4403, 4403, 4403, 4404, 4405, 4405, 4405, 4407, 4408, 4408, 4408, 4409, 4410, 4410, 4410, 4410, 4411, 4411, 4412, 4412, 4413, 4413, 4414, 4414, 4414, 4414, 4414, 4415, 4415, 4419, 4419, 4419, 4419, 4420, 4420, 4420, 4421, 4421, 4421, 4421, 4423, 4424, 4425, 4426, 4427, 4427, 4428, 4429, 4429, 4430, 4430, 4430, 4431, 4431, 4431, 4431, 4432, 4432, 4432, 4432, 4432, 4432, 4433, 4433, 4434, 4434, 4435, 4435, 4435, 4435, 4436, 4436, 4436, 4436, 4437, 4437, 4438, 4438, 4438, 4438, 4438, 4439, 4439, 4440, 4440, 4441, 4441, 4442, 4443, 4444, 4444, 4446, 4446, 4447, 4447, 4447, 4448, 4448, 4448, 4449, 4450, 4451, 4452, 4453, 4453, 4454, 4454, 4455, 4455, 4455, 4456, 4456, 4456, 4457, 4457, 4457, 4457, 4457, 4457, 4457, 4457, 4459, 4460, 4460, 4461, 4462, 4462, 4462, 4462, 4465, 4465, 4466, 4467, 4468, 4468, 4469, 4470, 4470, 4471, 4471, 4471, 4471, 4471, 4471, 4471, 4471, 4472, 4472, 4472, 4473, 4473, 4474, 4474, 4474, 4475, 4475, 4476, 4477, 4479, 4479, 4479, 4479, 4481, 4481, 4481, 4481, 4482, 4482, 4482, 4483, 4483, 4484, 4484, 4486, 4487, 4487, 4487, 4487, 4487, 4488, 4488, 4488, 4489, 4491, 4491, 4492, 4492, 4493, 4493, 4494, 4494, 4494, 4494, 4494, 4495, 4495, 4495, 4496, 4496, 4496, 4497, 4498, 4499, 4500, 4500, 4501, 4501, 4503, 4503, 4503, 4504, 4504, 4506, 4509, 4509, 4509, 4509, 4510, 4510, 4511, 4511, 4511, 4512, 4513, 4513, 4514, 4514, 4514, 4515, 4517, 4518, 4521, 4521, 4521, 4521, 4522, 4523, 4523, 4524, 4524, 4525, 4525, 4525, 4525, 4525, 4526, 4526, 4527, 4527, 4528, 4528, 4528, 4529, 4529, 4529, 4529, 4530, 4531, 4532, 4533, 4533, 4534, 4535, 4536, 4536, 4536, 4536, 4537, 4537, 4538, 4539, 4539, 4542, 4542, 4542, 4543, 4543, 4543, 4544, 4544, 4546, 4547, 4547, 4548, 4548, 4549, 4549, 4550, 4550, 4551, 4552, 4552, 4552, 4553, 4553, 4554, 4554, 4554, 4554, 4554, 4555, 4555, 4556, 4556, 4557, 4557, 4558, 4558, 4559, 4559, 4559, 4560, 4560, 4562, 4563, 4563, 4564, 4565, 4566, 4566, 4566, 4567, 4567, 4567, 4567, 4567, 4568, 4568, 4568, 4569, 4569, 4570, 4571, 4572, 4572, 4572, 4572, 4573, 4574, 4574, 4574, 4575, 4575, 4575, 4575, 4575, 4575, 4576, 4576, 4577, 4577, 4578, 4578, 4578, 4579, 4579, 4579, 4579, 4580, 4580, 4580, 4580, 4580, 4581, 4581, 4582, 4583, 4584, 4584, 4586, 4586, 4587, 4588, 4589, 4590, 4590, 4592, 4592, 4592, 4593, 4594, 4594, 4594, 4595, 4595, 4595, 4596, 4597, 4597, 4597, 4598, 4598, 4600, 4600, 4600, 4600, 4601, 4601, 4602, 4602, 4602, 4603, 4604, 4604, 4605, 4605, 4605, 4606, 4607, 4608, 4608, 4608, 4609, 4609, 4609, 4610, 4611, 4611, 4612, 4612, 4614, 4614, 4614, 4614, 4615, 4615, 4616, 4616, 4616, 4616, 4617, 4617, 4617, 4617, 4618, 4618, 4618, 4618, 4620, 4621, 4621, 4621, 4622, 4623, 4623, 4623, 4624, 4624, 4625, 4625, 4626, 4626, 4627, 4627, 4627, 4629, 4629, 4630, 4630, 4631, 4631, 4631, 4631, 4631, 4631, 4632, 4633, 4634, 4634, 4634, 4635, 4635, 4635, 4635, 4636, 4636, 4636, 4636, 4637, 4637, 4638, 4639, 4639, 4640, 4640, 4640, 4641, 4641, 4642, 4643, 4643, 4643, 4644, 4644, 4645, 4646, 4646, 4647, 4648, 4649, 4649, 4649, 4649, 4651, 4651, 4653, 4654, 4655, 4655, 4656, 4656, 4657, 4658, 4658, 4658, 4659, 4659, 4659, 4659, 4659, 4660, 4661, 4662, 4662, 4663, 4663, 4664, 4664, 4665, 4665, 4666, 4666, 4666, 4667, 4667, 4668, 4669, 4669, 4669, 4669, 4670, 4670, 4670, 4671, 4673, 4673, 4674, 4674, 4674, 4674, 4675, 4675, 4675, 4676, 4677, 4678, 4678, 4679, 4679, 4679, 4679, 4680, 4680, 4681, 4681, 4683, 4683, 4683, 4683, 4684, 4684, 4685, 4685, 4686, 4686, 4687, 4687, 4688, 4690, 4690, 4690, 4690, 4691, 4691, 4693, 4693, 4693, 4693, 4693, 4695, 4695, 4697, 4697, 4698, 4699, 4699, 4700, 4700, 4700, 4701, 4701, 4701, 4702, 4703, 4703, 4704, 4704, 4704, 4705, 4705, 4705, 4706, 4707, 4707, 4707, 4708, 4708, 4709, 4709, 4710, 4710, 4710, 4711, 4711, 4712, 4712, 4714, 4715, 4716, 4716, 4717, 4718, 4718, 4718, 4718, 4719, 4719, 4720, 4720, 4720, 4720, 4721, 4721, 4721, 4722, 4722, 4725, 4725, 4726, 4726, 4727, 4728, 4728, 4728, 4728, 4728, 4729, 4729, 4730, 4730, 4731, 4731, 4732, 4732, 4733, 4733, 4733, 4733, 4733, 4734, 4734, 4734, 4734, 4735, 4735, 4735, 4736, 4737, 4738, 4738, 4738, 4738, 4738, 4739, 4739, 4740, 4740, 4741, 4741, 4743, 4743, 4743, 4744, 4744, 4744, 4744, 4744, 4746, 4746, 4746, 4746, 4747, 4747, 4747, 4748, 4748, 4748, 4749, 4749, 4749, 4750, 4751, 4751, 4751, 4752, 4753, 4753, 4753, 4755, 4755, 4756, 4756, 4757, 4757, 4757, 4758, 4758, 4760, 4760, 4760, 4761, 4761, 4762, 4762, 4762, 4763, 4764, 4764, 4765, 4766, 4767, 4767, 4768, 4768, 4769, 4770, 4771, 4771, 4771, 4773, 4774, 4774, 4774, 4774, 4775, 4778, 4779, 4780, 4780, 4780, 4781, 4781, 4782, 4782, 4782, 4783, 4785, 4785, 4786, 4787, 4787, 4787, 4787, 4788, 4788, 4788, 4788, 4788, 4789, 4790, 4790, 4790, 4791, 4791, 4791, 4792, 4792, 4792, 4792, 4792, 4792, 4793, 4794, 4794, 4796, 4796, 4796, 4796, 4797, 4798, 4798, 4799, 4799, 4799, 4799, 4801, 4801, 4802, 4802, 4802, 4803, 4805, 4805, 4808, 4808, 4808, 4810, 4810, 4810, 4811, 4811, 4811, 4811, 4812, 4812, 4813, 4814, 4815, 4815, 4816, 4816, 4816, 4816, 4816, 4817, 4817, 4817, 4818, 4818, 4818, 4819, 4819, 4820, 4822, 4822, 4822, 4822, 4822, 4822, 4823, 4823, 4823, 4824, 4824, 4825, 4826, 4826, 4827, 4827, 4828, 4828, 4828, 4829, 4829, 4830, 4830, 4830, 4831, 4831, 4831, 4832, 4832, 4833, 4834, 4834, 4834, 4834, 4835, 4835, 4835, 4836, 4837, 4838, 4838, 4838, 4838, 4838, 4838, 4839, 4839, 4839, 4839, 4840, 4840, 4841, 4842, 4842, 4842, 4843, 4843, 4843, 4843, 4843, 4844, 4844, 4845, 4846, 4846, 4847, 4847, 4847, 4847, 4847, 4848, 4848, 4849, 4849, 4849, 4849, 4849, 4850, 4850, 4851, 4853, 4853, 4853, 4854, 4854, 4856, 4856, 4857, 4857, 4857, 4858, 4858, 4859, 4859, 4859, 4859, 4860, 4860, 4861, 4862, 4862, 4863, 4863, 4863, 4863, 4864, 4864, 4864, 4864, 4865, 4865, 4866, 4866, 4867, 4867, 4869, 4870, 4870, 4870, 4870, 4870, 4870, 4871, 4871, 4871, 4872, 4873, 4873, 4874, 4874, 4875, 4875, 4876, 4876, 4876, 4876, 4877, 4879, 4879, 4879, 4881, 4882, 4882, 4883, 4883, 4883, 4884, 4884, 4886, 4888, 4888, 4888, 4889, 4890, 4890, 4890, 4891, 4891, 4892, 4892, 4892, 4892, 4893, 4893, 4893, 4894, 4894, 4894, 4894, 4894, 4894, 4895, 4898, 4899, 4899, 4900, 4901, 4901, 4901, 4901, 4902, 4902, 4903, 4904, 4904, 4904, 4904, 4904, 4905, 4906, 4908, 4908, 4909, 4910, 4910, 4911, 4911, 4912, 4912, 4913, 4913, 4914, 4914, 4914, 4915, 4915, 4916, 4917, 4917, 4918, 4918, 4920, 4921, 4921, 4921, 4921, 4922, 4922, 4922, 4922, 4923, 4923, 4924, 4924, 4924, 4925, 4926, 4926, 4926, 4927, 4928, 4928, 4928, 4928, 4928, 4928, 4929, 4930, 4930, 4931, 4932, 4934, 4934, 4935, 4935, 4936, 4936, 4937, 4937, 4937, 4937, 4937, 4938, 4939, 4939, 4939, 4939, 4939, 4939, 4942, 4943, 4943, 4944, 4944, 4944, 4944, 4944, 4945, 4946, 4946, 4946, 4947, 4948, 4948, 4948, 4949, 4949, 4950, 4950, 4950, 4950, 4951, 4951, 4952, 4956, 4956, 4957, 4957, 4957, 4957, 4958, 4960, 4960, 4960, 4961, 4961, 4961, 4962, 4962, 4962, 4963, 4963, 4964, 4964, 4964, 4965, 4966, 4967, 4967, 4968, 4968, 4968, 4971, 4971, 4972, 4972, 4974, 4975, 4975, 4975, 4976, 4976, 4977, 4978, 4978, 4979, 4979, 4979, 4980, 4980, 4980, 4981, 4981, 4981, 4981, 4982, 4982, 4982, 4982, 4982, 4983, 4983, 4983, 4983, 4984, 4985, 4985, 4986, 4986, 4986, 4986, 4987, 4987, 4988, 4989, 4989, 4989, 4990, 4991, 4992, 4992, 4993, 4993, 4994, 4995, 4995, 4996, 4997, 4997, 4997, 4997, 4997, 4998, 4998, 4999, 4999]\n", diff --git a/crates/cli_utils/src/helpers.rs b/crates/cli_utils/src/helpers.rs index 1a0b8f1c19..86f0950a36 100644 --- a/crates/cli_utils/src/helpers.rs +++ b/crates/cli_utils/src/helpers.rs @@ -373,19 +373,17 @@ pub fn cli_testing_dir(dir_name: &str) -> PathBuf { } #[allow(dead_code)] -pub fn examples_dir(dir_name: &str) -> PathBuf { +pub fn dir_path_from_root(dir_name: &str) -> PathBuf { let mut path = root_dir(); - // Descend into examples/{dir_name} - path.push("examples"); path.extend(dir_name.split("/")); // Make slashes cross-target path } #[allow(dead_code)] -pub fn example_file(dir_name: &str, file_name: &str) -> PathBuf { - let mut path = examples_dir(dir_name); +pub fn file_path_from_root(dir_name: &str, file_name: &str) -> PathBuf { + let mut path = dir_path_from_root(dir_name); path.push(file_name); diff --git a/examples/gui/breakout/platform/Cargo.toml b/examples/gui/breakout/platform/Cargo.toml index 544db04357..413da65537 100644 --- a/examples/gui/breakout/platform/Cargo.toml +++ b/examples/gui/breakout/platform/Cargo.toml @@ -15,7 +15,7 @@ name = "host" path = "src/main.rs" [dependencies] -roc_std = { path = "../../../crates/roc_std" } +roc_std = { path = "../../../../crates/roc_std" } libc = "0.2" arrayvec = "0.7.2" page_size = "0.4.2" diff --git a/examples/gui/breakout/platform/src/graphics/primitives/text.rs b/examples/gui/breakout/platform/src/graphics/primitives/text.rs index 6aa2844878..45189fdc96 100644 --- a/examples/gui/breakout/platform/src/graphics/primitives/text.rs +++ b/examples/gui/breakout/platform/src/graphics/primitives/text.rs @@ -127,7 +127,7 @@ pub fn build_glyph_brush( render_format: wgpu::TextureFormat, ) -> Result, InvalidFont> { let inconsolata = FontArc::try_from_slice(include_bytes!( - "../../../../../../crates/editor/Inconsolata-Regular.ttf" + "../../../../../../../crates/editor/Inconsolata-Regular.ttf" ))?; Ok(GlyphBrushBuilder::using_font(inconsolata).build(gpu_device, render_format)) diff --git a/examples/gui/Hello.roc b/examples/gui/hello.roc similarity index 100% rename from examples/gui/Hello.roc rename to examples/gui/hello.roc diff --git a/examples/helloWorld.roc b/examples/helloWorld.roc index 1b6c4d7655..08c5230d8d 100644 --- a/examples/helloWorld.roc +++ b/examples/helloWorld.roc @@ -1,6 +1,11 @@ app "helloWorld" packages { pf: "cli/cli-platform/main.roc" } - imports [pf.Stdout] + imports [pf.Stdout, pf.Program.{ Program }] provides [main] to pf -main = Stdout.line "Hello, World!" +main = Program.noArgs mainTask + +mainTask = + Stdout.line "Hello, World!" + |> Program.exit 0 + From 376b6b0bc3e2c3582ff10b85703f6f663d233c32 Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Wed, 28 Sep 2022 12:55:07 +0200 Subject: [PATCH 10/65] fix peg_grammar tests --- crates/highlight/tests/peg_grammar.rs | 38 ++++++++++++++++----------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/crates/highlight/tests/peg_grammar.rs b/crates/highlight/tests/peg_grammar.rs index b5156a6daa..294c992b84 100644 --- a/crates/highlight/tests/peg_grammar.rs +++ b/crates/highlight/tests/peg_grammar.rs @@ -730,16 +730,24 @@ test1 = file_to_string(&file_path) } + fn cli_testing_path(sub_path: &str) -> String { + let examples_dir = "../cli_testing_examples/".to_string(); + + let file_path = examples_dir + sub_path; + + file_to_string(&file_path) + } + #[test] fn test_hello() { - let tokens = tokenize(&example_path("hello-world/main.roc")); + let tokens = tokenize(&example_path("helloWorld.roc")); assert_eq!(tokenparser::module(&tokens), Ok(())); } #[test] fn test_fibo() { - let tokens = tokenize(&example_path("algorithms/fibonacci.roc")); + let tokens = tokenize(&cli_testing_path("algorithms/fibonacci.roc")); assert_eq!(tokenparser::module(&tokens), Ok(())); } @@ -831,14 +839,14 @@ test1 = #[test] fn test_base64() { - let tokens = tokenize(&example_path("benchmarks/Base64.roc")); + let tokens = tokenize(&cli_testing_path("benchmarks/Base64.roc")); assert_eq!(tokenparser::module(&tokens), Ok(())); } #[test] fn test_base64_test() { - let tokens = tokenize(&example_path("benchmarks/TestBase64.roc")); + let tokens = tokenize(&cli_testing_path("benchmarks/TestBase64.roc")); assert_eq!(tokenparser::module(&tokens), Ok(())); } @@ -874,7 +882,7 @@ test1 = #[test] fn test_astar_test() { - let tokens = tokenize(&example_path("benchmarks/TestAStar.roc")); + let tokens = tokenize(&cli_testing_path("benchmarks/TestAStar.roc")); assert_eq!(tokenparser::module(&tokens), Ok(())); } @@ -1106,7 +1114,7 @@ test1 = #[test] fn test_closure_file() { - let tokens = tokenize(&example_path("benchmarks/Closure.roc")); + let tokens = tokenize(&cli_testing_path("benchmarks/Closure.roc")); assert_eq!(tokenparser::module(&tokens), Ok(())); } @@ -1126,7 +1134,7 @@ test1 = #[test] fn test_nqueens() { - let tokens = tokenize(&example_path("benchmarks/NQueens.roc")); + let tokens = tokenize(&cli_testing_path("benchmarks/NQueens.roc")); assert_eq!(tokenparser::module(&tokens), Ok(())); } @@ -1149,7 +1157,7 @@ test1 = #[test] fn test_quicksort() { - let tokens = tokenize(&example_path("benchmarks/Quicksort.roc")); + let tokens = tokenize(&cli_testing_path("benchmarks/Quicksort.roc")); assert_eq!(tokenparser::module(&tokens), Ok(())); } @@ -1176,7 +1184,7 @@ test1 = #[test] fn test_task() { - let tokens = tokenize(&example_path("benchmarks/platform/Task.roc")); + let tokens = tokenize(&cli_testing_path("benchmarks/platform/Task.roc")); assert_eq!(tokenparser::module(&tokens), Ok(())); } @@ -1221,7 +1229,7 @@ test1 = #[test] fn test_cfold() { - let tokens = tokenize(&example_path("benchmarks/CFold.roc")); + let tokens = tokenize(&cli_testing_path("benchmarks/CFold.roc")); assert_eq!(tokenparser::module(&tokens), Ok(())); } @@ -1291,7 +1299,7 @@ balance = \color -> #[test] fn test_rbtree_insert() { - let tokens = tokenize(&example_path("benchmarks/RBTreeInsert.roc")); + let tokens = tokenize(&cli_testing_path("benchmarks/RBTreeInsert.roc")); assert_eq!(tokenparser::module(&tokens), Ok(())); } @@ -1357,7 +1365,7 @@ balance = \color -> #[test] fn test_rbtree_ck() { - let tokens = tokenize(&example_path("benchmarks/RBTreeCk.roc")); + let tokens = tokenize(&cli_testing_path("benchmarks/RBTreeCk.roc")); assert_eq!(tokenparser::module(&tokens), Ok(())); } @@ -1390,7 +1398,7 @@ balance = \color -> #[test] fn test_astar() { - let tokens = tokenize(&example_path("benchmarks/AStar.roc")); + let tokens = tokenize(&cli_testing_path("benchmarks/AStar.roc")); assert_eq!(tokenparser::module(&tokens), Ok(())); } @@ -1409,7 +1417,7 @@ balance = \color -> #[test] fn test_false_interpreter_context() { - let tokens = tokenize(&example_path("false-interpreter/Context.roc")); + let tokens = tokenize(&example_path("cli/false-interpreter/Context.roc")); assert_eq!(tokenparser::module(&tokens), Ok(())); } @@ -1437,7 +1445,7 @@ balance = \color -> #[test] fn test_deriv() { - let tokens = tokenize(&example_path("benchmarks/Deriv.roc")); + let tokens = tokenize(&cli_testing_path("benchmarks/Deriv.roc")); assert_eq!(tokenparser::module(&tokens), Ok(())); } From 05ed0e4cc32cfef71e2e2d97ebc64203ed9499bb Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Wed, 28 Sep 2022 14:30:08 +0200 Subject: [PATCH 11/65] clippy fix, benchmarks debugging --- ci/bench-runner/src/main.rs | 7 +++++++ crates/cli/tests/cli_run.rs | 3 --- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ci/bench-runner/src/main.rs b/ci/bench-runner/src/main.rs index 03888e34e5..dfd35df440 100644 --- a/ci/bench-runner/src/main.rs +++ b/ci/bench-runner/src/main.rs @@ -230,6 +230,13 @@ fn check_if_bench_executables_changed() -> bool { let bench_folder_str = "/crates/cli_testing_examples/benchmarks/"; let main_benches_path_str = [BENCH_FOLDER_MAIN, bench_folder_str].join(""); + + Command::new("tree") + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) + .output() + .unwrap_or_else(|_| panic!("tree command failed", file_or_folder)); + let main_bench_hashes = calc_hashes_for_folder(&main_benches_path_str); let branch_benches_path_str = [BENCH_FOLDER_BRANCH, bench_folder_str].join(""); diff --git a/crates/cli/tests/cli_run.rs b/crates/cli/tests/cli_run.rs index 7e418d0124..09e3604a6a 100644 --- a/crates/cli/tests/cli_run.rs +++ b/crates/cli/tests/cli_run.rs @@ -37,9 +37,6 @@ mod cli_run { Roc, } - #[cfg(not(debug_assertions))] - use roc_collections::all::MutMap; - #[cfg(all(target_os = "linux", target_arch = "x86_64"))] const TEST_LEGACY_LINKER: bool = true; From fcb7d04ce9ba9597d0e4f9a83ec72a737a5a535c Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Wed, 28 Sep 2022 15:41:11 +0200 Subject: [PATCH 12/65] fixed panic arg --- ci/bench-runner/src/main.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ci/bench-runner/src/main.rs b/ci/bench-runner/src/main.rs index dfd35df440..c0a4e257b7 100644 --- a/ci/bench-runner/src/main.rs +++ b/ci/bench-runner/src/main.rs @@ -231,11 +231,10 @@ fn check_if_bench_executables_changed() -> bool { let main_benches_path_str = [BENCH_FOLDER_MAIN, bench_folder_str].join(""); - Command::new("tree") + dbg!(Command::new("tree") .stdout(Stdio::inherit()) .stderr(Stdio::inherit()) - .output() - .unwrap_or_else(|_| panic!("tree command failed", file_or_folder)); + .output()); let main_bench_hashes = calc_hashes_for_folder(&main_benches_path_str); From b46a060a36688a1c1f8ac1cb4db20c96692f5b7b Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Wed, 28 Sep 2022 17:09:44 +0200 Subject: [PATCH 13/65] install tree command Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com> --- .github/workflows/benchmarks.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index 58e0ee422c..432b9973ba 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -39,6 +39,9 @@ jobs: - uses: actions-rs/toolchain@v1 with: toolchain: stable + + # for debugging + - run: sudo apt install -y tree - name: build benchmark runner run: cd ci/bench-runner && cargo build --release && cd ../.. From e1277a1fc126bad33bffcebdc943e8a4a9167494 Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Fri, 30 Sep 2022 19:22:29 +0200 Subject: [PATCH 14/65] fixed race condition errors --- Cargo.lock | 2 - crates/cli/Cargo.toml | 2 - crates/cli/tests/cli_run.rs | 89 +++++++++++++++++++++---------------- 3 files changed, 51 insertions(+), 42 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 36536407dd..626e522d86 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3466,8 +3466,6 @@ dependencies = [ "roc_tracing", "serial_test", "signal-hook", - "strum", - "strum_macros", "target-lexicon", "tempfile", "ven_pretty", diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 594a582d3a..c4caf732d9 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -99,8 +99,6 @@ indoc = "1.0.7" serial_test = "0.9.0" criterion = { git = "https://github.com/Anton-4/criterion.rs"} cli_utils = { path = "../cli_utils" } -strum = "0.24.0" -strum_macros = "0.24" once_cell = "1.14.0" parking_lot = "0.12" diff --git a/crates/cli/tests/cli_run.rs b/crates/cli/tests/cli_run.rs index 6124e2752f..2bd2f63841 100644 --- a/crates/cli/tests/cli_run.rs +++ b/crates/cli/tests/cli_run.rs @@ -20,8 +20,6 @@ mod cli_run { use serial_test::serial; use std::iter; use std::path::Path; - use strum::IntoEnumIterator; - use strum_macros::EnumIter; const OPTIMIZE_FLAG: &str = concatcp!("--", roc_cli::FLAG_OPTIMIZE); const LINKER_FLAG: &str = concatcp!("--", roc_cli::FLAG_LINKER); @@ -30,11 +28,11 @@ mod cli_run { #[allow(dead_code)] const TARGET_FLAG: &str = concatcp!("--", roc_cli::FLAG_TARGET); - #[derive(Debug, EnumIter)] + #[derive(Debug)] enum CliMode { - RocBuild, - RocRun, - Roc, + RocBuild, // buildOnly + RocRun, // buildAndRun + Roc, // buildAndRunIfNoErrors } #[cfg(all(target_os = "linux", target_arch = "x86_64"))] @@ -126,6 +124,7 @@ mod cli_run { extra_env: &[(&str, &str)], expected_ending: &str, use_valgrind: bool, + test_many_cli_commands: bool, // buildOnly, buildAndRun and buildAndRunIfNoErrors ) { // valgrind does not yet support avx512 instructions, see #1963. // we can't enable this only when testing with valgrind because of host re-use between tests @@ -134,7 +133,13 @@ mod cli_run { std::env::set_var("NO_AVX512", "1"); } - for cli_mode in CliMode::iter() { + let cli_commands = if test_many_cli_commands { + vec![CliMode::RocBuild, CliMode::RocRun, CliMode::Roc] + } else { + vec![CliMode::Roc] + }; + + for cli_mode in cli_commands.iter() { let flags = { let mut vec = flags.to_vec(); @@ -243,17 +248,19 @@ mod cli_run { use_valgrind: bool, ) { test_roc_app( - dir_name, - roc_filename, - executable_filename, - &[], - &[], - &[], - expected_ending, - use_valgrind + dir_name, + roc_filename, + executable_filename, + &[], + &[], + &[], + expected_ending, + use_valgrind, + false, ) } + #[allow(clippy::too_many_arguments)] fn test_roc_app( dir_name: &str, roc_filename: &str, @@ -263,6 +270,7 @@ mod cli_run { extra_env: &[(&str, &str)], expected_ending: &str, use_valgrind: bool, + test_many_cli_commands: bool, // buildOnly, buildAndRun and buildAndRunIfNoErrors ) { let file_name = file_path_from_root(dir_name, roc_filename); @@ -284,7 +292,8 @@ mod cli_run { } // workaround for surgical linker issue, see PR #3990 - let mut custom_flags: Vec<&str> = vec![]; + // TODO temp for debugging: set back to empty vec + let mut custom_flags: Vec<&str> = vec![LINKER_FLAG, "legacy"]; match executable_filename { "form" | "hello-gui" | "breakout" | "ruby" => { @@ -330,6 +339,7 @@ mod cli_run { extra_env, expected_ending, use_valgrind, + test_many_cli_commands, ); custom_flags.push(OPTIMIZE_FLAG); @@ -345,6 +355,7 @@ mod cli_run { extra_env, expected_ending, use_valgrind, + test_many_cli_commands, ); // Also check with the legacy linker. @@ -359,6 +370,7 @@ mod cli_run { extra_env, expected_ending, use_valgrind, + test_many_cli_commands, ); } } @@ -436,13 +448,7 @@ mod cli_run { #[test] fn ruby_interop() { - test_roc_app_slim( - "examples/ruby-interop", - "main.roc", - "libhello", - "", - true, - ) + test_roc_app_slim("examples/ruby-interop", "main.roc", "libhello", "", true) } #[test] @@ -458,13 +464,7 @@ mod cli_run { #[test] fn hello_gui() { - test_roc_app_slim( - "examples/gui", - "hello.roc", - "hello-gui", - "", - false, - ) + test_roc_app_slim("examples/gui", "hello.roc", "hello-gui", "", false) } #[test] @@ -506,6 +506,7 @@ mod cli_run { &[], "4\n", false, + false, ) } @@ -520,6 +521,7 @@ mod cli_run { &[], "hi there!\nIt is known\n", true, + false, ) } @@ -535,6 +537,7 @@ mod cli_run { &[], "Hello Worldfoo!\n", true, + false, ) } @@ -549,18 +552,13 @@ mod cli_run { &[], "Hello, World!\n", false, + true, ) } #[test] fn swift_ui() { - test_roc_app_slim( - "examples/swiftui", - "main.roc", - "swiftui", - "", - false, - ) + test_roc_app_slim("examples/swiftui", "main.roc", "swiftui", "", false) } #[test] @@ -574,6 +572,7 @@ mod cli_run { &[], "Processed 3 files with 3 successes and 0 errors\n", false, + false, ) } @@ -585,11 +584,16 @@ mod cli_run { "env", &[], &[], - &[("EDITOR", "roc-editor"), ("SHLVL", "3"), ("LETTERS", "a,c,e,j")], + &[ + ("EDITOR", "roc-editor"), + ("SHLVL", "3"), + ("LETTERS", "a,c,e,j"), + ], "Your favorite editor is roc-editor!\n\ Your current shell level is 3!\n\ Your favorite letters are: a c e j\n", false, + false, ) } @@ -665,6 +669,7 @@ mod cli_run { &[], expected_ending, use_valgrind, + false, ); ran_without_optimizations = true; @@ -684,6 +689,7 @@ mod cli_run { &[], expected_ending, use_valgrind, + false, ); } @@ -696,6 +702,7 @@ mod cli_run { &[], expected_ending, use_valgrind, + false, ); } @@ -774,6 +781,7 @@ mod cli_run { &[], expected_ending, use_valgrind, + false, ); check_output_with_stdin( @@ -784,6 +792,7 @@ mod cli_run { &[], expected_ending, use_valgrind, + false, ); } @@ -888,6 +897,7 @@ mod cli_run { &[], "I am Dep2.str2\n", true, + false, ); } @@ -903,6 +913,7 @@ mod cli_run { &[], "I am Dep2.str2\n", true, + false, ); } @@ -918,6 +929,7 @@ mod cli_run { &[], "I am Dep2.value2\n", true, + false, ); } @@ -933,6 +945,7 @@ mod cli_run { &[], "I am Dep2.value2\n", true, + false, ); } From efd2611911143c368854416ad07ab46991281a13 Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Fri, 30 Sep 2022 19:35:11 +0200 Subject: [PATCH 15/65] re-enable surgical linker for cli_run tests --- crates/cli/tests/cli_run.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/cli/tests/cli_run.rs b/crates/cli/tests/cli_run.rs index 052ce69d00..df4681b436 100644 --- a/crates/cli/tests/cli_run.rs +++ b/crates/cli/tests/cli_run.rs @@ -298,8 +298,7 @@ mod cli_run { } // workaround for surgical linker issue, see PR #3990 - // TODO temp for debugging: set back to empty vec - let mut custom_flags: Vec<&str> = vec![LINKER_FLAG, "legacy"]; + let mut custom_flags: Vec<&str> = vec![]; match executable_filename { "form" | "hello-gui" | "breakout" | "ruby" => { From 5a188bda256b61739bf4bcc8917bafbbce11b407 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Wed, 28 Sep 2022 15:34:38 -0500 Subject: [PATCH 16/65] More efficient representation of args in the arg parser Rather than taking slices of a list when parsing subcommands and the like, we can mark certain positions in the arguments list as having already been parsed. This allows us to keep the argument list constant, at just the precise of an extra set (which is likely to be small in practice). This also makes it easy to show what arguments are leftover, if the time comes for that. It also makes parsing positional arguments easy; you just grab the next unmarked arguments. --- examples/interactive/cli-platform/Arg.roc | 121 +++++++++++++--------- 1 file changed, 74 insertions(+), 47 deletions(-) diff --git a/examples/interactive/cli-platform/Arg.roc b/examples/interactive/cli-platform/Arg.roc index 668b94b9dc..e05c08e512 100644 --- a/examples/interactive/cli-platform/Arg.roc +++ b/examples/interactive/cli-platform/Arg.roc @@ -31,7 +31,7 @@ NamedParser a := { ## needs, consider transforming it into a [NamedParser]. Parser a := [ Succeed a, - Arg Config (List Str -> Result a [NotFound Str, WrongType { arg : Str, expected : Type }]), + Arg Config (MarkedArgs -> Result a [NotFound Str, WrongType { arg : Str, expected : Type }]), # TODO: hiding the record behind an alias currently causes a panic SubCommand (List { @@ -44,6 +44,8 @@ Parser a := [ Lazy ({} -> a), ] +MarkedArgs : { args : List Str, taken : Set Nat } + ## Enumerates errors that can occur during parsing a list of command line arguments. ParseError a : [ ## The program name was not found as the first argument to be parsed. @@ -123,24 +125,32 @@ toHelpHelper = \@Parser parser, configs -> (\{ name, parser: innerParser } -> { name, help: toHelpHelper innerParser [] }) |> SubCommands -findOneArg : Str, Str, List Str -> Result Str [NotFound]* -findOneArg = \long, short, args -> - argMatches = \arg -> - if arg == "--\(long)" then - Bool.true +findOneArg : Str, Str, MarkedArgs -> Result { val : Str, newTaken : Set Nat } [NotFound]* +findOneArg = \long, short, { args, taken } -> + argMatches = \{ index, found: _ }, arg -> + if Set.contains taken index || Set.contains taken (index + 1) then + Continue { index: index + 1, found: Bool.false } + else if arg == "--\(long)" then + Break { index, found: Bool.true } + else if Bool.not (Str.isEmpty short) && arg == "-\(short)" then + Break { index, found: Bool.true } else - Bool.not (Str.isEmpty short) && arg == "-\(short)" + Continue { index: index + 1, found: Bool.false } # TODO allow = as well, etc. - result = List.findFirstIndex args argMatches + { index: argIndex, found } = List.walkUntil args { index: 0, found: Bool.false } argMatches - when result is - Ok index -> - # Return the next arg after the given one - List.get args (index + 1) - |> Result.mapErr \_ -> NotFound + if !found then + Err NotFound + else + # Return the next arg after the given one + List.get args (argIndex + 1) + |> Result.mapErr (\_ -> NotFound) + |> Result.map + (\val -> + newUsed = Set.fromList [argIndex, argIndex + 1] - Err NotFound -> Err NotFound + { val, newTaken: Set.union taken newUsed }) # andMap : Parser a, Parser (a -> b) -> Parser b andMap = \@Parser parser, @Parser mapper -> @@ -275,9 +285,11 @@ parse = \@NamedParser parser, args -> then Err (ProgramNameNotProvided parser.name) else - parseHelp parser.parser (List.split args 1).others + markedArgs = { args, taken: Set.single 0 } -parseHelp : Parser a, List Str -> Result a (ParseError *) + parseHelp parser.parser markedArgs + +parseHelp : Parser a, MarkedArgs -> Result a (ParseError *) parseHelp = \@Parser parser, args -> when parser is Succeed val -> Ok val @@ -288,9 +300,9 @@ parseHelp = \@Parser parser, args -> Err (WrongType { arg, expected }) -> Err (WrongType { arg, expected }) SubCommand cmds -> - when List.get args 0 is - Ok cmd -> - argsRest = (List.split args 1).others + when nextUnmarked args is + Ok { index, val: cmd } -> + argsRest = { args & taken: Set.insert args.taken index } state = List.walkUntil cmds @@ -313,6 +325,17 @@ parseHelp = \@Parser parser, args -> WithConfig parser2 _config -> parseHelp parser2 args +nextUnmarked : MarkedArgs -> Result { index : Nat, val : Str } [OutOfBounds] +nextUnmarked = \marked -> + help = \index -> + if Set.contains marked.taken index then + help (index + 1) + else + List.get marked.args index + |> Result.map \val -> { index, val } + + help 0 + ## Creates a parser for a boolean flag argument. ## Flags of value "true" and "false" will be parsed as [Bool.true] and [Bool.false], respectively. ## All other values will result in a `WrongType` error. @@ -321,9 +344,11 @@ bool = \{ long, short ? "", help ? "" } -> fn = \args -> when findOneArg long short args is Err NotFound -> Err (NotFound long) - Ok "true" -> Ok Bool.true - Ok "false" -> Ok Bool.false - Ok _ -> Err (WrongType { arg: long, expected: Bool }) + Ok { val, newTaken: _ } -> + when val is + "true" -> Ok Bool.true + "false" -> Ok Bool.false + _ -> Err (WrongType { arg: long, expected: Bool }) @Parser (Arg { long, short, help, type: Bool } fn) @@ -333,7 +358,7 @@ str = \{ long, short ? "", help ? "" } -> fn = \args -> when findOneArg long short args is Err NotFound -> Err (NotFound long) - Ok foundArg -> Ok foundArg + Ok { val, newTaken: _ } -> Ok val @Parser (Arg { long, short, help, type: Str } fn) @@ -343,8 +368,8 @@ i64 = \{ long, short ? "", help ? "" } -> fn = \args -> when findOneArg long short args is Err NotFound -> Err (NotFound long) - Ok foundArg -> - Str.toI64 foundArg + Ok { val, newTaken: _ } -> + Str.toI64 val |> Result.mapErr \_ -> WrongType { arg: long, expected: I64 } @Parser (Arg { long, short, help, type: I64 } fn) @@ -507,107 +532,109 @@ formatError = \err -> ## ``` withParser = \arg1, arg2 -> andMap arg2 arg1 +mark = \args -> { args, taken: Set.empty } + # bool undashed long argument is missing expect parser = bool { long: "foo" } - parseHelp parser ["foo"] == Err (MissingRequiredArg "foo") + parseHelp parser (mark ["foo"]) == Err (MissingRequiredArg "foo") # bool dashed long argument without value is missing expect parser = bool { long: "foo" } - parseHelp parser ["--foo"] == Err (MissingRequiredArg "foo") + parseHelp parser (mark ["--foo"]) == Err (MissingRequiredArg "foo") # bool dashed long argument with value is determined true expect parser = bool { long: "foo" } - parseHelp parser ["--foo", "true"] == Ok Bool.true + parseHelp parser (mark ["--foo", "true"]) == Ok Bool.true # bool dashed long argument with value is determined false expect parser = bool { long: "foo" } - parseHelp parser ["--foo", "false"] == Ok Bool.false + parseHelp parser (mark ["--foo", "false"]) == Ok Bool.false # bool dashed long argument with value is determined wrong type expect parser = bool { long: "foo" } - parseHelp parser ["--foo", "not-a-bool"] == Err (WrongType { arg: "foo", expected: Bool }) + parseHelp parser (mark ["--foo", "not-a-bool"]) == Err (WrongType { arg: "foo", expected: Bool }) # bool dashed short argument with value is determined true expect parser = bool { long: "foo", short: "F" } - parseHelp parser ["-F", "true"] == Ok Bool.true + parseHelp parser (mark ["-F", "true"]) == Ok Bool.true # bool dashed short argument with value is determined false expect parser = bool { long: "foo", short: "F" } - parseHelp parser ["-F", "false"] == Ok Bool.false + parseHelp parser (mark ["-F", "false"]) == Ok Bool.false # bool dashed short argument with value is determined wrong type expect parser = bool { long: "foo", short: "F" } - parseHelp parser ["-F", "not-a-bool"] == Err (WrongType { arg: "foo", expected: Bool }) + parseHelp parser (mark ["-F", "not-a-bool"]) == Err (WrongType { arg: "foo", expected: Bool }) # string dashed long argument without value is missing expect parser = str { long: "foo" } - parseHelp parser ["--foo"] == Err (MissingRequiredArg "foo") + parseHelp parser (mark ["--foo"]) == Err (MissingRequiredArg "foo") # string dashed long argument with value is determined expect parser = str { long: "foo" } - parseHelp parser ["--foo", "itsme"] == Ok "itsme" + parseHelp parser (mark ["--foo", "itsme"]) == Ok "itsme" # string dashed short argument without value is missing expect parser = str { long: "foo", short: "F" } - parseHelp parser ["-F"] == Err (MissingRequiredArg "foo") + parseHelp parser (mark ["-F"]) == Err (MissingRequiredArg "foo") # string dashed short argument with value is determined expect parser = str { long: "foo", short: "F" } - parseHelp parser ["-F", "itsme"] == Ok "itsme" + parseHelp parser (mark ["-F", "itsme"]) == Ok "itsme" # i64 dashed long argument without value is missing expect parser = i64 { long: "foo" } - parseHelp parser ["--foo"] == Err (MissingRequiredArg "foo") + parseHelp parser (mark ["--foo"]) == Err (MissingRequiredArg "foo") # i64 dashed long argument with value is determined positive expect parser = i64 { long: "foo" } - parseHelp parser ["--foo", "1234"] == Ok 1234 + parseHelp parser (mark ["--foo", "1234"]) == Ok 1234 # i64 dashed long argument with value is determined negative expect parser = i64 { long: "foo" } - parseHelp parser ["--foo", "-1234"] == Ok -1234 + parseHelp parser (mark ["--foo", "-1234"]) == Ok -1234 # i64 dashed short argument without value is missing expect parser = i64 { long: "foo", short: "F" } - parseHelp parser ["-F"] == Err (MissingRequiredArg "foo") + parseHelp parser (mark ["-F"]) == Err (MissingRequiredArg "foo") # i64 dashed short argument with value is determined expect parser = i64 { long: "foo", short: "F" } - parseHelp parser ["-F", "1234"] == Ok 1234 + parseHelp parser (mark ["-F", "1234"]) == Ok 1234 # two string parsers complete cases expect @@ -622,7 +649,7 @@ expect ["--foo", "true", "--bar", "baz", "--other", "something"], ] - List.all cases \args -> parseHelp parser args == Ok "foo: true bar: baz" + List.all cases \args -> parseHelp parser (mark args) == Ok "foo: true bar: baz" # one argument is missing out of multiple expect @@ -657,7 +684,7 @@ expect expect parser = bool { long: "foo" } - when parseHelp parser ["foo"] is + when parseHelp parser (mark ["foo"]) is Ok _ -> Bool.false Err e -> err = formatError e @@ -668,7 +695,7 @@ expect expect parser = bool { long: "foo" } - when parseHelp parser ["--foo", "12"] is + when parseHelp parser (mark ["--foo", "12"]) is Ok _ -> Bool.false Err e -> err = formatError e @@ -786,7 +813,7 @@ expect parser = choice [subCommand (succeed "") "auth", subCommand (succeed "") "publish"] - when parseHelp parser [] is + when parseHelp parser (mark []) is Ok _ -> Bool.true Err e -> err = formatError e @@ -804,7 +831,7 @@ expect parser = choice [subCommand (succeed "") "auth", subCommand (succeed "") "publish"] - when parseHelp parser ["logs"] is + when parseHelp parser (mark ["logs"]) is Ok _ -> Bool.true Err e -> err = formatError e From 6ccab8357651b42019b0ee8273fd282850c6b9a4 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Wed, 28 Sep 2022 15:39:39 -0500 Subject: [PATCH 17/65] Add comments about MarkedArgs --- examples/interactive/cli-platform/Arg.roc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/interactive/cli-platform/Arg.roc b/examples/interactive/cli-platform/Arg.roc index e05c08e512..1c8964c8a1 100644 --- a/examples/interactive/cli-platform/Arg.roc +++ b/examples/interactive/cli-platform/Arg.roc @@ -44,6 +44,10 @@ Parser a := [ Lazy ({} -> a), ] +## A representation of parsed and unparsed arguments in a constant list of +## command-line arguments. +## Used only internally, for efficient representation of parsed and unparsed +## arguments. MarkedArgs : { args : List Str, taken : Set Nat } ## Enumerates errors that can occur during parsing a list of command line arguments. From 84ddf35956e36d6443d982d51c7d2474e2853a59 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Wed, 28 Sep 2022 16:00:32 -0500 Subject: [PATCH 18/65] Make sure argument parsing marks arguments as taken --- examples/interactive/cli-platform/Arg.roc | 44 ++++++++++++++--------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/examples/interactive/cli-platform/Arg.roc b/examples/interactive/cli-platform/Arg.roc index 1c8964c8a1..7bb91e9d52 100644 --- a/examples/interactive/cli-platform/Arg.roc +++ b/examples/interactive/cli-platform/Arg.roc @@ -31,7 +31,7 @@ NamedParser a := { ## needs, consider transforming it into a [NamedParser]. Parser a := [ Succeed a, - Arg Config (MarkedArgs -> Result a [NotFound Str, WrongType { arg : Str, expected : Type }]), + Arg Config (MarkedArgs -> Result { newlyTaken : Taken, val : a } [NotFound Str, WrongType { arg : Str, expected : Type }]), # TODO: hiding the record behind an alias currently causes a panic SubCommand (List { @@ -44,11 +44,14 @@ Parser a := [ Lazy ({} -> a), ] +## Indices in an arguments list that have already been parsed. +Taken : Set Nat + ## A representation of parsed and unparsed arguments in a constant list of ## command-line arguments. ## Used only internally, for efficient representation of parsed and unparsed ## arguments. -MarkedArgs : { args : List Str, taken : Set Nat } +MarkedArgs : { args : List Str, taken : Taken } ## Enumerates errors that can occur during parsing a list of command line arguments. ParseError a : [ @@ -129,7 +132,7 @@ toHelpHelper = \@Parser parser, configs -> (\{ name, parser: innerParser } -> { name, help: toHelpHelper innerParser [] }) |> SubCommands -findOneArg : Str, Str, MarkedArgs -> Result { val : Str, newTaken : Set Nat } [NotFound]* +findOneArg : Str, Str, MarkedArgs -> Result { val : Str, newlyTaken : Taken } [NotFound]* findOneArg = \long, short, { args, taken } -> argMatches = \{ index, found: _ }, arg -> if Set.contains taken index || Set.contains taken (index + 1) then @@ -154,7 +157,10 @@ findOneArg = \long, short, { args, taken } -> (\val -> newUsed = Set.fromList [argIndex, argIndex + 1] - { val, newTaken: Set.union taken newUsed }) + { val, newlyTaken: newUsed }) + +updateTaken : MarkedArgs, Taken -> MarkedArgs +updateTaken = \{ args, taken }, taken2 -> { args, taken: Set.union taken taken2 } # andMap : Parser a, Parser (a -> b) -> Parser b andMap = \@Parser parser, @Parser mapper -> @@ -176,7 +182,7 @@ andMap = \@Parser parser, @Parser mapper -> Arg config run -> Arg config \args -> run args - |> Result.map fn + |> Result.map (\{ val, newlyTaken } -> { val: fn val, newlyTaken }) SubCommand cmds -> mapSubParser = \{ name, parser: parser2 } -> @@ -190,13 +196,13 @@ andMap = \@Parser parser, @Parser mapper -> Succeed a -> Arg config \args -> when run args is - Ok fn -> Ok (fn a) + Ok { val: fn, newlyTaken } -> Ok { val: fn a, newlyTaken } Err err -> Err err Lazy thunk -> Arg config \args -> when run args is - Ok fn -> Ok (fn (thunk {})) + Ok { val: fn, newlyTaken } -> Ok { val: fn (thunk {}), newlyTaken } Err err -> Err err WithConfig parser2 config2 -> @@ -208,7 +214,10 @@ andMap = \@Parser parser, @Parser mapper -> # Parse first the one and then the other. combinedParser = Arg config2 \args -> when run args is - Ok fn -> run2 args |> Result.map fn + Ok { val: fn, newlyTaken } -> + run2 (updateTaken args newlyTaken) + |> Result.map (\{ val, newlyTaken: newlyTaken2 } -> { val: fn val, newlyTaken: Set.union newlyTaken newlyTaken2 }) + Err err -> Err err # Store the extra config. @@ -242,7 +251,7 @@ andMap = \@Parser parser, @Parser mapper -> Arg config run -> Arg config \args -> run args - |> Result.map fn + |> Result.map (\{ val, newlyTaken } -> { val: fn val, newlyTaken }) SubCommand cmds -> mapSubParser = \{ name, parser: parser2 } -> @@ -299,9 +308,9 @@ parseHelp = \@Parser parser, args -> Succeed val -> Ok val Arg _ run -> when run args is - Ok val -> Ok val + Ok { val, newlyTaken: _ } -> Ok val Err (NotFound long) -> Err (MissingRequiredArg long) - Err (WrongType { arg, expected }) -> Err (WrongType { arg, expected }) + Err (WrongType {arg, expected}) -> Err (WrongType { arg: long, expected: type }) SubCommand cmds -> when nextUnmarked args is @@ -348,10 +357,10 @@ bool = \{ long, short ? "", help ? "" } -> fn = \args -> when findOneArg long short args is Err NotFound -> Err (NotFound long) - Ok { val, newTaken: _ } -> + Ok { val, newlyTaken } -> when val is - "true" -> Ok Bool.true - "false" -> Ok Bool.false + "true" -> Ok { val: Bool.true, newlyTaken } + "false" -> Ok { val: Bool.false, newlyTaken } _ -> Err (WrongType { arg: long, expected: Bool }) @Parser (Arg { long, short, help, type: Bool } fn) @@ -362,7 +371,7 @@ str = \{ long, short ? "", help ? "" } -> fn = \args -> when findOneArg long short args is Err NotFound -> Err (NotFound long) - Ok { val, newTaken: _ } -> Ok val + Ok { val, newlyTaken } -> Ok { val, newlyTaken } @Parser (Arg { long, short, help, type: Str } fn) @@ -372,9 +381,10 @@ i64 = \{ long, short ? "", help ? "" } -> fn = \args -> when findOneArg long short args is Err NotFound -> Err (NotFound long) - Ok { val, newTaken: _ } -> + Ok { val, newlyTaken } -> Str.toI64 val - |> Result.mapErr \_ -> WrongType { arg: long, expected: I64 } + |> Result.mapErr (\_ -> WrongType { arg: long, expected: I64 }) + |> Result.map (\v -> { val: v, newlyTaken }) @Parser (Arg { long, short, help, type: I64 } fn) From 5245c4f6409968496d3f0e7543972cd3ba7b1a75 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Wed, 28 Sep 2022 17:29:09 -0500 Subject: [PATCH 19/65] Implement positional arguments --- examples/interactive/cli-platform/Arg.roc | 258 +++++++++++++++++++--- 1 file changed, 227 insertions(+), 31 deletions(-) diff --git a/examples/interactive/cli-platform/Arg.roc b/examples/interactive/cli-platform/Arg.roc index 7bb91e9d52..83617819f8 100644 --- a/examples/interactive/cli-platform/Arg.roc +++ b/examples/interactive/cli-platform/Arg.roc @@ -9,6 +9,7 @@ interface Arg bool, str, i64, + positional, subCommand, choice, withParser, @@ -31,7 +32,8 @@ NamedParser a := { ## needs, consider transforming it into a [NamedParser]. Parser a := [ Succeed a, - Arg Config (MarkedArgs -> Result { newlyTaken : Taken, val : a } [NotFound Str, WrongType { arg : Str, expected : Type }]), + Arg ArgConfig (MarkedArgs -> Result { newlyTaken : Taken, val : a } [NotFound Str, WrongType { arg : Str, expected : Type }]), + Positional PositionalConfig (MarkedArgs -> Result { newlyTaken : Taken, val : a } [NotFound, WrongType]), # TODO: hiding the record behind an alias currently causes a panic SubCommand (List { @@ -92,13 +94,20 @@ Help : [ Config (List Config), ] -Config : { +ArgConfig : { long : Str, short : Str, help : Str, type : Type, } +PositionalConfig : { + name : Str, + help : Str, +} + +Config : [Arg ArgConfig, Positional PositionalConfig] + ## Generates help metadata from a [Parser]. ## ## This is useful if you would like to use this metadata to generate your own @@ -123,7 +132,7 @@ toHelpHelper = \@Parser parser, configs -> toHelpHelper innerParser (List.append configs config) Arg config _ -> - List.append configs config + List.append configs (Arg config) |> Config SubCommand commands -> @@ -132,6 +141,10 @@ toHelpHelper = \@Parser parser, configs -> (\{ name, parser: innerParser } -> { name, help: toHelpHelper innerParser [] }) |> SubCommands + Positional config _ -> + List.append configs (Positional config) + |> Config + findOneArg : Str, Str, MarkedArgs -> Result { val : Str, newlyTaken : Taken } [NotFound]* findOneArg = \long, short, { args, taken } -> argMatches = \{ index, found: _ }, arg -> @@ -184,6 +197,11 @@ andMap = \@Parser parser, @Parser mapper -> run args |> Result.map (\{ val, newlyTaken } -> { val: fn val, newlyTaken }) + Positional config run -> + Positional config \args -> + run args + |> Result.map (\{val, newlyTaken} -> {val: fn val, newlyTaken}) + SubCommand cmds -> mapSubParser = \{ name, parser: parser2 } -> { name, parser: andMap parser2 (@Parser mapper) } @@ -222,7 +240,75 @@ andMap = \@Parser parser, @Parser mapper -> # Store the extra config. @Parser combinedParser - |> WithConfig config + |> WithConfig (Arg config) + + Positional config2 run2 -> + combinedParser = Positional config2 \args -> + when run args is + Ok { val: fn, newlyTaken } -> + run2 (updateTaken args newlyTaken) + |> Result.map (\{ val, newlyTaken: newlyTaken2 } -> { val: fn val, newlyTaken: Set.union newlyTaken newlyTaken2 }) + + Err err -> Err err + + # Store the extra config. + @Parser combinedParser + |> WithConfig (Arg config) + + SubCommand cmds -> + # For each subcommand, first run the subcommand, then + # push the result through the arg parser. + mapSubParser = \{ name, parser: parser2 } -> + { name, parser: andMap parser2 (@Parser mapper) } + + List.map cmds mapSubParser + |> SubCommand + + Positional config run -> + when parser is + Succeed a -> + Positional config \args -> + when run args is + Ok { val: fn, newlyTaken } -> Ok { val: fn a, newlyTaken } + Err err -> Err err + + Lazy thunk -> + Positional config \args -> + when run args is + Ok { val: fn, newlyTaken } -> Ok { val: fn (thunk {}), newlyTaken } + Err err -> Err err + + WithConfig parser2 config2 -> + parser2 + |> andMap (@Parser mapper) + |> WithConfig config2 + + Arg config2 run2 -> + # Parse first the one and then the other. + combinedParser = Arg config2 \args -> + when run args is + Ok { val: fn, newlyTaken } -> + run2 (updateTaken args newlyTaken) + |> Result.map (\{ val, newlyTaken: newlyTaken2 } -> { val: fn val, newlyTaken: Set.union newlyTaken newlyTaken2 }) + + Err err -> Err err + + # Store the extra config. + @Parser combinedParser + |> WithConfig (Positional config) + + Positional config2 run2 -> + combinedParser = Positional config2 \args -> + when run args is + Ok { val: fn, newlyTaken } -> + run2 (updateTaken args newlyTaken) + |> Result.map (\{ val, newlyTaken: newlyTaken2 } -> { val: fn val, newlyTaken: Set.union newlyTaken newlyTaken2 }) + + Err err -> Err err + + # Store the extra config. + @Parser combinedParser + |> WithConfig (Positional config) SubCommand cmds -> # For each subcommand, first run the subcommand, then @@ -253,6 +339,11 @@ andMap = \@Parser parser, @Parser mapper -> run args |> Result.map (\{ val, newlyTaken } -> { val: fn val, newlyTaken }) + Positional config run -> + Positional config \args -> + run args + |> Result.map (\{val, newlyTaken} -> {val: fn val, newlyTaken}) + SubCommand cmds -> mapSubParser = \{ name, parser: parser2 } -> { name, parser: andMap parser2 (@Parser mapper) } @@ -312,6 +403,12 @@ parseHelp = \@Parser parser, args -> Err (NotFound long) -> Err (MissingRequiredArg long) Err (WrongType {arg, expected}) -> Err (WrongType { arg: long, expected: type }) + Positional { name } run -> + when run args is + Ok {val, newlyTaken: _} -> Ok val + Err NotFound -> Err (MissingRequiredArg name) + Err WrongType -> Err (MissingRequiredArg name) + SubCommand cmds -> when nextUnmarked args is Ok { index, val: cmd } -> @@ -388,6 +485,15 @@ i64 = \{ long, short ? "", help ? "" } -> @Parser (Arg { long, short, help, type: I64 } fn) +## Parses a single positional argument as a string. +positional = \{ name, help ? "" } -> + fn = \args -> + nextUnmarked args + |> Result.mapErr (\OutOfBounds -> NotFound) + |> Result.map (\{val, index} -> {val, newlyTaken: Set.insert args.taken index}) + + @Parser (Positional { name, help } fn) + ## Wraps a given parser as a subcommand parser. ## ## When parsing arguments, the subcommand name will be expected to be parsed @@ -429,6 +535,13 @@ indentLevel = 4 mapNonEmptyStr = \s, f -> if Str.isEmpty s then s else f s +filterMap : List a, (a -> [Some b, None]) -> List b +filterMap = \lst, transform -> + List.walk lst [] \all, elem -> + when transform elem is + Some v -> List.append all v + None -> all + # formatHelp : NamedParser a -> Str formatHelp = \@NamedParser { name, help, parser } -> fmtHelp = @@ -436,40 +549,84 @@ formatHelp = \@NamedParser { name, help, parser } -> cmdHelp = toHelp parser - fmtCmdHeading = - when cmdHelp is - SubCommands _ -> "COMMANDS:" - Config _ -> "OPTIONS:" - - fmtCmdHelp = formatCmdHelp indentLevel cmdHelp + fmtCmdHelp = formatHelpHelp 0 cmdHelp """ \(name)\(fmtHelp) - - \(fmtCmdHeading) \(fmtCmdHelp) """ -# formatCmdHelp : Nat, Help -> Str <- TODO: layout-gen panics when the following annotation is applied! -formatCmdHelp = \n, help -> - when help is +# formatHelpHelp : Nat, Help -> Str +formatHelpHelp = \n, cmdHelp -> + indented = indent n + when cmdHelp is SubCommands cmds -> - Str.joinWith - (List.map cmds \subCmd -> formatSubCommand n subCmd) - "\n\n" + fmtCmdHelp = + Str.joinWith + (List.map cmds \subCmd -> formatSubCommand (n + indentLevel) subCmd) + "\n\n" + + + """ + + \(indented)COMMANDS: + \(fmtCmdHelp) + """ Config configs -> - Str.joinWith (List.map configs \c -> formatConfig n c) "\n" + argConfigs = + filterMap configs (\config -> + when config is + Arg c -> Some c + _ -> None) + + positionaConfigs = + filterMap configs (\config -> + when config is + Positional c -> Some c + _ -> None) + + fmtArgsHelp = + if List.isEmpty argConfigs then + "" + else + helpStr = + argConfigs + |> List.map (\c -> formatArgConfig (n + indentLevel) c) + |> Str.joinWith "\n" + + """ + + \(indented)OPTIONS: + \(helpStr) + """ + + fmtPositionalsHelp = + if List.isEmpty positionaConfigs then + "" + else + helpStr = + positionaConfigs + |> List.map (\c -> formatPositionalConfig (n + indentLevel) c) + |> Str.joinWith "\n" + + """ + + \(indented)POSITIONAL ARGUMENTS: + \(helpStr) + """ + + Str.concat fmtArgsHelp fmtPositionalsHelp formatSubCommand = \n, { name, help } -> indented = indent n - fmtHelp = formatCmdHelp (n + indentLevel) help + fmtHelp = formatHelpHelp (n + indentLevel) help - "\(indented)\(name)\n\(fmtHelp)" + "\(indented)\(name)\(fmtHelp)" -formatConfig : Nat, Config -> Str -formatConfig = \n, { long, short, help, type } -> +formatArgConfig : Nat, ArgConfig -> Str +formatArgConfig = \n, { long, short, help, type } -> indented = indent n formattedShort = @@ -482,6 +639,15 @@ formatConfig = \n, { long, short, help, type } -> "\(indented)--\(long)\(formattedShort)\(formattedHelp) (\(formattedType))" +formatPositionalConfig : Nat, PositionalConfig -> Str +formatPositionalConfig = \n, { name, help } -> + indented = indent n + + formattedHelp = + mapNonEmptyStr help \h -> " \(h)" + + "\(indented)\(name)\(formattedHelp)" + formatType : Type -> Str formatType = \type -> when type is @@ -689,9 +855,9 @@ expect toHelp parser == Config [ - { long: "foo", short: "", help: "the foo flag", type: Str }, - { long: "bar", short: "B", help: "", type: Str }, - { long: "bool", short: "", help: "", type: Bool }, + (Arg { long: "foo", short: "", help: "the foo flag", type: Str }), + (Arg { long: "bar", short: "B", help: "", type: Str }), + (Arg { long: "bool", short: "", help: "", type: Bool }), ] # format argument is missing @@ -760,12 +926,14 @@ expect COMMANDS: login - --user (string) - --pw (string) + OPTIONS: + --user (string) + --pw (string) publish - --file (string) - --url (string) + OPTIONS: + --file (string) + --url (string) """ # format help menu with program help message @@ -782,7 +950,6 @@ expect COMMANDS: login - """ # subcommand parser @@ -857,3 +1024,32 @@ expect The available subcommands are: \t"auth", "publish" """ + +# parse positional argument +expect + parser = positional {name: "foo"} + + parseHelp parser (mark ["myArg"]) == Ok "myArg" + +# parse positional argument with argument flag +expect + parser = + succeed (\foo -> \bar -> "foo: \(foo), bar: \(bar)") + |> withParser (str { long: "foo" }) + |> withParser (positional {name: "bar"}) + + cases = [ + ["--foo", "true", "baz"], + ["baz", "--foo", "true"], + ] + + List.all cases \args -> parseHelp parser (mark args) == Ok "foo: true, bar: baz" + +# parse positional argument with subcommand +expect + parser = choice [ + positional {name: "bar"} + |> subCommand "hello" + ] + + parseHelp parser (mark ["hello", "foo"]) == Ok "foo" From cee38b895a16a88afdf1f9bec95e7cb6cec66cd1 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Wed, 28 Sep 2022 17:43:50 -0500 Subject: [PATCH 20/65] Error on missing positional args --- examples/interactive/cli-platform/Arg.roc | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/examples/interactive/cli-platform/Arg.roc b/examples/interactive/cli-platform/Arg.roc index 83617819f8..7cfbe18213 100644 --- a/examples/interactive/cli-platform/Arg.roc +++ b/examples/interactive/cli-platform/Arg.roc @@ -61,6 +61,8 @@ ParseError a : [ ProgramNameNotProvided Str, ## An argument is required, but it was not found. MissingRequiredArg Str, + ## A positional argument is required, but it was not found. + MissingPositionalArg Str, ## An argument was found, but it didn't have the expected [Type]. WrongType { @@ -406,8 +408,7 @@ parseHelp = \@Parser parser, args -> Positional { name } run -> when run args is Ok {val, newlyTaken: _} -> Ok val - Err NotFound -> Err (MissingRequiredArg name) - Err WrongType -> Err (MissingRequiredArg name) + Err _ -> Err (MissingPositionalArg name) SubCommand cmds -> when nextUnmarked args is @@ -666,6 +667,9 @@ formatError = \err -> MissingRequiredArg arg -> "Argument `--\(arg)` is required but was not provided!" + MissingPositionalArg arg -> + "A positional argument for `\(arg)` is required but was not provided!" + WrongType { arg, expected } -> formattedType = formatType expected @@ -1053,3 +1057,9 @@ expect ] parseHelp parser (mark ["hello", "foo"]) == Ok "foo" + +# missing positional argument +expect + parser = positional {name: "bar"} + + parseHelp parser (mark []) == Err (MissingPositionalArg "bar") From e2c9a8fc178cae9639c38f3139ff5921984bb823 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Wed, 28 Sep 2022 17:53:59 -0500 Subject: [PATCH 21/65] Annotate arg --- examples/interactive/cli-platform/Arg.roc | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/interactive/cli-platform/Arg.roc b/examples/interactive/cli-platform/Arg.roc index 7cfbe18213..e885a45903 100644 --- a/examples/interactive/cli-platform/Arg.roc +++ b/examples/interactive/cli-platform/Arg.roc @@ -487,6 +487,7 @@ i64 = \{ long, short ? "", help ? "" } -> @Parser (Arg { long, short, help, type: I64 } fn) ## Parses a single positional argument as a string. +positional : _ -> Parser Str positional = \{ name, help ? "" } -> fn = \args -> nextUnmarked args From 13369b47d2d4a335fb2cab15b1734c094b6c024a Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Wed, 28 Sep 2022 17:54:38 -0500 Subject: [PATCH 22/65] Format --- examples/interactive/cli-platform/Arg.roc | 58 ++++++++++++----------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/examples/interactive/cli-platform/Arg.roc b/examples/interactive/cli-platform/Arg.roc index e885a45903..cca02a9eac 100644 --- a/examples/interactive/cli-platform/Arg.roc +++ b/examples/interactive/cli-platform/Arg.roc @@ -202,7 +202,7 @@ andMap = \@Parser parser, @Parser mapper -> Positional config run -> Positional config \args -> run args - |> Result.map (\{val, newlyTaken} -> {val: fn val, newlyTaken}) + |> Result.map (\{ val, newlyTaken } -> { val: fn val, newlyTaken }) SubCommand cmds -> mapSubParser = \{ name, parser: parser2 } -> @@ -344,7 +344,7 @@ andMap = \@Parser parser, @Parser mapper -> Positional config run -> Positional config \args -> run args - |> Result.map (\{val, newlyTaken} -> {val: fn val, newlyTaken}) + |> Result.map (\{ val, newlyTaken } -> { val: fn val, newlyTaken }) SubCommand cmds -> mapSubParser = \{ name, parser: parser2 } -> @@ -407,7 +407,7 @@ parseHelp = \@Parser parser, args -> Positional { name } run -> when run args is - Ok {val, newlyTaken: _} -> Ok val + Ok { val, newlyTaken: _ } -> Ok val Err _ -> Err (MissingPositionalArg name) SubCommand cmds -> @@ -490,9 +490,9 @@ i64 = \{ long, short ? "", help ? "" } -> positional : _ -> Parser Str positional = \{ name, help ? "" } -> fn = \args -> - nextUnmarked args + nextUnmarked args |> Result.mapErr (\OutOfBounds -> NotFound) - |> Result.map (\{val, index} -> {val, newlyTaken: Set.insert args.taken index}) + |> Result.map (\{ val, index } -> { val, newlyTaken: Set.insert args.taken index }) @Parser (Positional { name, help } fn) @@ -561,44 +561,48 @@ formatHelp = \@NamedParser { name, help, parser } -> # formatHelpHelp : Nat, Help -> Str formatHelpHelp = \n, cmdHelp -> indented = indent n + when cmdHelp is SubCommands cmds -> - fmtCmdHelp = + fmtCmdHelp = Str.joinWith (List.map cmds \subCmd -> formatSubCommand (n + indentLevel) subCmd) "\n\n" - """ - + \(indented)COMMANDS: \(fmtCmdHelp) """ Config configs -> argConfigs = - filterMap configs (\config -> - when config is - Arg c -> Some c - _ -> None) + filterMap + configs + (\config -> + when config is + Arg c -> Some c + _ -> None) positionaConfigs = - filterMap configs (\config -> - when config is - Positional c -> Some c - _ -> None) + filterMap + configs + (\config -> + when config is + Positional c -> Some c + _ -> None) fmtArgsHelp = if List.isEmpty argConfigs then "" else - helpStr = + helpStr = argConfigs |> List.map (\c -> formatArgConfig (n + indentLevel) c) |> Str.joinWith "\n" """ - + \(indented)OPTIONS: \(helpStr) """ @@ -613,7 +617,7 @@ formatHelpHelp = \n, cmdHelp -> |> Str.joinWith "\n" """ - + \(indented)POSITIONAL ARGUMENTS: \(helpStr) """ @@ -860,9 +864,9 @@ expect toHelp parser == Config [ - (Arg { long: "foo", short: "", help: "the foo flag", type: Str }), - (Arg { long: "bar", short: "B", help: "", type: Str }), - (Arg { long: "bool", short: "", help: "", type: Bool }), + Arg { long: "foo", short: "", help: "the foo flag", type: Str }, + Arg { long: "bar", short: "B", help: "", type: Str }, + Arg { long: "bool", short: "", help: "", type: Bool }, ] # format argument is missing @@ -1032,7 +1036,7 @@ expect # parse positional argument expect - parser = positional {name: "foo"} + parser = positional { name: "foo" } parseHelp parser (mark ["myArg"]) == Ok "myArg" @@ -1041,7 +1045,7 @@ expect parser = succeed (\foo -> \bar -> "foo: \(foo), bar: \(bar)") |> withParser (str { long: "foo" }) - |> withParser (positional {name: "bar"}) + |> withParser (positional { name: "bar" }) cases = [ ["--foo", "true", "baz"], @@ -1053,14 +1057,14 @@ expect # parse positional argument with subcommand expect parser = choice [ - positional {name: "bar"} - |> subCommand "hello" + positional { name: "bar" } + |> subCommand "hello", ] parseHelp parser (mark ["hello", "foo"]) == Ok "foo" # missing positional argument expect - parser = positional {name: "bar"} + parser = positional { name: "bar" } parseHelp parser (mark []) == Err (MissingPositionalArg "bar") From b47e26aa832ad7a57b93ee9be40f3d08fcd739ae Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Fri, 30 Sep 2022 13:35:32 -0500 Subject: [PATCH 23/65] Fix some leftover type errors --- examples/interactive/cli-platform/Arg.roc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/interactive/cli-platform/Arg.roc b/examples/interactive/cli-platform/Arg.roc index cca02a9eac..2b7724a9bd 100644 --- a/examples/interactive/cli-platform/Arg.roc +++ b/examples/interactive/cli-platform/Arg.roc @@ -33,7 +33,7 @@ NamedParser a := { Parser a := [ Succeed a, Arg ArgConfig (MarkedArgs -> Result { newlyTaken : Taken, val : a } [NotFound Str, WrongType { arg : Str, expected : Type }]), - Positional PositionalConfig (MarkedArgs -> Result { newlyTaken : Taken, val : a } [NotFound, WrongType]), + Positional PositionalConfig (MarkedArgs -> Result { newlyTaken : Taken, val : a } [NotFound Str, WrongType { arg : Str, expected : Type }]), # TODO: hiding the record behind an alias currently causes a panic SubCommand (List { @@ -403,7 +403,7 @@ parseHelp = \@Parser parser, args -> when run args is Ok { val, newlyTaken: _ } -> Ok val Err (NotFound long) -> Err (MissingRequiredArg long) - Err (WrongType {arg, expected}) -> Err (WrongType { arg: long, expected: type }) + Err (WrongType {arg, expected}) -> Err (WrongType { arg, expected }) Positional { name } run -> when run args is @@ -491,7 +491,7 @@ positional : _ -> Parser Str positional = \{ name, help ? "" } -> fn = \args -> nextUnmarked args - |> Result.mapErr (\OutOfBounds -> NotFound) + |> Result.mapErr (\OutOfBounds -> (NotFound name)) |> Result.map (\{ val, index } -> { val, newlyTaken: Set.insert args.taken index }) @Parser (Positional { name, help } fn) @@ -849,8 +849,8 @@ expect List.all [ - parseHelp parser ["--foo", "zaz"] == Err (MissingRequiredArg "bar"), - parseHelp parser ["--bar", "zaz"] == Err (MissingRequiredArg "foo"), + parseHelp parser (mark ["--foo", "zaz"]) == Err (MissingRequiredArg "bar"), + parseHelp parser (mark ["--bar", "zaz"]) == Err (MissingRequiredArg "foo"), ] (\b -> b) From 0fceb8573c260a2635d54857e684288bc1da4a27 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Fri, 30 Sep 2022 13:38:40 -0500 Subject: [PATCH 24/65] Simplify parse error logic a bit --- examples/interactive/cli-platform/Arg.roc | 27 ++++++++++------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/examples/interactive/cli-platform/Arg.roc b/examples/interactive/cli-platform/Arg.roc index 2b7724a9bd..655fefa0c9 100644 --- a/examples/interactive/cli-platform/Arg.roc +++ b/examples/interactive/cli-platform/Arg.roc @@ -32,8 +32,8 @@ NamedParser a := { ## needs, consider transforming it into a [NamedParser]. Parser a := [ Succeed a, - Arg ArgConfig (MarkedArgs -> Result { newlyTaken : Taken, val : a } [NotFound Str, WrongType { arg : Str, expected : Type }]), - Positional PositionalConfig (MarkedArgs -> Result { newlyTaken : Taken, val : a } [NotFound Str, WrongType { arg : Str, expected : Type }]), + Arg ArgConfig (MarkedArgs -> Result { newlyTaken : Taken, val : a } (ParseError [])), + Positional PositionalConfig (MarkedArgs -> Result { newlyTaken : Taken, val : a } (ParseError [])), # TODO: hiding the record behind an alias currently causes a panic SubCommand (List { @@ -395,20 +395,17 @@ parse = \@NamedParser parser, args -> parseHelp parser.parser markedArgs -parseHelp : Parser a, MarkedArgs -> Result a (ParseError *) +parseHelp : Parser a, MarkedArgs -> Result a (ParseError []) parseHelp = \@Parser parser, args -> when parser is Succeed val -> Ok val Arg _ run -> - when run args is - Ok { val, newlyTaken: _ } -> Ok val - Err (NotFound long) -> Err (MissingRequiredArg long) - Err (WrongType {arg, expected}) -> Err (WrongType { arg, expected }) + run args + |> Result.map .val - Positional { name } run -> - when run args is - Ok { val, newlyTaken: _ } -> Ok val - Err _ -> Err (MissingPositionalArg name) + Positional _ run -> + run args + |> Result.map .val SubCommand cmds -> when nextUnmarked args is @@ -454,7 +451,7 @@ bool : _ -> Parser Bool # TODO: panics if parameter annotation given bool = \{ long, short ? "", help ? "" } -> fn = \args -> when findOneArg long short args is - Err NotFound -> Err (NotFound long) + Err NotFound -> Err (MissingRequiredArg long) Ok { val, newlyTaken } -> when val is "true" -> Ok { val: Bool.true, newlyTaken } @@ -468,7 +465,7 @@ str : _ -> Parser Str # TODO: panics if parameter annotation given str = \{ long, short ? "", help ? "" } -> fn = \args -> when findOneArg long short args is - Err NotFound -> Err (NotFound long) + Err NotFound -> Err (MissingRequiredArg long) Ok { val, newlyTaken } -> Ok { val, newlyTaken } @Parser (Arg { long, short, help, type: Str } fn) @@ -478,7 +475,7 @@ i64 : _ -> Parser I64 # TODO: panics if parameter annotation given i64 = \{ long, short ? "", help ? "" } -> fn = \args -> when findOneArg long short args is - Err NotFound -> Err (NotFound long) + Err NotFound -> Err (MissingRequiredArg long) Ok { val, newlyTaken } -> Str.toI64 val |> Result.mapErr (\_ -> WrongType { arg: long, expected: I64 }) @@ -491,7 +488,7 @@ positional : _ -> Parser Str positional = \{ name, help ? "" } -> fn = \args -> nextUnmarked args - |> Result.mapErr (\OutOfBounds -> (NotFound name)) + |> Result.mapErr (\OutOfBounds -> (MissingPositionalArg name)) |> Result.map (\{ val, index } -> { val, newlyTaken: Set.insert args.taken index }) @Parser (Positional { name, help } fn) From 3490b4b6ef4e680fdde424f71c83ea75bc063b1c Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Fri, 30 Sep 2022 13:39:02 -0500 Subject: [PATCH 25/65] Format --- examples/interactive/cli-platform/Arg.roc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/interactive/cli-platform/Arg.roc b/examples/interactive/cli-platform/Arg.roc index 655fefa0c9..a97f743252 100644 --- a/examples/interactive/cli-platform/Arg.roc +++ b/examples/interactive/cli-platform/Arg.roc @@ -488,7 +488,7 @@ positional : _ -> Parser Str positional = \{ name, help ? "" } -> fn = \args -> nextUnmarked args - |> Result.mapErr (\OutOfBounds -> (MissingPositionalArg name)) + |> Result.mapErr (\OutOfBounds -> MissingPositionalArg name) |> Result.map (\{ val, index } -> { val, newlyTaken: Set.insert args.taken index }) @Parser (Positional { name, help } fn) From 2709af2aaf9a209badb3aef3c131f7bcf52bbbba Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Sat, 1 Oct 2022 13:34:27 +0200 Subject: [PATCH 26/65] tree is already installed Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com> --- .github/workflows/benchmarks.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index 432b9973ba..58e0ee422c 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -39,9 +39,6 @@ jobs: - uses: actions-rs/toolchain@v1 with: toolchain: stable - - # for debugging - - run: sudo apt install -y tree - name: build benchmark runner run: cd ci/bench-runner && cargo build --release && cd ../.. From e97de12476a8aa3b97d69414c31b77428f327383 Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Tue, 4 Oct 2022 14:42:06 +0200 Subject: [PATCH 27/65] installing nixFlakes is no longer necessary Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com> --- BUILDING_FROM_SOURCE.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/BUILDING_FROM_SOURCE.md b/BUILDING_FROM_SOURCE.md index 39c7104cf4..e2b5963c54 100644 --- a/BUILDING_FROM_SOURCE.md +++ b/BUILDING_FROM_SOURCE.md @@ -28,13 +28,7 @@ sh <(curl -L https://nixos.org/nix/install) --no-daemon sh <(curl -L https://nixos.org/nix/install) --daemon ``` -Open a new terminal and install nixFlakes in your environment: - -```sh -nix-env -iA nixpkgs.nixFlakes -``` - -Edit either `~/.config/nix/nix.conf` or `/etc/nix/nix.conf` and add: +Open a new terminal and edit either `~/.config/nix/nix.conf` or `/etc/nix/nix.conf` and add: ```text experimental-features = nix-command flakes From ad4d98be9cbc52527f21b9c402d26cf2c35a22e6 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Tue, 4 Oct 2022 14:35:33 -0500 Subject: [PATCH 28/65] Add derive key generation for record hashing --- crates/compiler/derive/src/hash.rs | 4 +- crates/compiler/derive_key/src/hash.rs | 40 +++++++++++++--- crates/compiler/test_derive/src/hash.rs | 63 ++++++++++++++++++++++++- 3 files changed, 97 insertions(+), 10 deletions(-) diff --git a/crates/compiler/derive/src/hash.rs b/crates/compiler/derive/src/hash.rs index ab1f079e98..0c6ddab6f5 100644 --- a/crates/compiler/derive/src/hash.rs +++ b/crates/compiler/derive/src/hash.rs @@ -10,5 +10,7 @@ pub(crate) fn derive_hash( key: FlatHashKey, _def_symbol: Symbol, ) -> DerivedBody { - match key {} + match key { + FlatHashKey::Record(_) => todo!(), + } } diff --git a/crates/compiler/derive_key/src/hash.rs b/crates/compiler/derive_key/src/hash.rs index 04c8c6c574..52c8cbc79e 100644 --- a/crates/compiler/derive_key/src/hash.rs +++ b/crates/compiler/derive_key/src/hash.rs @@ -1,7 +1,10 @@ -use roc_module::symbol::Symbol; +use roc_module::{ident::Lowercase, symbol::Symbol}; use roc_types::subs::{Content, FlatType, Subs, Variable}; -use crate::DeriveError; +use crate::{ + util::{check_derivable_ext_var, debug_name_record}, + DeriveError, +}; #[derive(Hash)] pub enum FlatHash { @@ -12,11 +15,16 @@ pub enum FlatHash { } #[derive(Hash, PartialEq, Eq, Debug, Clone)] -pub enum FlatHashKey {} +pub enum FlatHashKey { + // Unfortunate that we must allocate here, c'est la vie + Record(Vec), +} impl FlatHashKey { pub(crate) fn debug_name(&self) -> String { - unreachable!() // yet + match self { + FlatHashKey::Record(fields) => debug_name_record(fields), + } } } @@ -31,8 +39,26 @@ impl FlatHash { Symbol::STR_STR => Ok(SingleLambdaSetImmediate(Symbol::HASH_HASH_STR_BYTES)), _ => Err(Underivable), }, - FlatType::Record(_fields, _ext) => { - Err(Underivable) // yet + FlatType::Record(fields, ext) => { + let (fields_iter, ext) = fields.unsorted_iterator_and_ext(subs, ext); + + check_derivable_ext_var(subs, ext, |ext| { + matches!(ext, Content::Structure(FlatType::EmptyRecord)) + })?; + + let mut field_names = Vec::with_capacity(fields.len()); + for (field_name, record_field) in fields_iter { + if record_field.is_optional() { + // Can't derive a concrete decoder for optional fields, since those are + // compile-time-polymorphic + return Err(Underivable); + } + field_names.push(field_name.clone()); + } + + field_names.sort(); + + Ok(Key(FlatHashKey::Record(field_names))) } FlatType::TagUnion(_tags, _ext) | FlatType::RecursiveTagUnion(_, _tags, _ext) => { Err(Underivable) // yet @@ -40,7 +66,7 @@ impl FlatHash { FlatType::FunctionOrTagUnion(_name_index, _, _) => { Err(Underivable) // yet } - FlatType::EmptyRecord => Err(Underivable), // yet + FlatType::EmptyRecord => Ok(Key(FlatHashKey::Record(vec![]))), FlatType::EmptyTagUnion => { Err(Underivable) // yet } diff --git a/crates/compiler/test_derive/src/hash.rs b/crates/compiler/test_derive/src/hash.rs index cce7969e3b..0c4a95695e 100644 --- a/crates/compiler/test_derive/src/hash.rs +++ b/crates/compiler/test_derive/src/hash.rs @@ -4,11 +4,38 @@ // For the `v!` macro we use uppercase variables when constructing tag unions. #![allow(non_snake_case)] -use crate::{util::check_single_lset_immediate, v}; +use crate::{ + test_key_eq, test_key_neq, + util::{check_derivable, check_single_lset_immediate, check_underivable}, + v, +}; use roc_module::symbol::Symbol; use roc_types::subs::Variable; -use roc_derive_key::DeriveBuiltin::Hash; +use roc_derive_key::{hash::FlatHashKey, DeriveBuiltin::Hash, DeriveError, DeriveKey}; + +test_key_eq! { + Hash, + + same_record: + v!({ a: v!(U8), }), v!({ a: v!(U8), }) + same_record_fields_diff_types: + v!({ a: v!(U8), }), v!({ a: v!(STR), }) + same_record_fields_any_order: + v!({ a: v!(U8), b: v!(U8), c: v!(U8), }), + v!({ c: v!(U8), a: v!(U8), b: v!(U8), }) + explicit_empty_record_and_implicit_empty_record: + v!(EMPTY_RECORD), v!({}) +} + +test_key_neq! { + Hash, + + different_record_fields: + v!({ a: v!(U8), }), v!({ b: v!(U8), }) + record_empty_vs_nonempty: + v!(EMPTY_RECORD), v!({ a: v!(U8), }) +} #[test] fn immediates() { @@ -26,3 +53,35 @@ fn immediates() { check_single_lset_immediate(Hash, v!(Symbol::LIST_LIST v!(U8)), Symbol::HASH_HASH_LIST); check_single_lset_immediate(Hash, v!(Symbol::LIST_LIST v!(STR)), Symbol::HASH_HASH_LIST); } + +#[test] +fn optional_record_field_derive_error() { + check_underivable(Hash, v!({ ?a: v!(U8), }), DeriveError::Underivable); +} + +#[test] +fn derivable_record_ext_flex_var() { + check_derivable( + Hash, + v!({ a: v!(STR), }* ), + DeriveKey::Hash(FlatHashKey::Record(vec!["a".into()])), + ); +} + +#[test] +fn derivable_record_ext_flex_able_var() { + check_derivable( + Hash, + v!({ a: v!(STR), }a has Symbol::DECODE_DECODER ), + DeriveKey::Hash(FlatHashKey::Record(vec!["a".into()])), + ); +} + +#[test] +fn derivable_record_with_record_ext() { + check_derivable( + Hash, + v!({ b: v!(STR), }{ a: v!(STR), } ), + DeriveKey::Hash(FlatHashKey::Record(vec!["a".into(), "b".into()])), + ); +} From 46f111c6dd7748fac8f8e6f6b3d248259cb9502f Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Tue, 4 Oct 2022 15:23:41 -0500 Subject: [PATCH 29/65] Add hash deriving for records --- crates/compiler/derive/src/hash.rs | 193 ++++++++++++++++++++++-- crates/compiler/test_derive/src/hash.rs | 66 +++++++- 2 files changed, 249 insertions(+), 10 deletions(-) diff --git a/crates/compiler/derive/src/hash.rs b/crates/compiler/derive/src/hash.rs index 0c6ddab6f5..5c5b705d87 100644 --- a/crates/compiler/derive/src/hash.rs +++ b/crates/compiler/derive/src/hash.rs @@ -1,16 +1,191 @@ //! Derivers for the `Hash` ability. +use std::iter::once; + +use roc_can::{ + expr::{AnnotatedMark, ClosureData, Expr, Recursive}, + pattern::Pattern, +}; use roc_derive_key::hash::FlatHashKey; -use roc_module::symbol::Symbol; +use roc_module::{called_via::CalledVia, ident::Lowercase, symbol::Symbol}; +use roc_region::all::Loc; +use roc_types::{ + subs::{ + Content, FlatType, LambdaSet, OptVariable, RecordFields, SubsSlice, UnionLambdas, Variable, + VariableSubsSlice, + }, + types::RecordField, +}; -use crate::{util::Env, DerivedBody}; +use crate::{synth_var, util::Env, DerivedBody}; -pub(crate) fn derive_hash( - _env: &mut Env<'_>, - key: FlatHashKey, - _def_symbol: Symbol, -) -> DerivedBody { - match key { - FlatHashKey::Record(_) => todo!(), +pub(crate) fn derive_hash(env: &mut Env<'_>, key: FlatHashKey, def_symbol: Symbol) -> DerivedBody { + let (body, body_type) = match key { + FlatHashKey::Record(fields) => hash_record(env, def_symbol, fields), + }; + + let specialization_lambda_sets = + env.get_specialization_lambda_sets(body_type, Symbol::HASH_HASH); + + DerivedBody { + body, + body_type, + specialization_lambda_sets, } } + +fn hash_record(env: &mut Env<'_>, fn_name: Symbol, fields: Vec) -> (Expr, Variable) { + // Suppose rcd = { f1, ..., fn }. + // Build a generalized type t_rcd = { f1: t1, ..., fn: tn }, with fresh t1, ..., tn, + // so that we can re-use the derived impl for many records of the same fields. + let (record_var, record_fields) = { + let flex_fields = fields + .into_iter() + .map(|name| { + ( + name, + RecordField::Required(env.subs.fresh_unnamed_flex_var()), + ) + }) + .collect::>(); + let fields = RecordFields::insert_into_subs(env.subs, flex_fields); + let record_var = synth_var( + env.subs, + Content::Structure(FlatType::Record(fields, Variable::EMPTY_RECORD)), + ); + + (record_var, fields) + }; + + // Now, a hasher for this record is + // + // hash_rcd : hasher, { f1: t1, ..., fn: tn } -> hasher | hasher has Hasher + // hash_rcd = \hasher, rcd -> + // Hash.hash ( + // Hash.hash + // ... + // (Hash.hash hasher rcd.f1) + // ... + // rcd.f_n1) + // rcd.fn + // + // So, just a build a fold travelling up the fields. + let rcd_sym = env.new_symbol("rcd"); + + let hasher_sym = env.new_symbol("hasher"); + let hasher_var = synth_var(env.subs, Content::FlexAbleVar(None, Symbol::HASH_HASHER)); + + let (body, body_var) = record_fields.iter_all().fold( + (Expr::Var(hasher_sym), hasher_var), + |(body, body_var), (field_name, field_var, _)| { + let field_name = env.subs[field_name].clone(); + let field_var = env.subs[field_var].clone(); + + let field_access = Expr::Access { + record_var, + field_var, + ext_var: env.subs.fresh_unnamed_flex_var(), + loc_expr: Box::new(Loc::at_zero(Expr::Var(rcd_sym))), + field: field_name, + }; + + let (hash_fn_data, returned_hasher_var) = { + // build `Hash.hash ...` function type + // + // hasher, val -[uls]-> hasher | hasher has Hasher, val has Hash + let exposed_hash_fn_var = env.import_builtin_symbol_var(Symbol::HASH_HASH); + + // (typeof body), (typeof field) -[clos]-> hasher_result + let this_arguments_slice = + VariableSubsSlice::insert_into_subs(env.subs, [body_var, field_var]); + let this_hash_clos_var = env.subs.fresh_unnamed_flex_var(); + let this_hasher_result_var = env.subs.fresh_unnamed_flex_var(); + let this_hash_fn_var = synth_var( + env.subs, + Content::Structure(FlatType::Func( + this_arguments_slice, + this_hash_clos_var, + this_hasher_result_var, + )), + ); + + // hasher, val -[uls]-> hasher | hasher has Hasher, val has Hash + // ~ (typeof body), (typeof field) -[clos]-> hasher_result + env.unify(exposed_hash_fn_var, this_hash_fn_var); + + // Hash.hash : hasher, (typeof field) -[clos]-> hasher | hasher has Hasher, (typeof field) has Hash + let hash_fn_head = Expr::AbilityMember(Symbol::HASH_HASH, None, this_hash_fn_var); + let hash_fn_data = Box::new(( + this_hash_fn_var, + Loc::at_zero(hash_fn_head), + this_hash_clos_var, + this_hasher_result_var, + )); + + (hash_fn_data, this_hasher_result_var) + }; + + let hash_arguments = vec![ + (body_var, Loc::at_zero(body)), + (field_var, Loc::at_zero(field_access)), + ]; + let call_hash = Expr::Call(hash_fn_data, hash_arguments, CalledVia::Space); + + (call_hash, returned_hasher_var) + }, + ); + + // Finally, build the closure + // \hasher, rcd -> body + + let (fn_var, fn_clos_var) = { + // Create fn_var for ambient capture; we fix it up below. + let fn_var = synth_var(env.subs, Content::Error); + + // -[fn_name]-> + let fn_captures = vec![]; + let fn_name_labels = UnionLambdas::insert_into_subs(env.subs, once((fn_name, fn_captures))); + let fn_clos_var = synth_var( + env.subs, + Content::LambdaSet(LambdaSet { + solved: fn_name_labels, + recursion_var: OptVariable::NONE, + unspecialized: SubsSlice::default(), + ambient_function: fn_var, + }), + ); + + // hasher, rcd_var -[fn_name]-> (hasher = body_var) + let args_slice = SubsSlice::insert_into_subs(env.subs, [hasher_var, record_var]); + env.subs.set_content( + fn_var, + Content::Structure(FlatType::Func(args_slice, fn_clos_var, body_var)), + ); + + (fn_var, fn_clos_var) + }; + + let clos_expr = Expr::Closure(ClosureData { + function_type: fn_var, + closure_type: fn_clos_var, + return_type: body_var, + name: fn_name, + captured_symbols: vec![], + recursive: Recursive::NotRecursive, + arguments: vec![ + ( + hasher_var, + AnnotatedMark::known_exhaustive(), + Loc::at_zero(Pattern::Identifier(hasher_sym)), + ), + ( + record_var, + AnnotatedMark::known_exhaustive(), + Loc::at_zero(Pattern::Identifier(rcd_sym)), + ), + ], + loc_body: Box::new(Loc::at_zero(body)), + }); + + (clos_expr, fn_var) +} diff --git a/crates/compiler/test_derive/src/hash.rs b/crates/compiler/test_derive/src/hash.rs index 0c4a95695e..842e8004ec 100644 --- a/crates/compiler/test_derive/src/hash.rs +++ b/crates/compiler/test_derive/src/hash.rs @@ -6,9 +6,10 @@ use crate::{ test_key_eq, test_key_neq, - util::{check_derivable, check_single_lset_immediate, check_underivable}, + util::{check_derivable, check_single_lset_immediate, check_underivable, derive_test}, v, }; +use insta::assert_snapshot; use roc_module::symbol::Symbol; use roc_types::subs::Variable; @@ -85,3 +86,66 @@ fn derivable_record_with_record_ext() { DeriveKey::Hash(FlatHashKey::Record(vec!["a".into(), "b".into()])), ); } + +#[test] +fn empty_record() { + derive_test(Hash, v!(EMPTY_RECORD), |golden| { + assert_snapshot!(golden, @r###" + # derived for {} + # hasher, {} -[[hash_{}(0)]]-> hasher | hasher has Hasher + # hasher, {} -[[hash_{}(0)]]-> hasher | hasher has Hasher + # Specialization lambda sets: + # @<1>: [[hash_{}(0)]] + #Derived.hash_{} = \#Derived.hasher, #Derived.rcd -> #Derived.hasher + "### + ) + }) +} + +#[test] +fn zero_field_record() { + derive_test(Hash, v!({}), |golden| { + assert_snapshot!(golden, @r###" + # derived for {} + # hasher, {} -[[hash_{}(0)]]-> hasher | hasher has Hasher + # hasher, {} -[[hash_{}(0)]]-> hasher | hasher has Hasher + # Specialization lambda sets: + # @<1>: [[hash_{}(0)]] + #Derived.hash_{} = \#Derived.hasher, #Derived.rcd -> #Derived.hasher + "### + ) + }) +} + +#[test] +fn one_field_record() { + derive_test(Hash, v!({ a: v!(U8), }), |golden| { + assert_snapshot!(golden, @r###" + # derived for { a : U8 } + # hasher, { a : a } -[[hash_{a}(0)]]-> hasher | a has Hash, hasher has Hasher + # hasher, { a : a } -[[hash_{a}(0)]]-> hasher | a has Hash, hasher has Hasher + # Specialization lambda sets: + # @<1>: [[hash_{a}(0)]] + #Derived.hash_{a} = + \#Derived.hasher, #Derived.rcd -> Hash.hash #Derived.hasher #Derived.rcd.a + "### + ) + }) +} + +#[test] +fn two_field_record() { + derive_test(Hash, v!({ a: v!(U8), b: v!(STR), }), |golden| { + assert_snapshot!(golden, @r###" + # derived for { a : U8, b : Str } + # hasher, { a : a, b : a1 } -[[hash_{a,b}(0)]]-> hasher | a has Hash, a1 has Hash, hasher has Hasher + # hasher, { a : a, b : a1 } -[[hash_{a,b}(0)]]-> hasher | a has Hash, a1 has Hash, hasher has Hasher + # Specialization lambda sets: + # @<1>: [[hash_{a,b}(0)]] + #Derived.hash_{a,b} = + \#Derived.hasher, #Derived.rcd -> + Hash.hash (Hash.hash #Derived.hasher #Derived.rcd.a) #Derived.rcd.b + "### + ) + }) +} From 5870de54aee724e4b066658b14da5cb785152e0c Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Tue, 4 Oct 2022 15:29:20 -0500 Subject: [PATCH 30/65] Add gen tests for record hash deriving --- crates/compiler/test_gen/src/gen_abilities.rs | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/crates/compiler/test_gen/src/gen_abilities.rs b/crates/compiler/test_gen/src/gen_abilities.rs index 40ae81efd9..bad342a99d 100644 --- a/crates/compiler/test_gen/src/gen_abilities.rs +++ b/crates/compiler/test_gen/src/gen_abilities.rs @@ -1330,4 +1330,47 @@ mod hash { ) } } + + mod derived { + use super::{assert_evals_to, build_test}; + use roc_std::RocList; + + #[test] + fn empty_record() { + assert_evals_to!( + &build_test(r#"{}"#), + RocList::from_slice(&[] as &[u8]), + RocList + ) + } + + #[test] + fn record_of_u8_and_str() { + assert_evals_to!( + &build_test(r#"{ a: 15u8, b: "bc" }"#), + RocList::from_slice(&[15, 98, 99]), + RocList + ) + } + + #[test] + fn record_of_records() { + assert_evals_to!( + &build_test(r#"{ a: { b: 15u8, c: "bc" }, d: { b: 23u8, e: "ef" } }"#), + RocList::from_slice(&[15, 98, 99, 23, 101, 102]), + RocList + ) + } + + #[test] + fn record_of_list_of_records() { + assert_evals_to!( + &build_test( + r#"{ a: [ { b: 15u8 }, { b: 23u8 } ], b: [ { c: 45u8 }, { c: 73u8 } ] }"# + ), + RocList::from_slice(&[15, 23, 45, 73]), + RocList + ) + } + } } From 7421485973963fa2ae5498a6d62a24a647cdc2e7 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Tue, 4 Oct 2022 15:37:03 -0500 Subject: [PATCH 31/65] Remove clone --- crates/compiler/derive/src/hash.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/compiler/derive/src/hash.rs b/crates/compiler/derive/src/hash.rs index 5c5b705d87..be8e35aa3b 100644 --- a/crates/compiler/derive/src/hash.rs +++ b/crates/compiler/derive/src/hash.rs @@ -79,7 +79,7 @@ fn hash_record(env: &mut Env<'_>, fn_name: Symbol, fields: Vec) -> (E (Expr::Var(hasher_sym), hasher_var), |(body, body_var), (field_name, field_var, _)| { let field_name = env.subs[field_name].clone(); - let field_var = env.subs[field_var].clone(); + let field_var = env.subs[field_var]; let field_access = Expr::Access { record_var, From 4ebe1b2bceb4c0d3b93ed70fc55e5d1dc5ac9946 Mon Sep 17 00:00:00 2001 From: Brendan Hansknecht Date: Wed, 5 Oct 2022 08:11:02 -0700 Subject: [PATCH 32/65] Avoid allocating a new list when calling List.sublist --- crates/compiler/builtins/bitcode/src/list.zig | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/crates/compiler/builtins/bitcode/src/list.zig b/crates/compiler/builtins/bitcode/src/list.zig index 467ee2ff37..e244cbe45f 100644 --- a/crates/compiler/builtins/bitcode/src/list.zig +++ b/crates/compiler/builtins/bitcode/src/list.zig @@ -517,17 +517,25 @@ pub fn listSublist( len: usize, dec: Dec, ) callconv(.C) RocList { - if (len == 0) { + const size = list.len(); + if (len == 0 or start >= size) { + if (list.isUnique()) { + // Decrement the reference counts of all elements. + if (list.bytes) |source_ptr| { + var i: usize = 0; + while (i < size) : (i += 1) { + const element = source_ptr + i * element_width; + dec(element); + } + var output = list; + output.length = 0; + return output; + } + } return RocList.empty(); } if (list.bytes) |source_ptr| { - const size = list.len(); - - if (start >= size) { - return RocList.empty(); - } - const keep_len = std.math.min(len, size - start); const drop_start_len = start; const drop_end_len = size - (start + keep_len); @@ -546,10 +554,17 @@ pub fn listSublist( dec(element); } - if (start == 0 and list.isUnique()) { + if (list.isUnique()) { var output = list; output.length = keep_len; - return output; + if (start == 0) { + return output; + } else { + // We want memmove due to aliasing. Zig does not expose it directly. + // Instead use copy which can write to aliases as long as the dest is before the source. + mem.copy(u8, source_ptr[0 .. keep_len * element_width], source_ptr[start * element_width .. (start + keep_len) * element_width]); + return output; + } } else { const output = RocList.allocate(alignment, keep_len, element_width); const target_ptr = output.bytes orelse unreachable; From ca92b5e8e881bfcea92f0b02df5fa328d35711b5 Mon Sep 17 00:00:00 2001 From: Brendan Hansknecht Date: Wed, 5 Oct 2022 08:11:10 -0700 Subject: [PATCH 33/65] Increase the inline threshold --- crates/compiler/gen_llvm/src/llvm/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/compiler/gen_llvm/src/llvm/build.rs b/crates/compiler/gen_llvm/src/llvm/build.rs index 6f961c26e3..a8af7bc1e4 100644 --- a/crates/compiler/gen_llvm/src/llvm/build.rs +++ b/crates/compiler/gen_llvm/src/llvm/build.rs @@ -714,7 +714,7 @@ pub fn construct_optimization_passes<'a>( OptLevel::Optimize => { pmb.set_optimization_level(OptimizationLevel::Aggressive); // this threshold seems to do what we want - pmb.set_inliner_with_threshold(275); + pmb.set_inliner_with_threshold(750); } } From 2504dd7e122d49eec9f91bf46d1097ddcda66a92 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Wed, 5 Oct 2022 13:09:50 -0500 Subject: [PATCH 34/65] Bump CI From 178b63426656765480b5116d0ada5dc487b9b8ca Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Mon, 3 Oct 2022 15:19:38 -0500 Subject: [PATCH 35/65] Treat single quote literals as ranged numbers for inference purposes --- crates/compiler/can/src/copy.rs | 2 +- crates/compiler/can/src/expr.rs | 18 +++++-- crates/compiler/can/src/module.rs | 2 +- crates/compiler/constrain/src/builtins.rs | 48 ++++++++++++++++++- crates/compiler/constrain/src/expr.rs | 12 ++++- crates/compiler/mono/src/ir.rs | 18 ++++--- crates/compiler/solve/tests/solve_expr.rs | 45 +++++++++++++++++ .../compiler/test_derive/src/pretty_print.rs | 2 +- crates/compiler/types/src/num.rs | 20 ++++++++ crates/reporting/tests/test_reporting.rs | 28 +++++++++++ 10 files changed, 179 insertions(+), 16 deletions(-) diff --git a/crates/compiler/can/src/copy.rs b/crates/compiler/can/src/copy.rs index 5722dcaf27..5deced7c19 100644 --- a/crates/compiler/can/src/copy.rs +++ b/crates/compiler/can/src/copy.rs @@ -259,7 +259,7 @@ fn deep_copy_expr_help(env: &mut C, copied: &mut Vec, expr Int(v1, v2, str, val, bound) => Int(sub!(*v1), sub!(*v2), str.clone(), *val, *bound), Float(v1, v2, str, val, bound) => Float(sub!(*v1), sub!(*v2), str.clone(), *val, *bound), Str(str) => Str(str.clone()), - SingleQuote(char) => SingleQuote(*char), + SingleQuote(v1, v2, char, bound) => SingleQuote(sub!(*v1), sub!(*v2), *char, *bound), List { elem_var, loc_elems, diff --git a/crates/compiler/can/src/expr.rs b/crates/compiler/can/src/expr.rs index 65bfe3f083..1483e190db 100644 --- a/crates/compiler/can/src/expr.rs +++ b/crates/compiler/can/src/expr.rs @@ -22,6 +22,7 @@ use roc_parse::ast::{self, Defs, EscapedChar, StrLiteral}; use roc_parse::pattern::PatternType::*; use roc_problem::can::{PrecedenceProblem, Problem, RuntimeError}; use roc_region::all::{Loc, Region}; +use roc_types::num::SingleQuoteBound; use roc_types::subs::{ExhaustiveMark, IllegalCycleMark, RedundantMark, VarStore, Variable}; use roc_types::types::{Alias, Category, LambdaSet, OptAbleVar, Type}; use std::fmt::{Debug, Display}; @@ -91,7 +92,8 @@ pub enum Expr { Int(Variable, Variable, Box, IntValue, IntBound), Float(Variable, Variable, Box, f64, FloatBound), Str(Box), - SingleQuote(char), + // Number variable, precision variable, value, bound + SingleQuote(Variable, Variable, char, SingleQuoteBound), List { elem_var: Variable, loc_elems: Vec>, @@ -637,7 +639,15 @@ pub fn canonicalize_expr<'a>( let mut it = string.chars().peekable(); if let Some(char) = it.next() { if it.peek().is_none() { - (Expr::SingleQuote(char), Output::default()) + ( + Expr::SingleQuote( + var_store.fresh(), + var_store.fresh(), + char, + SingleQuoteBound::from_char(char), + ), + Output::default(), + ) } else { // multiple chars is found let error = roc_problem::can::RuntimeError::MultipleCharsInSingleQuote(region); @@ -1642,7 +1652,7 @@ pub fn inline_calls(var_store: &mut VarStore, scope: &mut Scope, expr: Expr) -> | other @ Int(..) | other @ Float(..) | other @ Str { .. } - | other @ SingleQuote(_) + | other @ SingleQuote(..) | other @ RuntimeError(_) | other @ EmptyRecord | other @ Accessor { .. } @@ -2703,7 +2713,7 @@ fn get_lookup_symbols(expr: &Expr, var_store: &mut VarStore) -> Vec<(Symbol, Var | Expr::Str(_) | Expr::ZeroArgumentTag { .. } | Expr::Accessor(_) - | Expr::SingleQuote(_) + | Expr::SingleQuote(..) | Expr::EmptyRecord | Expr::TypedHole(_) | Expr::RuntimeError(_) diff --git a/crates/compiler/can/src/module.rs b/crates/compiler/can/src/module.rs index e6c71422e0..41919ed091 100644 --- a/crates/compiler/can/src/module.rs +++ b/crates/compiler/can/src/module.rs @@ -1038,7 +1038,7 @@ fn fix_values_captured_in_closure_expr( | Int(..) | Float(..) | Str(_) - | SingleQuote(_) + | SingleQuote(..) | Var(_) | AbilityMember(..) | EmptyRecord diff --git a/crates/compiler/constrain/src/builtins.rs b/crates/compiler/constrain/src/builtins.rs index e0925dcbb5..d26dc58b34 100644 --- a/crates/compiler/constrain/src/builtins.rs +++ b/crates/compiler/constrain/src/builtins.rs @@ -4,7 +4,7 @@ use roc_can::expected::Expected::{self, *}; use roc_can::num::{FloatBound, FloatWidth, IntBound, IntLitWidth, NumBound, SignDemand}; use roc_module::symbol::Symbol; use roc_region::all::Region; -use roc_types::num::NumericRange; +use roc_types::num::{NumericRange, SingleQuoteBound}; use roc_types::subs::Variable; use roc_types::types::Type::{self, *}; use roc_types::types::{AliasKind, Category}; @@ -99,6 +99,42 @@ pub fn int_literal( constraints.exists([num_var], and_constraint) } +pub fn single_quote_literal( + constraints: &mut Constraints, + num_var: Variable, + precision_var: Variable, + expected: Expected, + region: Region, + bound: SingleQuoteBound, +) -> Constraint { + let reason = Reason::IntLiteral; + + // Always add the bound first; this improves the resolved type quality in case it's an alias like "U8". + let mut constrs = ArrayVec::<_, 3>::new(); + let num_type = add_numeric_bound_constr( + constraints, + &mut constrs, + num_var, + precision_var, + bound, + region, + Category::Character, + ); + + constrs.extend([ + constraints.equal_types( + num_type.clone(), + ForReason(reason, num_int(Type::Variable(precision_var)), region), + Category::Character, + region, + ), + constraints.equal_types(num_type, expected, Category::Character, region), + ]); + + let and_constraint = constraints.and_constraint(constrs); + constraints.exists([num_var], and_constraint) +} + #[inline(always)] pub fn float_literal( constraints: &mut Constraints, @@ -332,6 +368,16 @@ impl TypedNumericBound for NumBound { } } +impl TypedNumericBound for SingleQuoteBound { + fn numeric_bound(&self) -> NumericBound { + match self { + &SingleQuoteBound::AtLeast { width } => { + NumericBound::Range(NumericRange::IntAtLeastEitherSign(width)) + } + } + } +} + /// A bound placed on a number because of its literal value. /// e.g. `-5` cannot be unsigned, and 300 does not fit in a U8 #[derive(Debug, Clone, Copy, PartialEq, Eq)] diff --git a/crates/compiler/constrain/src/expr.rs b/crates/compiler/constrain/src/expr.rs index 9eb996941b..869b063901 100644 --- a/crates/compiler/constrain/src/expr.rs +++ b/crates/compiler/constrain/src/expr.rs @@ -1,7 +1,8 @@ use std::ops::Range; use crate::builtins::{ - empty_list_type, float_literal, int_literal, list_type, num_literal, num_u32, str_type, + empty_list_type, float_literal, int_literal, list_type, num_literal, single_quote_literal, + str_type, }; use crate::pattern::{constrain_pattern, PatternState}; use roc_can::annotation::IntroducedVariables; @@ -292,7 +293,14 @@ pub fn constrain_expr( constraints.exists(vars, and_constraint) } Str(_) => constraints.equal_types(str_type(), expected, Category::Str, region), - SingleQuote(_) => constraints.equal_types(num_u32(), expected, Category::Character, region), + SingleQuote(num_var, precision_var, _, bound) => single_quote_literal( + constraints, + *num_var, + *precision_var, + expected, + region, + *bound, + ), List { elem_var, loc_elems, diff --git a/crates/compiler/mono/src/ir.rs b/crates/compiler/mono/src/ir.rs index 80b08ebb3a..60394efba4 100644 --- a/crates/compiler/mono/src/ir.rs +++ b/crates/compiler/mono/src/ir.rs @@ -4027,12 +4027,18 @@ pub fn with_hole<'a>( hole, ), - SingleQuote(character) => Stmt::Let( - assigned, - Expr::Literal(Literal::Int((character as i128).to_ne_bytes())), - Layout::int_width(IntWidth::I32), - hole, - ), + SingleQuote(_, _, character, _) => { + let layout = layout_cache + .from_var(env.arena, variable, env.subs) + .unwrap(); + + Stmt::Let( + assigned, + Expr::Literal(Literal::Int((character as i128).to_ne_bytes())), + layout, + hole, + ) + } LetNonRec(def, cont) => from_can_let( env, procs, diff --git a/crates/compiler/solve/tests/solve_expr.rs b/crates/compiler/solve/tests/solve_expr.rs index 2abc12d6cc..534c6cabaa 100644 --- a/crates/compiler/solve/tests/solve_expr.rs +++ b/crates/compiler/solve/tests/solve_expr.rs @@ -7841,4 +7841,49 @@ mod solve_expr { "hasher -> hasher | hasher has Hasher", ); } + + #[test] + fn check_char_as_u8() { + infer_eq_without_problem( + indoc!( + r#" + x : U8 + x = '.' + + x + "# + ), + "U8", + ); + } + + #[test] + fn check_char_as_u16() { + infer_eq_without_problem( + indoc!( + r#" + x : U16 + x = '.' + + x + "# + ), + "U16", + ); + } + + #[test] + fn check_char_as_u32() { + infer_eq_without_problem( + indoc!( + r#" + x : U32 + x = '.' + + x + "# + ), + "U32", + ); + } } diff --git a/crates/compiler/test_derive/src/pretty_print.rs b/crates/compiler/test_derive/src/pretty_print.rs index 953ea05057..9493458b4c 100644 --- a/crates/compiler/test_derive/src/pretty_print.rs +++ b/crates/compiler/test_derive/src/pretty_print.rs @@ -58,7 +58,7 @@ fn expr<'a>(c: &Ctx, p: EPrec, f: &'a Arena<'a>, e: &'a Expr) -> DocBuilder<'a, match e { Num(_, n, _, _) | Int(_, _, n, _, _) | Float(_, _, n, _, _) => f.text(&**n), Str(s) => f.text(format!(r#""{}""#, s)), - SingleQuote(c) => f.text(format!("'{}'", c)), + SingleQuote(_, _, c, _) => f.text(format!("'{}'", c)), List { elem_var: _, loc_elems, diff --git a/crates/compiler/types/src/num.rs b/crates/compiler/types/src/num.rs index 73b52860f7..74cce37dcf 100644 --- a/crates/compiler/types/src/num.rs +++ b/crates/compiler/types/src/num.rs @@ -328,6 +328,26 @@ pub enum NumBound { }, } +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub enum SingleQuoteBound { + AtLeast { width: IntLitWidth }, +} + +impl SingleQuoteBound { + pub fn from_char(c: char) -> Self { + let n = c as u32; + let width = if n > u16::MAX as _ { + IntLitWidth::U32 + } else if n > u8::MAX as _ { + IntLitWidth::U16 + } else { + IntLitWidth::U8 + }; + + Self::AtLeast { width } + } +} + pub const fn int_lit_width_to_variable(w: IntLitWidth) -> Variable { match w { IntLitWidth::U8 => Variable::U8, diff --git a/crates/reporting/tests/test_reporting.rs b/crates/reporting/tests/test_reporting.rs index 96749a5018..de8e16fb4c 100644 --- a/crates/reporting/tests/test_reporting.rs +++ b/crates/reporting/tests/test_reporting.rs @@ -11072,4 +11072,32 @@ All branches in an `if` must have the same type! U8 "### ); + + test_report!( + big_char_does_not_fit_in_u8, + indoc!( + r#" + digits : List U8 + digits = List.range '0' '9' + + List.contains digits '☃' + "# + ), + @r###" + ── TYPE MISMATCH ───────────────────────────────────────── /code/proj/Main.roc ─ + + This 2nd argument to `contains` has an unexpected type: + + 7│ List.contains digits '☃' + ^^^^^ + + The argument is a Unicode scalar value of type: + + U16, I32, U32, I64, Nat, U64, I128, or U128 + + But `contains` needs its 2nd argument to be: + + U8 + "### + ); } From 9054266a76274e09e0fc8011383f2d418c99a182 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Mon, 3 Oct 2022 15:33:49 -0500 Subject: [PATCH 36/65] Simplify Json.roc --- crates/compiler/builtins/roc/Json.roc | 29 +++++++++++++-------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/crates/compiler/builtins/roc/Json.roc b/crates/compiler/builtins/roc/Json.roc index 3dca470cf5..e7926e0310 100644 --- a/crates/compiler/builtins/roc/Json.roc +++ b/crates/compiler/builtins/roc/Json.roc @@ -187,9 +187,8 @@ takeWhile = \list, predicate -> helper { taken: [], rest: list } -asciiByte = \b -> Num.toU8 b - -digits = List.range (asciiByte '0') (asciiByte '9' + 1) +digits : List U8 +digits = List.range '0' ('9' + 1) takeDigits = \bytes -> takeWhile bytes \n -> List.contains digits n @@ -201,7 +200,7 @@ takeFloat = \bytes -> Ok 46 -> # 46 = . { taken: floatPart, rest: afterAll } = takeDigits (List.split rest 1).others builtFloat = - List.concat (List.append intPart (asciiByte '.')) floatPart + List.concat (List.append intPart '.') floatPart { taken: builtFloat, rest: afterAll } @@ -305,14 +304,14 @@ decodeBool = Decode.custom \bytes, @Json {} -> # Note: this could be more performant by traversing both branches char-by-char. # Doing that would also make `rest` more correct in the erroring case. if - maybeFalse == [asciiByte 'f', asciiByte 'a', asciiByte 'l', asciiByte 's', asciiByte 'e'] + maybeFalse == ['f', 'a', 'l', 's', 'e'] then { result: Ok Bool.false, rest: afterFalse } else { before: maybeTrue, others: afterTrue } = List.split bytes 4 if - maybeTrue == [asciiByte 't', asciiByte 'r', asciiByte 'u', asciiByte 'e'] + maybeTrue == ['t', 'r', 'u', 'e'] then { result: Ok Bool.true, rest: afterTrue } else @@ -323,10 +322,10 @@ jsonString = \bytes -> { before, others: afterStartingQuote } = List.split bytes 1 if - before == [asciiByte '"'] + before == ['"'] then # TODO: handle escape sequences - { taken: strSequence, rest } = takeWhile afterStartingQuote \n -> n != asciiByte '"' + { taken: strSequence, rest } = takeWhile afterStartingQuote \n -> n != '"' when Str.fromUtf8 strSequence is Ok s -> @@ -351,7 +350,7 @@ decodeList = \decodeElem -> Decode.custom \bytes, @Json {} -> { before: afterElem, others } = List.split rest 1 if - afterElem == [asciiByte ','] + afterElem == [','] then decodeElems others (List.append accum val) else @@ -362,7 +361,7 @@ decodeList = \decodeElem -> Decode.custom \bytes, @Json {} -> { before, others: afterStartingBrace } = List.split bytes 1 if - before == [asciiByte '['] + before == ['['] then # TODO: empty lists when decodeElems afterStartingBrace [] is @@ -371,7 +370,7 @@ decodeList = \decodeElem -> Decode.custom \bytes, @Json {} -> { before: maybeEndingBrace, others: afterEndingBrace } = List.split rest 1 if - maybeEndingBrace == [asciiByte ']'] + maybeEndingBrace == [']'] then { result: Ok vals, rest: afterEndingBrace } else @@ -393,10 +392,10 @@ parseExactChar = \bytes, char -> Err _ -> { result: Err TooShort, rest: bytes } openBrace : List U8 -> DecodeResult {} -openBrace = \bytes -> parseExactChar bytes (asciiByte '{') +openBrace = \bytes -> parseExactChar bytes '{' closingBrace : List U8 -> DecodeResult {} -closingBrace = \bytes -> parseExactChar bytes (asciiByte '}') +closingBrace = \bytes -> parseExactChar bytes '}' recordKey : List U8 -> DecodeResult Str recordKey = \bytes -> jsonString bytes @@ -405,10 +404,10 @@ anything : List U8 -> DecodeResult {} anything = \bytes -> { result: Err TooShort, rest: bytes } colon : List U8 -> DecodeResult {} -colon = \bytes -> parseExactChar bytes (asciiByte ':') +colon = \bytes -> parseExactChar bytes ':' comma : List U8 -> DecodeResult {} -comma = \bytes -> parseExactChar bytes (asciiByte ',') +comma = \bytes -> parseExactChar bytes ',' tryDecode : DecodeResult a, ({ val : a, rest : List U8 } -> DecodeResult b) -> DecodeResult b tryDecode = \{ result, rest }, mapper -> From 811c8554ac87c681e262170563bcd94497c2fb5f Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Mon, 3 Oct 2022 15:36:46 -0500 Subject: [PATCH 37/65] Simplify Parser example --- examples/parser/Parser/CSV.roc | 10 +++++----- examples/parser/Parser/Str.roc | 3 +-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/examples/parser/Parser/CSV.roc b/examples/parser/Parser/CSV.roc index 48f7933974..e801d5390d 100644 --- a/examples/parser/Parser/CSV.roc +++ b/examples/parser/Parser/CSV.roc @@ -175,7 +175,7 @@ escapedCsvField = between escapedContents dquote dquote escapedContents = many ( oneOf [ - twodquotes |> map (\_ -> 34), # An escaped double quote + twodquotes |> map (\_ -> '"'), comma, cr, lf, @@ -187,10 +187,10 @@ twodquotes = Parser.Str.string "\"\"" nonescapedCsvField : Parser RawStr CSVField nonescapedCsvField = many textdata -comma = codeunit 44 # ',' -dquote = codeunit 34 # '"' +comma = codeunit ',' +dquote = codeunit '"' endOfLine = alt (ignore crlf) (ignore lf) -cr = codeunit 13 # '\r' -lf = codeunit 10 # '\n' +cr = codeunit '\r' +lf = codeunit '\n' crlf = Parser.Str.string "\r\n" textdata = codeunitSatisfies (\x -> (x >= 32 && x <= 33) || (x >= 35 && x <= 43) || (x >= 45 && x <= 126)) # Any printable char except " (34) and , (44) diff --git a/examples/parser/Parser/Str.roc b/examples/parser/Parser/Str.roc index e1f11c9d97..b01edbad6a 100644 --- a/examples/parser/Parser/Str.roc +++ b/examples/parser/Parser/Str.roc @@ -177,10 +177,9 @@ anyString = buildPrimitiveParser \fieldRawString -> digit : Parser RawStr U8 digit = digitParsers = - List.range 0 10 + List.range '0' ('9' + 1) |> List.map \digitNum -> digitNum - + 48 |> codeunit |> map (\_ -> digitNum) From 619cd2f629f065aeb4302c79388035f9e07a079c Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Mon, 3 Oct 2022 15:57:54 -0500 Subject: [PATCH 38/65] Infer ranged number for chars in patterns --- crates/compiler/can/src/copy.rs | 2 +- crates/compiler/can/src/def.rs | 2 +- crates/compiler/can/src/exhaustive.rs | 2 +- crates/compiler/can/src/module.rs | 2 +- crates/compiler/can/src/pattern.rs | 16 ++++++---- crates/compiler/constrain/src/pattern.rs | 29 +++++++++++++++++-- crates/compiler/mono/src/ir.rs | 10 ++++--- .../compiler/test_derive/src/pretty_print.rs | 2 +- 8 files changed, 48 insertions(+), 17 deletions(-) diff --git a/crates/compiler/can/src/copy.rs b/crates/compiler/can/src/copy.rs index 5deced7c19..98e3ad8040 100644 --- a/crates/compiler/can/src/copy.rs +++ b/crates/compiler/can/src/copy.rs @@ -725,7 +725,7 @@ fn deep_copy_pattern_help( FloatLiteral(sub!(*v1), sub!(*v2), s.clone(), *n, *bound) } StrLiteral(s) => StrLiteral(s.clone()), - SingleQuote(c) => SingleQuote(*c), + SingleQuote(v1, v2, c, bound) => SingleQuote(sub!(*v1), sub!(*v2), *c, *bound), Underscore => Underscore, AbilityMemberSpecialization { ident, specializes } => AbilityMemberSpecialization { ident: *ident, diff --git a/crates/compiler/can/src/def.rs b/crates/compiler/can/src/def.rs index 978e8a2f61..3084daeeaa 100644 --- a/crates/compiler/can/src/def.rs +++ b/crates/compiler/can/src/def.rs @@ -1884,7 +1884,7 @@ fn pattern_to_vars_by_symbol( | IntLiteral(..) | FloatLiteral(..) | StrLiteral(_) - | SingleQuote(_) + | SingleQuote(..) | Underscore | MalformedPattern(_, _) | UnsupportedPattern(_) diff --git a/crates/compiler/can/src/exhaustive.rs b/crates/compiler/can/src/exhaustive.rs index 1fcc73e470..b094d6b7a5 100644 --- a/crates/compiler/can/src/exhaustive.rs +++ b/crates/compiler/can/src/exhaustive.rs @@ -253,7 +253,7 @@ fn sketch_pattern(pattern: &crate::pattern::Pattern) -> SketchedPattern { } &FloatLiteral(_, _, _, f, _) => SP::Literal(Literal::Float(f64::to_bits(f))), StrLiteral(v) => SP::Literal(Literal::Str(v.clone())), - &SingleQuote(c) => SP::Literal(Literal::Byte(c as u8)), + &SingleQuote(_, _, c, _) => SP::Literal(Literal::Byte(c as u8)), RecordDestructure { destructs, .. } => { let tag_id = TagId(0); let mut patterns = std::vec::Vec::with_capacity(destructs.len()); diff --git a/crates/compiler/can/src/module.rs b/crates/compiler/can/src/module.rs index 41919ed091..6a44341fe5 100644 --- a/crates/compiler/can/src/module.rs +++ b/crates/compiler/can/src/module.rs @@ -899,7 +899,7 @@ fn fix_values_captured_in_closure_pattern( | IntLiteral(..) | FloatLiteral(..) | StrLiteral(_) - | SingleQuote(_) + | SingleQuote(..) | Underscore | Shadowed(..) | MalformedPattern(_, _) diff --git a/crates/compiler/can/src/pattern.rs b/crates/compiler/can/src/pattern.rs index 9fc18f35ed..e15899ab6e 100644 --- a/crates/compiler/can/src/pattern.rs +++ b/crates/compiler/can/src/pattern.rs @@ -12,6 +12,7 @@ use roc_parse::ast::{self, StrLiteral, StrSegment}; use roc_parse::pattern::PatternType; use roc_problem::can::{MalformedPatternProblem, Problem, RuntimeError, ShadowKind}; use roc_region::all::{Loc, Region}; +use roc_types::num::SingleQuoteBound; use roc_types::subs::{VarStore, Variable}; use roc_types::types::{LambdaSet, OptAbleVar, PatternCategory, Type}; @@ -59,7 +60,7 @@ pub enum Pattern { IntLiteral(Variable, Variable, Box, IntValue, IntBound), FloatLiteral(Variable, Variable, Box, f64, FloatBound), StrLiteral(Box), - SingleQuote(char), + SingleQuote(Variable, Variable, char, SingleQuoteBound), Underscore, /// An identifier that marks a specialization of an ability member. @@ -95,7 +96,7 @@ impl Pattern { IntLiteral(var, ..) => Some(*var), FloatLiteral(var, ..) => Some(*var), StrLiteral(_) => None, - SingleQuote(_) => None, + SingleQuote(..) => None, Underscore => None, AbilityMemberSpecialization { .. } => None, @@ -148,7 +149,7 @@ impl Pattern { IntLiteral(..) => C::Int, FloatLiteral(..) => C::Float, StrLiteral(_) => C::Str, - SingleQuote(_) => C::Character, + SingleQuote(..) => C::Character, Underscore => C::PatternDefault, AbilityMemberSpecialization { .. } => C::PatternDefault, @@ -456,7 +457,12 @@ pub fn canonicalize_pattern<'a>( let mut it = string.chars().peekable(); if let Some(char) = it.next() { if it.peek().is_none() { - Pattern::SingleQuote(char) + Pattern::SingleQuote( + var_store.fresh(), + var_store.fresh(), + char, + SingleQuoteBound::from_char(char), + ) } else { // multiple chars is found let problem = MalformedPatternProblem::MultipleCharsInSingleQuote; @@ -724,7 +730,7 @@ impl<'a> BindingsFromPattern<'a> { | IntLiteral(..) | FloatLiteral(..) | StrLiteral(_) - | SingleQuote(_) + | SingleQuote(..) | Underscore | Shadowed(_, _, _) | MalformedPattern(_, _) diff --git a/crates/compiler/constrain/src/pattern.rs b/crates/compiler/constrain/src/pattern.rs index 31ff602be5..babcbba774 100644 --- a/crates/compiler/constrain/src/pattern.rs +++ b/crates/compiler/constrain/src/pattern.rs @@ -71,7 +71,7 @@ fn headers_from_annotation_help( | NumLiteral(..) | IntLiteral(..) | FloatLiteral(..) - | SingleQuote(_) + | SingleQuote(..) | StrLiteral(_) => true, RecordDestructure { destructs, .. } => match annotation.value.shallow_dealias() { @@ -320,9 +320,32 @@ pub fn constrain_pattern( )); } - SingleQuote(_) => { + &SingleQuote(num_var, precision_var, _, bound) => { + // First constraint on the free num var; this improves the resolved type quality in + // case the bound is an alias. + let num_type = builtins::add_numeric_bound_constr( + constraints, + &mut state.constraints, + num_var, + num_var, + bound, + region, + Category::Int, + ); + + // Link the free num var with the int var and our expectation. + let int_type = builtins::num_int(Type::Variable(precision_var)); + + state.constraints.push(constraints.equal_types( + num_type.clone(), // TODO check me if something breaks! + Expected::NoExpectation(int_type), + Category::Int, + region, + )); + + // Also constrain the pattern against the num var, again to reuse aliases if they're present. state.constraints.push(constraints.equal_pattern_types( - builtins::num_u32(), + num_type, expected, PatternCategory::Character, region, diff --git a/crates/compiler/mono/src/ir.rs b/crates/compiler/mono/src/ir.rs index 60394efba4..4bb5c799ed 100644 --- a/crates/compiler/mono/src/ir.rs +++ b/crates/compiler/mono/src/ir.rs @@ -8889,10 +8889,12 @@ fn from_can_pattern_help<'a>( IntOrFloatValue::Float(*float), )), StrLiteral(v) => Ok(Pattern::StrLiteral(v.clone())), - SingleQuote(c) => Ok(Pattern::IntLiteral( - (*c as i128).to_ne_bytes(), - IntWidth::I32, - )), + SingleQuote(var, _, c, _) => match layout_cache.from_var(env.arena, *var, env.subs) { + Ok(Layout::Builtin(Builtin::Int(width))) => { + Ok(Pattern::IntLiteral((*c as i128).to_ne_bytes(), width)) + } + o => internal_error!("an integer width was expected, but we found {:?}", o), + }, Shadowed(region, ident, _new_symbol) => Err(RuntimeError::Shadowing { original_region: *region, shadow: ident.clone(), diff --git a/crates/compiler/test_derive/src/pretty_print.rs b/crates/compiler/test_derive/src/pretty_print.rs index 9493458b4c..8a8a02da4e 100644 --- a/crates/compiler/test_derive/src/pretty_print.rs +++ b/crates/compiler/test_derive/src/pretty_print.rs @@ -366,7 +366,7 @@ fn pattern<'a>( f.text(&**n) } StrLiteral(s) => f.text(format!(r#""{}""#, s)), - SingleQuote(c) => f.text(format!("'{}'", c)), + SingleQuote(_, _, c, _) => f.text(format!("'{}'", c)), Underscore => f.text("_"), Shadowed(_, _, _) => todo!(), From 912cebc33db5964a65a3f6d498053267b2a14506 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Mon, 3 Oct 2022 16:00:25 -0500 Subject: [PATCH 39/65] Add tests for inferring char ranged number --- crates/compiler/solve/tests/solve_expr.rs | 54 +++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/crates/compiler/solve/tests/solve_expr.rs b/crates/compiler/solve/tests/solve_expr.rs index 534c6cabaa..06fb7c7ec4 100644 --- a/crates/compiler/solve/tests/solve_expr.rs +++ b/crates/compiler/solve/tests/solve_expr.rs @@ -7886,4 +7886,58 @@ mod solve_expr { "U32", ); } + + #[test] + fn check_char_pattern_as_u8() { + infer_eq_without_problem( + indoc!( + r#" + f : U8 -> _ + f = \c -> + when c is + '.' -> 'A' + c1 -> c1 + + f + "# + ), + "U8 -> U8", + ); + } + + #[test] + fn check_char_pattern_as_u16() { + infer_eq_without_problem( + indoc!( + r#" + f : U16 -> _ + f = \c -> + when c is + '.' -> 'A' + c1 -> c1 + + f + "# + ), + "U16 -> U16", + ); + } + + #[test] + fn check_char_pattern_as_u32() { + infer_eq_without_problem( + indoc!( + r#" + f : U32 -> _ + f = \c -> + when c is + '.' -> 'A' + c1 -> c1 + + f + "# + ), + "U32 -> U32", + ); + } } From 9d91b9bc5a577f753651525c3700e2a7b9e683bd Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Mon, 3 Oct 2022 16:01:59 -0500 Subject: [PATCH 40/65] Add reporting case for inferred char range type mismatch --- crates/reporting/tests/test_reporting.rs | 32 ++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/crates/reporting/tests/test_reporting.rs b/crates/reporting/tests/test_reporting.rs index de8e16fb4c..27f86c654b 100644 --- a/crates/reporting/tests/test_reporting.rs +++ b/crates/reporting/tests/test_reporting.rs @@ -11100,4 +11100,36 @@ All branches in an `if` must have the same type! U8 "### ); + + test_report!( + big_char_does_not_fit_in_u8_pattern, + indoc!( + r#" + x : U8 + + when x is + '☃' -> "" + _ -> "" + "# + ), + @r###" + ── TYPE MISMATCH ───────────────────────────────────────── /code/proj/Main.roc ─ + + The branches of this `when` expression don't match the condition: + + 6│> when x is + 7│ '☃' -> "" + 8│ _ -> "" + + This `x` value is a: + + U8 + + But the branch patterns have type: + + U16, I32, U32, I64, Nat, U64, I128, or U128 + + The branches must be cases of the `when` condition's type! + "### + ); } From 7064d1c0605c3d24aa48a046fa03c0973624fe16 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Mon, 3 Oct 2022 16:04:29 -0500 Subject: [PATCH 41/65] Gen test for char pattern matching --- crates/compiler/test_gen/src/gen_primitives.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/crates/compiler/test_gen/src/gen_primitives.rs b/crates/compiler/test_gen/src/gen_primitives.rs index 01179bf886..5a65af1f17 100644 --- a/crates/compiler/test_gen/src/gen_primitives.rs +++ b/crates/compiler/test_gen/src/gen_primitives.rs @@ -4067,3 +4067,21 @@ fn int_let_generalization() { RocStr ); } + +#[test] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] +fn pattern_match_char() { + assert_evals_to!( + indoc!( + r#" + c = 'A' + + when c is + 'A' -> "okay" + _ -> "FAIL" + "# + ), + RocStr::from("okay"), + RocStr + ); +} From 262d13ffe7857dffcdc3e676ec49762962bafd48 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Mon, 3 Oct 2022 16:04:55 -0500 Subject: [PATCH 42/65] Simplify char pattern matching in json parser --- crates/compiler/builtins/roc/Json.roc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/compiler/builtins/roc/Json.roc b/crates/compiler/builtins/roc/Json.roc index e7926e0310..11172b717d 100644 --- a/crates/compiler/builtins/roc/Json.roc +++ b/crates/compiler/builtins/roc/Json.roc @@ -197,7 +197,7 @@ takeFloat = \bytes -> { taken: intPart, rest } = takeDigits bytes when List.get rest 0 is - Ok 46 -> # 46 = . + Ok '.' -> { taken: floatPart, rest: afterAll } = takeDigits (List.split rest 1).others builtFloat = List.concat (List.append intPart '.') floatPart From 5416eb7cbf57f508e9b1b6e879f0a30b326e96d5 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Wed, 5 Oct 2022 18:49:48 -0500 Subject: [PATCH 43/65] List dependencies in the stdlib explicitly rather than hard-coding --- crates/compiler/builtins/roc/Decode.roc | 17 +++++++++++++++++ crates/compiler/builtins/roc/Dict.roc | 1 + crates/compiler/builtins/roc/Encode.roc | 19 ++++++++++++++++++- crates/compiler/builtins/roc/Hash.roc | 1 + crates/compiler/builtins/roc/Json.roc | 17 +++++++++++++++++ crates/compiler/builtins/roc/List.roc | 2 ++ crates/compiler/builtins/roc/Num.roc | 1 + crates/compiler/builtins/roc/Set.roc | 2 +- crates/compiler/builtins/roc/Str.roc | 7 ++++++- crates/compiler/load_internal/src/file.rs | 19 +++++-------------- 10 files changed, 69 insertions(+), 17 deletions(-) diff --git a/crates/compiler/builtins/roc/Decode.roc b/crates/compiler/builtins/roc/Decode.roc index 46574421ad..55021ca86e 100644 --- a/crates/compiler/builtins/roc/Decode.roc +++ b/crates/compiler/builtins/roc/Decode.roc @@ -30,6 +30,23 @@ interface Decode ] imports [ List, + Result.{ Result }, + Num.{ + U8, + U16, + U32, + U64, + U128, + I8, + I16, + I32, + I64, + I128, + F32, + F64, + Dec, + }, + Bool.{ Bool }, ] DecodeError : [TooShort] diff --git a/crates/compiler/builtins/roc/Dict.roc b/crates/compiler/builtins/roc/Dict.roc index ef012f7f21..3a90eef8f9 100644 --- a/crates/compiler/builtins/roc/Dict.roc +++ b/crates/compiler/builtins/roc/Dict.roc @@ -20,6 +20,7 @@ interface Dict Bool.{ Bool }, Result.{ Result }, List, + Num.{ Nat }, ] ## A [dictionary](https://en.wikipedia.org/wiki/Associative_array) that lets you can associate keys with values. diff --git a/crates/compiler/builtins/roc/Encode.roc b/crates/compiler/builtins/roc/Encode.roc index 5941723871..ec0d10ef0a 100644 --- a/crates/compiler/builtins/roc/Encode.roc +++ b/crates/compiler/builtins/roc/Encode.roc @@ -27,7 +27,24 @@ interface Encode append, toBytes, ] - imports [] + imports [ + Num.{ + U8, + U16, + U32, + U64, + U128, + I8, + I16, + I32, + I64, + I128, + F32, + F64, + Dec, + }, + Bool.{ Bool }, + ] Encoder fmt := List U8, fmt -> List U8 | fmt has EncoderFormatting diff --git a/crates/compiler/builtins/roc/Hash.roc b/crates/compiler/builtins/roc/Hash.roc index a9fe6ecbc4..59cf8f476c 100644 --- a/crates/compiler/builtins/roc/Hash.roc +++ b/crates/compiler/builtins/roc/Hash.roc @@ -20,6 +20,7 @@ interface Hash ] imports [ List, Str, + Num.{ U8, U16, U32, U64, U128, I8, I16, I32, I64, I128 }, ] ## A value that can hashed. diff --git a/crates/compiler/builtins/roc/Json.roc b/crates/compiler/builtins/roc/Json.roc index 3dca470cf5..ca7643c584 100644 --- a/crates/compiler/builtins/roc/Json.roc +++ b/crates/compiler/builtins/roc/Json.roc @@ -18,6 +18,23 @@ interface Json DecoderFormatting, DecodeResult, }, + Num.{ + U8, + U16, + U32, + U64, + U128, + I8, + I16, + I32, + I64, + I128, + F32, + F64, + Dec, + }, + Bool.{ Bool }, + Result, ] Json := {} has [ diff --git a/crates/compiler/builtins/roc/List.roc b/crates/compiler/builtins/roc/List.roc index f5b5734767..168de8181a 100644 --- a/crates/compiler/builtins/roc/List.roc +++ b/crates/compiler/builtins/roc/List.roc @@ -63,6 +63,8 @@ interface List ] imports [ Bool.{ Bool }, + Result.{ Result }, + Num.{ Nat, Num, Int }, ] ## Types diff --git a/crates/compiler/builtins/roc/Num.roc b/crates/compiler/builtins/roc/Num.roc index 9280d49003..23b879ce2e 100644 --- a/crates/compiler/builtins/roc/Num.roc +++ b/crates/compiler/builtins/roc/Num.roc @@ -145,6 +145,7 @@ interface Num ] imports [ Bool.{ Bool }, + Result.{ Result }, ] ## Represents a number that could be either an [Int] or a [Frac]. diff --git a/crates/compiler/builtins/roc/Set.roc b/crates/compiler/builtins/roc/Set.roc index 381c94d383..c1fe50a5ad 100644 --- a/crates/compiler/builtins/roc/Set.roc +++ b/crates/compiler/builtins/roc/Set.roc @@ -14,7 +14,7 @@ interface Set intersection, difference, ] - imports [List, Bool.{ Bool }, Dict.{ Dict }] + imports [List, Bool.{ Bool }, Dict.{ Dict }, Num.{ Nat }] Set k := Dict.Dict k {} diff --git a/crates/compiler/builtins/roc/Str.roc b/crates/compiler/builtins/roc/Str.roc index fd8d3fcc30..1d4c8d136a 100644 --- a/crates/compiler/builtins/roc/Str.roc +++ b/crates/compiler/builtins/roc/Str.roc @@ -44,7 +44,12 @@ interface Str walkScalars, walkScalarsUntil, ] - imports [Bool.{ Bool }, Result.{ Result }, List] + imports [ + Bool.{ Bool }, + Result.{ Result }, + List, + Num.{ Nat, Num, U8, U16, U32, U64, U128, I8, I16, I32, I64, I128, F32, F64, Dec }, + ] ## # Types ## diff --git a/crates/compiler/load_internal/src/file.rs b/crates/compiler/load_internal/src/file.rs index af1024f28a..ccffd37964 100644 --- a/crates/compiler/load_internal/src/file.rs +++ b/crates/compiler/load_internal/src/file.rs @@ -2232,24 +2232,15 @@ fn update<'a>( // add the prelude let mut header = header; - if ![ModuleId::RESULT, ModuleId::BOOL].contains(&header.module_id) { - extend_header_with_builtin(&mut header, ModuleId::RESULT); - } - - if ![ModuleId::NUM, ModuleId::BOOL, ModuleId::RESULT].contains(&header.module_id) { - extend_header_with_builtin(&mut header, ModuleId::NUM); - } - - if ![ModuleId::BOOL].contains(&header.module_id) { - extend_header_with_builtin(&mut header, ModuleId::BOOL); - } - if !header.module_id.is_builtin() { - extend_header_with_builtin(&mut header, ModuleId::BOX); + extend_header_with_builtin(&mut header, ModuleId::NUM); + extend_header_with_builtin(&mut header, ModuleId::BOOL); extend_header_with_builtin(&mut header, ModuleId::STR); + extend_header_with_builtin(&mut header, ModuleId::LIST); + extend_header_with_builtin(&mut header, ModuleId::RESULT); extend_header_with_builtin(&mut header, ModuleId::DICT); extend_header_with_builtin(&mut header, ModuleId::SET); - extend_header_with_builtin(&mut header, ModuleId::LIST); + extend_header_with_builtin(&mut header, ModuleId::BOX); extend_header_with_builtin(&mut header, ModuleId::ENCODE); extend_header_with_builtin(&mut header, ModuleId::DECODE); extend_header_with_builtin(&mut header, ModuleId::HASH); From d9207137e8747586cae662797acdd52308897f0d Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Wed, 5 Oct 2022 19:41:21 -0500 Subject: [PATCH 44/65] Implement Num.isZero as a low-level This will be needed ahead of the `Eq` ability. Closes #4223 --- crates/compiler/builtins/roc/Num.roc | 1 - crates/compiler/can/src/builtins.rs | 32 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/crates/compiler/builtins/roc/Num.roc b/crates/compiler/builtins/roc/Num.roc index 9280d49003..f826903ba6 100644 --- a/crates/compiler/builtins/roc/Num.roc +++ b/crates/compiler/builtins/roc/Num.roc @@ -574,7 +574,6 @@ isGte : Num a, Num a -> Bool ## Returns `Bool.true` if the number is `0`, and `Bool.false` otherwise. isZero : Num a -> Bool -isZero = \x -> x == 0 ## A number is even if dividing it by 2 gives a remainder of 0. ## diff --git a/crates/compiler/can/src/builtins.rs b/crates/compiler/can/src/builtins.rs index d381f591cc..548316fe9d 100644 --- a/crates/compiler/can/src/builtins.rs +++ b/crates/compiler/can/src/builtins.rs @@ -55,6 +55,8 @@ macro_rules! map_symbol_to_lowlevel_and_arity { Symbol::NUM_TO_F32_CHECKED => Some(to_num_checked(Symbol::NUM_TO_F32_CHECKED, var_store, LowLevel::NumToFloatChecked)), Symbol::NUM_TO_F64_CHECKED => Some(to_num_checked(Symbol::NUM_TO_F64_CHECKED, var_store, LowLevel::NumToFloatChecked)), + Symbol::NUM_IS_ZERO => Some(to_num_is_zero(Symbol::NUM_IS_ZERO, var_store)), + _ => None, } } @@ -535,3 +537,33 @@ fn to_num_checked(symbol: Symbol, var_store: &mut VarStore, lowlevel: LowLevel) ret_var, ) } + +fn to_num_is_zero(symbol: Symbol, var_store: &mut VarStore) -> Def { + let bool_var = var_store.fresh(); + let num_var = var_store.fresh(); + + let body = Expr::RunLowLevel { + op: LowLevel::Eq, + args: vec![ + (num_var, Var(Symbol::ARG_1)), + ( + num_var, + Num( + var_store.fresh(), + "0".to_string().into_boxed_str(), + crate::expr::IntValue::I128(0i128.to_ne_bytes()), + roc_types::num::NumBound::None, + ), + ), + ], + ret_var: bool_var, + }; + + defn( + symbol, + vec![(num_var, Symbol::ARG_1)], + var_store, + body, + bool_var, + ) +} From 76a8a6054736ca5614f2fa62594e059e942524c9 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Thu, 6 Oct 2022 08:22:08 +0100 Subject: [PATCH 45/65] Web REPL: ensure we only try to append to DOM Elements, not text nodes --- www/public/repl/repl.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/public/repl/repl.js b/www/public/repl/repl.js index 48a8b2c64f..0c64ca4f72 100644 --- a/www/public/repl/repl.js +++ b/www/public/repl/repl.js @@ -212,7 +212,7 @@ function updateHistoryEntry(index, ok, outputText) { outputElem.classList.add("output"); outputElem.classList.add(ok ? "output-ok" : "output-error"); - const historyItem = repl.elemHistory.childNodes[index]; + const historyItem = repl.elemHistory.children[index]; historyItem.appendChild(outputElem); repl.elemHistory.scrollTop = repl.elemHistory.scrollHeight; From a455f527cdea325e5422c117b407ad57dae12977 Mon Sep 17 00:00:00 2001 From: Marcos Prieto Date: Mon, 3 Oct 2022 15:26:01 +0200 Subject: [PATCH 46/65] Expose more fields on Game.Text - Expose color - Expose size - Expose left & top --- examples/breakout/hello.roc | 2 +- examples/breakout/platform/Game.roc | 2 +- examples/breakout/platform/src/gui.rs | 10 ++++------ examples/breakout/platform/src/roc.rs | 12 +++++++++++- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/examples/breakout/hello.roc b/examples/breakout/hello.roc index 0c50f63dac..0e05e50705 100644 --- a/examples/breakout/hello.roc +++ b/examples/breakout/hello.roc @@ -12,6 +12,6 @@ update : Model, Event -> Model update = \model, _ -> model render : Model -> List Elem -render = \model -> [Text model.text] +render = \model -> [Text { text: model.text, top: 0, left: 0, size: 40, color: { r: 1, g: 1, b: 1, a: 1 } }] program = { init, update, render } diff --git a/examples/breakout/platform/Game.roc b/examples/breakout/platform/Game.roc index 0ce338ee3d..0d10fec464 100644 --- a/examples/breakout/platform/Game.roc +++ b/examples/breakout/platform/Game.roc @@ -6,7 +6,7 @@ Rgba : { r : F32, g : F32, b : F32, a : F32 } Bounds : { height : F32, width : F32 } -Elem : [Rect { color : Rgba, left : F32, top : F32, width : F32, height : F32 }, Text Str] +Elem : [Rect { color : Rgba, left : F32, top : F32, width : F32, height : F32 }, Text { text : Str, color : Rgba, left : F32, top : F32, size : F32 }] KeyCode : [Left, Right, Other] diff --git a/examples/breakout/platform/src/gui.rs b/examples/breakout/platform/src/gui.rs index c43604c638..0330398126 100644 --- a/examples/breakout/platform/src/gui.rs +++ b/examples/breakout/platform/src/gui.rs @@ -455,7 +455,7 @@ fn to_drawable( wgpu_glyph::HorizontalAlign::Left }); - let section = owned_section_from_str(text.as_str(), bounds, layout); + let section = owned_section_from_str(text.text.as_str(),text.color, text.size, bounds, layout); // Calculate the bounds and offset by measuring glyphs let text_bounds; @@ -481,7 +481,7 @@ fn to_drawable( } let drawable = Drawable { - pos: (0.0, 0.0).into(), // TODO store the pos in Text and read it here + pos: (text.left, text.top).into(), bounds: text_bounds, content: DrawableContent::Text(section, offset), }; @@ -493,13 +493,11 @@ fn to_drawable( fn owned_section_from_str( string: &str, + color: Rgba, + size: f32, bounds: Bounds, layout: wgpu_glyph::Layout, ) -> OwnedSection { - // TODO don't hardcode any of this! - let color = Rgba::WHITE; - let size: f32 = 40.0; - OwnedSection { bounds: (bounds.width, bounds.height), layout, diff --git a/examples/breakout/platform/src/roc.rs b/examples/breakout/platform/src/roc.rs index 50ab87b9cc..2e793147fd 100644 --- a/examples/breakout/platform/src/roc.rs +++ b/examples/breakout/platform/src/roc.rs @@ -210,7 +210,7 @@ pub struct ElemId(*const RocElemEntry); #[repr(C)] pub union RocElemEntry { pub rect: ManuallyDrop, - pub text: ManuallyDrop, + pub text: ManuallyDrop, } #[repr(u8)] @@ -284,6 +284,16 @@ pub struct RocRect { pub width: f32, } +#[repr(C)] +#[derive(Debug, Clone)] +pub struct RocText { + pub text: RocStr, + pub color: Rgba, + pub left: f32, + pub size: f32, + pub top: f32, +} + impl Clone for RocElem { fn clone(&self) -> Self { unsafe { From 0fa8658edeaa14b438ce86496b0155324300ce04 Mon Sep 17 00:00:00 2001 From: Marcos Prieto Date: Wed, 5 Oct 2022 10:45:21 +0200 Subject: [PATCH 47/65] Expose Up & Down in Game.KeyCodes --- examples/breakout/platform/Game.roc | 2 +- examples/breakout/platform/src/roc.rs | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/breakout/platform/Game.roc b/examples/breakout/platform/Game.roc index 0d10fec464..26b966bf8d 100644 --- a/examples/breakout/platform/Game.roc +++ b/examples/breakout/platform/Game.roc @@ -8,6 +8,6 @@ Bounds : { height : F32, width : F32 } Elem : [Rect { color : Rgba, left : F32, top : F32, width : F32, height : F32 }, Text { text : Str, color : Rgba, left : F32, top : F32, size : F32 }] -KeyCode : [Left, Right, Other] +KeyCode : [Left, Right, Other, Up, Down] Event : [Resize { width : F32, height : F32 }, KeyDown KeyCode, KeyUp KeyCode, Tick U128] diff --git a/examples/breakout/platform/src/roc.rs b/examples/breakout/platform/src/roc.rs index 2e793147fd..aecfd0427d 100644 --- a/examples/breakout/platform/src/roc.rs +++ b/examples/breakout/platform/src/roc.rs @@ -142,9 +142,11 @@ impl RocEvent { #[allow(unused)] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum RocKeyCode { - Left = 0, + Down = 0, + Left, Other, Right, + Up, } impl From for RocKeyCode { @@ -154,6 +156,8 @@ impl From for RocKeyCode { match keycode { Left => RocKeyCode::Left, Right => RocKeyCode::Right, + Up => RocKeyCode::Up, + Down => RocKeyCode::Down, _ => RocKeyCode::Other, } } From 29869569297371d52c72185fc1dc29428d308242 Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Thu, 6 Oct 2022 20:14:51 +0200 Subject: [PATCH 48/65] serialize cli_platform cli_run tests --- crates/cli/tests/cli_run.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/cli/tests/cli_run.rs b/crates/cli/tests/cli_run.rs index df4681b436..fe4d579ec2 100644 --- a/crates/cli/tests/cli_run.rs +++ b/crates/cli/tests/cli_run.rs @@ -381,6 +381,7 @@ mod cli_run { } #[test] + #[serial(cli_platform)] fn hello_world() { test_roc_app_slim( "examples", @@ -495,6 +496,7 @@ mod cli_run { } #[test] + #[serial(cli_platform)] fn cli_args() { test_roc_app( "examples/cli", @@ -582,6 +584,7 @@ mod cli_run { } #[test] + #[serial(cli_platform)] fn with_env_vars() { test_roc_app( "examples/cli", From 0f96dddc25ab72e56ea87f1c38e683e2027d14c4 Mon Sep 17 00:00:00 2001 From: Prajwal S N Date: Fri, 7 Oct 2022 00:03:18 +0530 Subject: [PATCH 49/65] builtin(list): expose walkTry Fixes: #4168 Signed-off-by: Prajwal S N --- crates/compiler/builtins/roc/List.roc | 2 +- crates/compiler/module/src/symbol.rs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/compiler/builtins/roc/List.roc b/crates/compiler/builtins/roc/List.roc index f5b5734767..4f309b13a7 100644 --- a/crates/compiler/builtins/roc/List.roc +++ b/crates/compiler/builtins/roc/List.roc @@ -39,6 +39,7 @@ interface List max, map4, mapTry, + walkTry, dropFirst, joinMap, any, @@ -959,7 +960,6 @@ mapTry = \list, toResult -> ## This is the same as `iterate` but with Result instead of [Continue, Break]. ## Using `Result` saves a conditional in `mapTry`. -## It might be useful to expose this in userspace? walkTry : List elem, state, (state, elem -> Result state err) -> Result state err walkTry = \list, init, func -> walkTryHelp list init func 0 (List.len list) diff --git a/crates/compiler/module/src/symbol.rs b/crates/compiler/module/src/symbol.rs index df6acd2b7f..3e4a130445 100644 --- a/crates/compiler/module/src/symbol.rs +++ b/crates/compiler/module/src/symbol.rs @@ -1373,6 +1373,7 @@ define_builtins! { 72 LIST_SUBLIST_LOWLEVEL: "sublistLowlevel" 73 LIST_CAPACITY: "capacity" 74 LIST_MAP_TRY: "mapTry" + 75 LIST_WALK_TRY: "walkTry" } 7 RESULT: "Result" => { 0 RESULT_RESULT: "Result" exposed_type=true // the Result.Result type alias From 2cf13093260ff82ce03cb05bb8e76d665f38f460 Mon Sep 17 00:00:00 2001 From: Ayaz <20735482+ayazhafiz@users.noreply.github.com> Date: Thu, 6 Oct 2022 16:19:15 -0500 Subject: [PATCH 50/65] Update crates/compiler/builtins/roc/List.roc Signed-off-by: Ayaz <20735482+ayazhafiz@users.noreply.github.com> --- crates/compiler/builtins/roc/List.roc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/compiler/builtins/roc/List.roc b/crates/compiler/builtins/roc/List.roc index 4f309b13a7..b7b440b20c 100644 --- a/crates/compiler/builtins/roc/List.roc +++ b/crates/compiler/builtins/roc/List.roc @@ -958,7 +958,7 @@ mapTry = \list, toResult -> Result.map (toResult elem) \ok -> List.append state ok -## This is the same as `iterate` but with Result instead of [Continue, Break]. +## This is the same as `iterate` but with [Result] instead of `[Continue, Break]`. ## Using `Result` saves a conditional in `mapTry`. walkTry : List elem, state, (state, elem -> Result state err) -> Result state err walkTry = \list, init, func -> From 07a66f49620d1659ef187e002b117bfaa88b6697 Mon Sep 17 00:00:00 2001 From: Jan Van Bruggen Date: Thu, 6 Oct 2022 23:53:51 -0600 Subject: [PATCH 51/65] Fix `positionaConfigs` typo --- examples/interactive/cli-platform/Arg.roc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/interactive/cli-platform/Arg.roc b/examples/interactive/cli-platform/Arg.roc index a97f743252..86a79eea31 100644 --- a/examples/interactive/cli-platform/Arg.roc +++ b/examples/interactive/cli-platform/Arg.roc @@ -581,7 +581,7 @@ formatHelpHelp = \n, cmdHelp -> Arg c -> Some c _ -> None) - positionaConfigs = + positionalConfigs = filterMap configs (\config -> @@ -605,11 +605,11 @@ formatHelpHelp = \n, cmdHelp -> """ fmtPositionalsHelp = - if List.isEmpty positionaConfigs then + if List.isEmpty positionalConfigs then "" else helpStr = - positionaConfigs + positionalConfigs |> List.map (\c -> formatPositionalConfig (n + indentLevel) c) |> Str.joinWith "\n" From 5ef7cb27500be632e39cac12afbc7a23f22db221 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Fri, 7 Oct 2022 08:26:31 +0100 Subject: [PATCH 52/65] www: handle empty input in web REPL --- www/public/repl/repl.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/www/public/repl/repl.js b/www/public/repl/repl.js index 0c64ca4f72..91248858f7 100644 --- a/www/public/repl/repl.js +++ b/www/public/repl/repl.js @@ -42,7 +42,7 @@ const repl = { repl.elemSourceInput.addEventListener("change", onInputChange); repl.elemSourceInput.addEventListener("keyup", onInputKeyup); roc_repl_wasm.default("/repl/roc_repl_wasm_bg.wasm").then((instance) => { - repl.elemHistory.querySelector('#loading-message').remove(); + repl.elemHistory.querySelector("#loading-message").remove(); repl.elemSourceInput.disabled = false; repl.elemSourceInput.placeholder = "Type some Roc code and press Enter. (Use Shift+Enter for multi-line input)"; @@ -54,8 +54,7 @@ roc_repl_wasm.default("/repl/roc_repl_wasm_bg.wasm").then((instance) => { // ---------------------------------------------------------------------------- function onInputChange(event) { - const inputText = event.target.value; - if (!inputText) return; + const inputText = event.target.value.trim(); event.target.value = ""; @@ -122,13 +121,15 @@ async function processInputQueue() { repl.inputHistoryIndex = createHistoryEntry(inputText); repl.inputStash = ""; - let outputText; + let outputText = ""; let ok = true; - try { - outputText = await roc_repl_wasm.entrypoint_from_js(inputText); - } catch (e) { - outputText = `${e}`; - ok = false; + if (inputText) { + try { + outputText = await roc_repl_wasm.entrypoint_from_js(inputText); + } catch (e) { + outputText = `${e}`; + ok = false; + } } updateHistoryEntry(repl.inputHistoryIndex, ok, outputText); From 722ece9d85ff2db2df2a8e9931149019c21f2d0a Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Fri, 7 Oct 2022 17:16:21 +0200 Subject: [PATCH 53/65] updated LLVM_SYS_130_PREFIX I believe updates to the VM image used by github require this change Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com> --- .github/workflows/nightly_macos_x86_64.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nightly_macos_x86_64.yml b/.github/workflows/nightly_macos_x86_64.yml index 413538587a..48eb4249c8 100644 --- a/.github/workflows/nightly_macos_x86_64.yml +++ b/.github/workflows/nightly_macos_x86_64.yml @@ -6,7 +6,7 @@ name: Nightly Release macOS x86_64 env: ZIG_VERSION: 0.9.1 - LLVM_SYS_130_PREFIX: /usr/local/opt/llvm + LLVM_SYS_130_PREFIX: /usr/local/opt/llvm@13 jobs: test-build-upload: From 9013e4ce11bd78e59bf25c321b5497769ba790be Mon Sep 17 00:00:00 2001 From: Prajwal S N Date: Fri, 7 Oct 2022 18:48:24 +0530 Subject: [PATCH 54/65] builtin(str): implement withCapacity Signed-off-by: Prajwal S N --- crates/compiler/builtins/bitcode/src/main.zig | 1 + crates/compiler/builtins/bitcode/src/str.zig | 4 +++ crates/compiler/builtins/roc/Str.roc | 4 +++ crates/compiler/builtins/src/bitcode.rs | 1 + crates/compiler/can/src/builtins.rs | 1 + crates/compiler/gen_llvm/src/llvm/build.rs | 16 ++++++++++- crates/compiler/gen_wasm/src/low_level.rs | 1 + crates/compiler/module/src/low_level.rs | 2 ++ crates/compiler/module/src/symbol.rs | 1 + crates/compiler/mono/src/borrow.rs | 2 +- crates/compiler/test_gen/src/gen_str.rs | 28 +++++++++++++++++++ 11 files changed, 59 insertions(+), 2 deletions(-) diff --git a/crates/compiler/builtins/bitcode/src/main.zig b/crates/compiler/builtins/bitcode/src/main.zig index 44ad0d99eb..b7c00d307d 100644 --- a/crates/compiler/builtins/bitcode/src/main.zig +++ b/crates/compiler/builtins/bitcode/src/main.zig @@ -144,6 +144,7 @@ comptime { exportStrFn(str.strTrimLeft, "trim_left"); exportStrFn(str.strTrimRight, "trim_right"); exportStrFn(str.strCloneTo, "clone_to"); + exportStrFn(str.withCapacity, "with_capacity"); inline for (INTEGERS) |T| { str.exportFromInt(T, ROC_BUILTINS ++ "." ++ STR ++ ".from_int."); diff --git a/crates/compiler/builtins/bitcode/src/str.zig b/crates/compiler/builtins/bitcode/src/str.zig index 930fd26cf5..6feacda78e 100644 --- a/crates/compiler/builtins/bitcode/src/str.zig +++ b/crates/compiler/builtins/bitcode/src/str.zig @@ -2596,6 +2596,10 @@ pub fn reserve(string: RocStr, capacity: usize) callconv(.C) RocStr { } } +pub fn withCapacity(capacity: usize) callconv(.C) RocStr { + return RocStr.allocate(0, capacity); +} + pub fn getScalarUnsafe(string: RocStr, index: usize) callconv(.C) extern struct { bytesParsed: usize, scalar: u32 } { const slice = string.asSlice(); const bytesParsed = @intCast(usize, std.unicode.utf8ByteSequenceLength(slice[index]) catch unreachable); diff --git a/crates/compiler/builtins/roc/Str.roc b/crates/compiler/builtins/roc/Str.roc index 1d4c8d136a..d789a01353 100644 --- a/crates/compiler/builtins/roc/Str.roc +++ b/crates/compiler/builtins/roc/Str.roc @@ -43,6 +43,7 @@ interface Str appendScalar, walkScalars, walkScalarsUntil, + withCapacity, ] imports [ Bool.{ Bool }, @@ -144,6 +145,9 @@ Utf8Problem : { byteIndex : Nat, problem : Utf8ByteProblem } isEmpty : Str -> Bool concat : Str, Str -> Str +## Returns a string of the specified capacity without any content +withCapacity : Nat -> Str + ## Combine a list of strings into a single string, with a separator ## string in between each. ## diff --git a/crates/compiler/builtins/src/bitcode.rs b/crates/compiler/builtins/src/bitcode.rs index 52878f2b3a..1c5cbdb6a0 100644 --- a/crates/compiler/builtins/src/bitcode.rs +++ b/crates/compiler/builtins/src/bitcode.rs @@ -361,6 +361,7 @@ pub const STR_RESERVE: &str = "roc_builtins.str.reserve"; pub const STR_APPEND_SCALAR: &str = "roc_builtins.str.append_scalar"; pub const STR_GET_SCALAR_UNSAFE: &str = "roc_builtins.str.get_scalar_unsafe"; pub const STR_CLONE_TO: &str = "roc_builtins.str.clone_to"; +pub const STR_WITH_CAPACITY: &str = "roc_builtins.str.with_capacity"; pub const LIST_MAP: &str = "roc_builtins.list.map"; pub const LIST_MAP2: &str = "roc_builtins.list.map2"; diff --git a/crates/compiler/can/src/builtins.rs b/crates/compiler/can/src/builtins.rs index d381f591cc..f7b0c65d15 100644 --- a/crates/compiler/can/src/builtins.rs +++ b/crates/compiler/can/src/builtins.rs @@ -121,6 +121,7 @@ map_symbol_to_lowlevel_and_arity! { StrGetScalarUnsafe; STR_GET_SCALAR_UNSAFE; 2, StrToNum; STR_TO_NUM; 1, StrGetCapacity; STR_CAPACITY; 1, + StrWithCapacity; STR_WITH_CAPACITY; 1, ListLen; LIST_LEN; 1, ListWithCapacity; LIST_WITH_CAPACITY; 1, diff --git a/crates/compiler/gen_llvm/src/llvm/build.rs b/crates/compiler/gen_llvm/src/llvm/build.rs index f084dc603d..12ee3b5ff7 100644 --- a/crates/compiler/gen_llvm/src/llvm/build.rs +++ b/crates/compiler/gen_llvm/src/llvm/build.rs @@ -6035,6 +6035,20 @@ fn run_low_level<'a, 'ctx, 'env>( bitcode::STR_TRIM_RIGHT, ) } + StrWithCapacity => { + // Str.withCapacity : Nat -> Str + debug_assert_eq!(args.len(), 1); + + let str_len = load_symbol(scope, &args[0]); + + call_str_bitcode_fn( + env, + &[], + &[str_len], + BitcodeReturns::Str, + bitcode::STR_WITH_CAPACITY, + ) + } ListLen => { // List.len : List * -> Nat debug_assert_eq!(args.len(), 1); @@ -6157,7 +6171,7 @@ fn run_low_level<'a, 'ctx, 'env>( list_prepend(env, original_wrapper, elem, elem_layout) } StrGetUnsafe => { - // List.getUnsafe : Str, Nat -> u8 + // Str.getUnsafe : Str, Nat -> u8 debug_assert_eq!(args.len(), 2); let wrapper_struct = load_symbol(scope, &args[0]); diff --git a/crates/compiler/gen_wasm/src/low_level.rs b/crates/compiler/gen_wasm/src/low_level.rs index a0a763c589..f23c487664 100644 --- a/crates/compiler/gen_wasm/src/low_level.rs +++ b/crates/compiler/gen_wasm/src/low_level.rs @@ -302,6 +302,7 @@ impl<'a> LowLevelCall<'a> { StrSubstringUnsafe => { self.load_args_and_call_zig(backend, bitcode::STR_SUBSTRING_UNSAFE) } + StrWithCapacity => self.load_args_and_call_zig(backend, bitcode::STR_WITH_CAPACITY), // List ListLen => match backend.storage.get(&self.arguments[0]) { diff --git a/crates/compiler/module/src/low_level.rs b/crates/compiler/module/src/low_level.rs index a45b965377..57ac2ac823 100644 --- a/crates/compiler/module/src/low_level.rs +++ b/crates/compiler/module/src/low_level.rs @@ -30,6 +30,7 @@ pub enum LowLevel { StrAppendScalar, StrGetScalarUnsafe, StrGetCapacity, + StrWithCapacity, ListLen, ListWithCapacity, ListReserve, @@ -249,6 +250,7 @@ map_symbol_to_lowlevel! { StrGetScalarUnsafe <= STR_GET_SCALAR_UNSAFE, StrToNum <= STR_TO_NUM, StrGetCapacity <= STR_CAPACITY, + StrWithCapacity <= STR_WITH_CAPACITY, ListLen <= LIST_LEN, ListGetCapacity <= LIST_CAPACITY, ListWithCapacity <= LIST_WITH_CAPACITY, diff --git a/crates/compiler/module/src/symbol.rs b/crates/compiler/module/src/symbol.rs index df6acd2b7f..e8376c8255 100644 --- a/crates/compiler/module/src/symbol.rs +++ b/crates/compiler/module/src/symbol.rs @@ -1296,6 +1296,7 @@ define_builtins! { 50 STR_REPLACE_EACH: "replaceEach" 51 STR_REPLACE_FIRST: "replaceFirst" 52 STR_REPLACE_LAST: "replaceLast" + 53 STR_WITH_CAPACITY: "withCapacity" } 6 LIST: "List" => { 0 LIST_LIST: "List" exposed_apply_type=true // the List.List type alias diff --git a/crates/compiler/mono/src/borrow.rs b/crates/compiler/mono/src/borrow.rs index d08835727f..a81139c125 100644 --- a/crates/compiler/mono/src/borrow.rs +++ b/crates/compiler/mono/src/borrow.rs @@ -881,7 +881,7 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] { Unreachable => arena.alloc_slice_copy(&[irrelevant]), ListLen | StrIsEmpty | StrToScalars | StrCountGraphemes | StrCountUtf8Bytes | StrGetCapacity | ListGetCapacity => arena.alloc_slice_copy(&[borrowed]), - ListWithCapacity => arena.alloc_slice_copy(&[irrelevant]), + ListWithCapacity | StrWithCapacity => arena.alloc_slice_copy(&[irrelevant]), ListReplaceUnsafe => arena.alloc_slice_copy(&[owned, irrelevant, irrelevant]), StrGetUnsafe | ListGetUnsafe => arena.alloc_slice_copy(&[borrowed, irrelevant]), ListConcat => arena.alloc_slice_copy(&[owned, owned]), diff --git a/crates/compiler/test_gen/src/gen_str.rs b/crates/compiler/test_gen/src/gen_str.rs index 6b06bf4a57..d38e8e0fcb 100644 --- a/crates/compiler/test_gen/src/gen_str.rs +++ b/crates/compiler/test_gen/src/gen_str.rs @@ -1930,3 +1930,31 @@ fn when_on_strings() { i64 ); } + +#[test] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] +fn with_capacity() { + assert_evals_to!( + indoc!( + r#" + Str.withCapacity 10 + "# + ), + RocStr::from(""), + RocStr + ); +} + +#[test] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] +fn with_capacity_concat() { + assert_evals_to!( + indoc!( + r#" + Str.withCapacity 10 |> Str.concat "Forty-two" + "# + ), + RocStr::from("Forty-two"), + RocStr + ); +} From 4bebe7e2363e3acec8db0643355c42ac39391c66 Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Sat, 8 Oct 2022 08:40:29 +0100 Subject: [PATCH 55/65] Corrections for List docs --- crates/compiler/builtins/roc/List.roc | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/crates/compiler/builtins/roc/List.roc b/crates/compiler/builtins/roc/List.roc index a729c2febb..483e0c218b 100644 --- a/crates/compiler/builtins/roc/List.roc +++ b/crates/compiler/builtins/roc/List.roc @@ -88,9 +88,8 @@ interface List ## ## ## Performance Details ## -## Under the hood, a list is a record containing a `len : Nat` field as well -## as a pointer to a reference count and a flat array of bytes. Unique lists -## store a capacity #Nat instead of a reference count. +## Under the hood, a list is a record containing a `len : Nat` field, a `capacity : Nat` +## field, and a pointer to a reference count and a flat array of bytes. ## ## ## Shared Lists ## @@ -112,9 +111,8 @@ interface List ## begins with a refcount of 1, because so far only `ratings` is referencing it. ## ## The second line alters this refcount. `{ foo: ratings` references -## the `ratings` list, which will result in its refcount getting incremented -## from 0 to 1. Similarly, `bar: ratings }` also references the `ratings` list, -## which will result in its refcount getting incremented from 1 to 2. +## the `ratings` list, and so does `bar: ratings }`. This will result in its +## refcount getting incremented from 1 to 3. ## ## Let's turn this example into a function. ## @@ -132,11 +130,11 @@ interface List ## ## Since `ratings` represented a way to reference the list, and that way is no ## longer accessible, the list's refcount gets decremented when `ratings` goes -## out of scope. It will decrease from 2 back down to 1. +## out of scope. It will decrease from 3 back down to 2. ## ## Putting these together, when we call `getRatings 5`, what we get back is ## a record with two fields, `foo`, and `bar`, each of which refers to the same -## list, and that list has a refcount of 1. +## list, and that list has a refcount of 2. ## ## Let's change the last line to be `(getRatings 5).bar` instead of `getRatings 5`: ## From c3730f49e4fd0f4f9a6169e19856401321fbfd61 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 8 Oct 2022 09:47:54 +0000 Subject: [PATCH 56/65] Bump confy from `c6b6203` to `fd069f0` Bumps [confy](https://github.com/rust-cli/confy) from `c6b6203` to `fd069f0`. - [Release notes](https://github.com/rust-cli/confy/releases) - [Commits](https://github.com/rust-cli/confy/compare/c6b62039281b8643539b436440bcea1b0d634bc7...fd069f062aa3373c846f0d8c6e3b5e2a5cd0096b) --- updated-dependencies: - dependency-name: confy dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Cargo.lock | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d973816c6f..21cf02978a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -620,10 +620,10 @@ dependencies = [ [[package]] name = "confy" -version = "0.4.0" -source = "git+https://github.com/rust-cli/confy#c6b62039281b8643539b436440bcea1b0d634bc7" +version = "0.5.0" +source = "git+https://github.com/rust-cli/confy#fd069f062aa3373c846f0d8c6e3b5e2a5cd0096b" dependencies = [ - "directories-next", + "directories", "serde", "serde_yaml", "thiserror", @@ -1160,13 +1160,13 @@ dependencies = [ ] [[package]] -name = "directories-next" -version = "2.0.0" +name = "directories" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc" +checksum = "551a778172a450d7fc12e629ca3b0428d00f6afa9a43da1b630d54604e97371c" dependencies = [ - "cfg-if 1.0.0", - "dirs-sys-next", + "cfg-if 0.1.10", + "dirs-sys", ] [[package]] @@ -1179,6 +1179,17 @@ dependencies = [ "dirs-sys-next", ] +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "dirs-sys-next" version = "0.1.2" @@ -3466,8 +3477,6 @@ dependencies = [ "roc_tracing", "serial_test", "signal-hook", - "strum", - "strum_macros", "target-lexicon", "tempfile", "ven_pretty", @@ -5154,7 +5163,7 @@ version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 0.1.10", "rand", "static_assertions", ] From c78666b3994f5679503a57c2b532fdcd87174879 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 8 Oct 2022 09:48:10 +0000 Subject: [PATCH 57/65] Bump regex from 1.5.4 to 1.6.0 in /examples/gui/breakout/platform Bumps [regex](https://github.com/rust-lang/regex) from 1.5.4 to 1.6.0. - [Release notes](https://github.com/rust-lang/regex/releases) - [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/regex/compare/1.5.4...1.6.0) --- updated-dependencies: - dependency-name: regex dependency-type: indirect ... Signed-off-by: dependabot[bot] --- examples/gui/breakout/platform/Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/gui/breakout/platform/Cargo.lock b/examples/gui/breakout/platform/Cargo.lock index 4d22e73d60..f0c43a52d2 100644 --- a/examples/gui/breakout/platform/Cargo.lock +++ b/examples/gui/breakout/platform/Cargo.lock @@ -2038,18 +2038,18 @@ dependencies = [ [[package]] name = "regex" -version = "1.5.4" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" dependencies = [ "regex-syntax", ] [[package]] name = "regex-syntax" -version = "0.6.25" +version = "0.6.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" [[package]] name = "renderdoc-sys" From 7d1cf8f6a8fec54c2843d26626e48b89aafec06c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 8 Oct 2022 09:48:11 +0000 Subject: [PATCH 58/65] Bump crossbeam-utils in /examples/gui/breakout/platform Bumps [crossbeam-utils](https://github.com/crossbeam-rs/crossbeam) from 0.8.6 to 0.8.12. - [Release notes](https://github.com/crossbeam-rs/crossbeam/releases) - [Changelog](https://github.com/crossbeam-rs/crossbeam/blob/master/CHANGELOG.md) - [Commits](https://github.com/crossbeam-rs/crossbeam/compare/crossbeam-utils-0.8.6...crossbeam-utils-0.8.12) --- updated-dependencies: - dependency-name: crossbeam-utils dependency-type: indirect ... Signed-off-by: dependabot[bot] --- examples/gui/breakout/platform/Cargo.lock | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/gui/breakout/platform/Cargo.lock b/examples/gui/breakout/platform/Cargo.lock index 4d22e73d60..19d862b928 100644 --- a/examples/gui/breakout/platform/Cargo.lock +++ b/examples/gui/breakout/platform/Cargo.lock @@ -585,12 +585,11 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.6" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcae03edb34f947e64acdb1c33ec169824e20657e9ecb61cef6c8c74dcb8120" +checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac" dependencies = [ "cfg-if 1.0.0", - "lazy_static", ] [[package]] From 59eeb43fa3c30510c9ad678bba275ea6b2660661 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 8 Oct 2022 09:48:41 +0000 Subject: [PATCH 59/65] Bump strum_macros from 0.24.2 to 0.24.3 Bumps [strum_macros](https://github.com/Peternator7/strum) from 0.24.2 to 0.24.3. - [Release notes](https://github.com/Peternator7/strum/releases) - [Changelog](https://github.com/Peternator7/strum/blob/master/CHANGELOG.md) - [Commits](https://github.com/Peternator7/strum/commits) --- updated-dependencies: - dependency-name: strum_macros dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index be118ad6ae..f7ccb6362c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4764,9 +4764,9 @@ checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" [[package]] name = "strum_macros" -version = "0.24.2" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4faebde00e8ff94316c01800f9054fd2ba77d30d9e922541913051d1d978918b" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ "heck", "proc-macro2", From 90530f51b4f0f0c7060cf845d679c28c4f78e879 Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Sat, 8 Oct 2022 12:47:57 +0200 Subject: [PATCH 60/65] re-enable benchmarks Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com> --- .github/workflows/benchmarks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index 275fa5ddbe..58e0ee422c 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -20,7 +20,7 @@ jobs: steps: - uses: actions/checkout@v3 with: - # TODO re-enable>> ref: "main" + ref: "main" clean: "true" - name: Earthly version From 654a51335a203440776b4f1851ae4705aceafce1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 8 Oct 2022 14:50:13 +0000 Subject: [PATCH 61/65] Bump dunce from 1.0.2 to 1.0.3 Bumps [dunce](https://gitlab.com/kornelski/dunce) from 1.0.2 to 1.0.3. - [Release notes](https://gitlab.com/kornelski/dunce/tags) - [Commits](https://gitlab.com/kornelski/dunce/commits/v1.0.3) --- updated-dependencies: - dependency-name: dunce dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 31 +++++++++++++++++++---------- crates/compiler/builtins/Cargo.toml | 2 +- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index be118ad6ae..311d5c4e89 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -620,10 +620,10 @@ dependencies = [ [[package]] name = "confy" -version = "0.4.0" -source = "git+https://github.com/rust-cli/confy#c6b62039281b8643539b436440bcea1b0d634bc7" +version = "0.5.0" +source = "git+https://github.com/rust-cli/confy#fd069f062aa3373c846f0d8c6e3b5e2a5cd0096b" dependencies = [ - "directories-next", + "directories", "serde", "serde_yaml", "thiserror", @@ -1160,13 +1160,13 @@ dependencies = [ ] [[package]] -name = "directories-next" -version = "2.0.0" +name = "directories" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc" +checksum = "551a778172a450d7fc12e629ca3b0428d00f6afa9a43da1b630d54604e97371c" dependencies = [ - "cfg-if 1.0.0", - "dirs-sys-next", + "cfg-if 0.1.10", + "dirs-sys", ] [[package]] @@ -1179,6 +1179,17 @@ dependencies = [ "dirs-sys-next", ] +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "dirs-sys-next" version = "0.1.2" @@ -1231,9 +1242,9 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" [[package]] name = "dunce" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453440c271cf5577fd2a40e4942540cb7d0d2f85e27c8d07dd0023c925a67541" +checksum = "0bd4b30a6560bbd9b4620f4de34c3f14f60848e58a9b7216801afcb4c7b31c3c" [[package]] name = "dynasm" diff --git a/crates/compiler/builtins/Cargo.toml b/crates/compiler/builtins/Cargo.toml index d824d44a64..840cce6f60 100644 --- a/crates/compiler/builtins/Cargo.toml +++ b/crates/compiler/builtins/Cargo.toml @@ -15,7 +15,7 @@ lazy_static = "1.4.0" [build-dependencies] # dunce can be removed once ziglang/zig#5109 is fixed -dunce = "1.0.2" +dunce = "1.0.3" [target.'cfg(target_os = "macos")'.build-dependencies] tempfile = "3.2.0" From 86b57be5ca10a21e99bf8dbf882c5a97e541b798 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 8 Oct 2022 14:50:30 +0000 Subject: [PATCH 62/65] Bump tracing-subscriber from 0.3.15 to 0.3.16 Bumps [tracing-subscriber](https://github.com/tokio-rs/tracing) from 0.3.15 to 0.3.16. - [Release notes](https://github.com/tokio-rs/tracing/releases) - [Commits](https://github.com/tokio-rs/tracing/compare/tracing-subscriber-0.3.15...tracing-subscriber-0.3.16) --- updated-dependencies: - dependency-name: tracing-subscriber dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 62 +++++++++++++++++++++++++-------------- crates/tracing/Cargo.toml | 2 +- 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index be118ad6ae..a070e3a4ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -75,15 +75,6 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - [[package]] name = "approx" version = "0.4.0" @@ -620,10 +611,10 @@ dependencies = [ [[package]] name = "confy" -version = "0.4.0" -source = "git+https://github.com/rust-cli/confy#c6b62039281b8643539b436440bcea1b0d634bc7" +version = "0.5.0" +source = "git+https://github.com/rust-cli/confy#fd069f062aa3373c846f0d8c6e3b5e2a5cd0096b" dependencies = [ - "directories-next", + "directories", "serde", "serde_yaml", "thiserror", @@ -1160,13 +1151,13 @@ dependencies = [ ] [[package]] -name = "directories-next" -version = "2.0.0" +name = "directories" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc" +checksum = "551a778172a450d7fc12e629ca3b0428d00f6afa9a43da1b630d54604e97371c" dependencies = [ - "cfg-if 1.0.0", - "dirs-sys-next", + "cfg-if 0.1.10", + "dirs-sys", ] [[package]] @@ -1179,6 +1170,17 @@ dependencies = [ "dirs-sys-next", ] +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "dirs-sys-next" version = "0.1.2" @@ -2438,6 +2440,16 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09f1f8e5676e1a1f2ee8b21f38238e1243c827531c9435624c7bfb305102cee4" +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-derive" version = "0.3.3" @@ -2636,6 +2648,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "owned_ttf_parser" version = "0.15.0" @@ -5103,9 +5121,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.29" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aeea4303076558a00714b823f9ad67d58a3bbda1df83d8827d21193156e22f7" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" dependencies = [ "once_cell", "valuable", @@ -5124,12 +5142,12 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60db860322da191b40952ad9affe65ea23e7dd6a5c442c2c42865810c6ab8e6b" +checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" dependencies = [ - "ansi_term", "matchers", + "nu-ansi-term", "once_cell", "regex", "sharded-slab", diff --git a/crates/tracing/Cargo.toml b/crates/tracing/Cargo.toml index 9cdbe41419..ee153b5aa8 100644 --- a/crates/tracing/Cargo.toml +++ b/crates/tracing/Cargo.toml @@ -8,5 +8,5 @@ description = "Utilities for setting up tracing at various executable entry poin [dependencies] tracing = { version = "0.1.36", features = ["release_max_level_off"] } -tracing-subscriber = { version = "0.3.15", features = ["env-filter"] } +tracing-subscriber = { version = "0.3.16", features = ["env-filter"] } tracing-appender = "0.2.2" From 94c51f3998d262438e9e5901eefdb73ca19da4f7 Mon Sep 17 00:00:00 2001 From: Brendan Hansknecht Date: Sat, 8 Oct 2022 09:48:39 -0700 Subject: [PATCH 63/65] add a backtrace to panics on the cli platform --- examples/cli/cli-platform/Cargo.lock | 249 ++++++++++++++++----------- examples/cli/cli-platform/Cargo.toml | 1 + examples/cli/cli-platform/src/lib.rs | 3 + 3 files changed, 151 insertions(+), 102 deletions(-) diff --git a/examples/cli/cli-platform/Cargo.lock b/examples/cli/cli-platform/Cargo.lock index 266b9b5e72..c1b2833f64 100644 --- a/examples/cli/cli-platform/Cargo.lock +++ b/examples/cli/cli-platform/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "arrayvec" version = "0.7.2" @@ -14,6 +29,21 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base64" version = "0.13.0" @@ -22,15 +52,15 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" [[package]] name = "bumpalo" -version = "3.10.0" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" +checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" [[package]] name = "bytes" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0b3de4a0c5e67e16066a0715723abd91edc2f9001d09c46e1dca929351e130e" +checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" [[package]] name = "cc" @@ -61,52 +91,51 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" dependencies = [ - "matches", "percent-encoding", ] [[package]] name = "futures-channel" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050" dependencies = [ "futures-core", ] [[package]] name = "futures-core" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" +checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf" [[package]] name = "futures-io" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" +checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68" [[package]] name = "futures-sink" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" +checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56" [[package]] name = "futures-task" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" +checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1" [[package]] name = "futures-util" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90" dependencies = [ "futures-core", "futures-io", @@ -118,10 +147,16 @@ dependencies = [ ] [[package]] -name = "h2" -version = "0.3.13" +name = "gimli" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" +checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" + +[[package]] +name = "h2" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca32592cf21ac7ccab1825cd87f6c9b3d9022c44d086172ed0966bec8af30be" dependencies = [ "bytes", "fnv", @@ -155,6 +190,7 @@ dependencies = [ name = "host" version = "0.0.1" dependencies = [ + "backtrace", "libc", "reqwest", "roc_std", @@ -184,9 +220,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" @@ -233,11 +269,10 @@ dependencies = [ [[package]] name = "idna" -version = "0.2.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" dependencies = [ - "matches", "unicode-bidi", "unicode-normalization", ] @@ -260,30 +295,24 @@ checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" [[package]] name = "itoa" -version = "1.0.2" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" [[package]] name = "js-sys" -version = "0.3.58" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" dependencies = [ "wasm-bindgen", ] -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - [[package]] name = "libc" -version = "0.2.126" +version = "0.2.134" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" +checksum = "329c933548736bc49fd575ee68c89e8be4d260064184389a5b77517cddd99ffb" [[package]] name = "log" @@ -294,12 +323,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "matches" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" - [[package]] name = "memchr" version = "2.5.0" @@ -312,6 +335,15 @@ version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +[[package]] +name = "miniz_oxide" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" +dependencies = [ + "adler", +] + [[package]] name = "mio" version = "0.8.4" @@ -335,16 +367,25 @@ dependencies = [ ] [[package]] -name = "once_cell" -version = "1.13.0" +name = "object" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" +checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" [[package]] name = "percent-encoding" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pin-project-lite" @@ -360,27 +401,27 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "proc-macro2" -version = "1.0.40" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" +checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.20" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" dependencies = [ "proc-macro2", ] [[package]] name = "reqwest" -version = "0.11.11" +version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b75aa69a3f06bbcc66ede33af2af253c6f7a86b1ca0033f60c580a27074fbf92" +checksum = "431949c384f4e2ae07605ccaa56d1d9d2ecdb5cadd4f9577ccfab29f2e5149fc" dependencies = [ "base64", "bytes", @@ -394,9 +435,9 @@ dependencies = [ "hyper-rustls", "ipnet", "js-sys", - "lazy_static", "log", "mime", + "once_cell", "percent-encoding", "pin-project-lite", "rustls", @@ -438,6 +479,12 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "rustc-demangle" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" + [[package]] name = "rustls" version = "0.20.6" @@ -452,18 +499,18 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7522c9de787ff061458fe9a829dc790a3f5b22dc571694fc5883f448b94d9a9" +checksum = "0864aeff53f8c05aa08d86e5ef839d3dfcf07aeba2db32f12db0ef716e87bd55" dependencies = [ "base64", ] [[package]] name = "ryu" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" [[package]] name = "sct" @@ -477,15 +524,15 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.140" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc855a42c7967b7c369eb5860f7164ef1f6f81c20c7cc1141f2a604e18723b03" +checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" [[package]] name = "serde_json" -version = "1.0.82" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7" +checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" dependencies = [ "itoa", "ryu", @@ -515,9 +562,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.4.4" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" +checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" dependencies = [ "libc", "winapi", @@ -537,9 +584,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "syn" -version = "1.0.98" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" +checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1" dependencies = [ "proc-macro2", "quote", @@ -563,9 +610,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.20.0" +version = "1.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57aec3cfa4c296db7255446efb4928a6be304b431a806216105542a67b6ca82e" +checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" dependencies = [ "autocfg", "bytes", @@ -573,7 +620,6 @@ dependencies = [ "memchr", "mio", "num_cpus", - "once_cell", "pin-project-lite", "socket2", "winapi", @@ -592,9 +638,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45" +checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" dependencies = [ "bytes", "futures-core", @@ -612,9 +658,9 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.35" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", "pin-project-lite", @@ -623,9 +669,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.28" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b7358be39f2f274f322d2aaed611acc57f382e8eb1e5b48cb9ae30933495ce7" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" dependencies = [ "once_cell", ] @@ -644,15 +690,15 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" [[package]] name = "unicode-ident" -version = "1.0.1" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" +checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd" [[package]] name = "unicode-normalization" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854cbdc4f7bc6ae19c820d44abdc3277ac3e1b2b93db20a636825d9322fb60e6" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ "tinyvec", ] @@ -665,13 +711,12 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" -version = "2.2.2" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" dependencies = [ "form_urlencoded", "idna", - "matches", "percent-encoding", ] @@ -693,9 +738,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.81" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -703,13 +748,13 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.81" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" dependencies = [ "bumpalo", - "lazy_static", "log", + "once_cell", "proc-macro2", "quote", "syn", @@ -718,9 +763,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.31" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de9a9cec1733468a8c657e57fa2413d2ae2c0129b95e87c5b72b8ace4d13f31f" +checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" dependencies = [ "cfg-if", "js-sys", @@ -730,9 +775,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.81" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -740,9 +785,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.81" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ "proc-macro2", "quote", @@ -753,15 +798,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.81" +version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" [[package]] name = "web-sys" -version = "0.3.58" +version = "0.3.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fed94beee57daf8dd7d51f2b15dc2bcde92d7a72304cdf662a4371008b71b90" +checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" dependencies = [ "js-sys", "wasm-bindgen", @@ -779,9 +824,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.22.4" +version = "0.22.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1c760f0d366a6c24a02ed7816e23e691f5d92291f94d15e836006fd11b04daf" +checksum = "368bfe657969fb01238bb756d351dcade285e0f6fcbd36dcb23359a5169975be" dependencies = [ "webpki", ] diff --git a/examples/cli/cli-platform/Cargo.toml b/examples/cli/cli-platform/Cargo.toml index 250b0419de..c50e3702ca 100644 --- a/examples/cli/cli-platform/Cargo.toml +++ b/examples/cli/cli-platform/Cargo.toml @@ -20,5 +20,6 @@ path = "src/main.rs" roc_std = { path = "../../../crates/roc_std" } libc = "0.2" reqwest = { version="0.11.11", default-features=false, features=["blocking", "rustls-tls"] } +backtrace = "0.3" [workspace] diff --git a/examples/cli/cli-platform/src/lib.rs b/examples/cli/cli-platform/src/lib.rs index 57808a0a53..5140d17587 100644 --- a/examples/cli/cli-platform/src/lib.rs +++ b/examples/cli/cli-platform/src/lib.rs @@ -3,6 +3,7 @@ mod file_glue; mod glue; +use backtrace::Backtrace; use core::alloc::Layout; use core::ffi::c_void; use core::mem::MaybeUninit; @@ -64,6 +65,8 @@ pub unsafe extern "C" fn roc_panic(c_ptr: *mut c_void, tag_id: u32) { let slice = CStr::from_ptr(c_ptr as *const c_char); let string = slice.to_str().unwrap(); eprintln!("Roc hit a panic: {}", string); + eprintln!("Printing backtrace. If it looks wrong, try rerunning your app without `--optimize` and with `--linker=legacy`"); + eprintln!("{:?}", Backtrace::new()); std::process::exit(1); } _ => todo!(), From 44ec52218df8745c8a3f54d68edac3d822a65c48 Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Sat, 8 Oct 2022 19:46:44 +0200 Subject: [PATCH 64/65] x86 should be x86_64 --- getting_started/README.md | 4 ++-- getting_started/{linux_x86.md => linux_x86_64.md} | 2 +- getting_started/{macos_x86.md => macos_x86_64.md} | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename getting_started/{linux_x86.md => linux_x86_64.md} (97%) rename getting_started/{macos_x86.md => macos_x86_64.md} (96%) diff --git a/getting_started/README.md b/getting_started/README.md index 9c7b2870eb..f05c36a90e 100644 --- a/getting_started/README.md +++ b/getting_started/README.md @@ -12,9 +12,9 @@ If you have a specific question, the [FAQ](../FAQ.md) might have an answer, alth ## Installation -- [Linux x86](linux_x86.md) +- [Linux x86_64](linux_x86_64.md) - [MacOS Apple Silicon](macos_apple_silicon.md) -- [MacOS x86](macos_x86.md) +- [MacOS x86_64](macos_x86_64.md) - [Windows](windows.md) - [Other](other.md) diff --git a/getting_started/linux_x86.md b/getting_started/linux_x86_64.md similarity index 97% rename from getting_started/linux_x86.md rename to getting_started/linux_x86_64.md index 49cb30fd95..3b390d5b23 100644 --- a/getting_started/linux_x86.md +++ b/getting_started/linux_x86_64.md @@ -1,4 +1,4 @@ -# Roc installation guide for x86 Linux systems +# Roc installation guide for x86_64 Linux systems ## How to install Roc diff --git a/getting_started/macos_x86.md b/getting_started/macos_x86_64.md similarity index 96% rename from getting_started/macos_x86.md rename to getting_started/macos_x86_64.md index a1efba5b49..23aecdb905 100644 --- a/getting_started/macos_x86.md +++ b/getting_started/macos_x86_64.md @@ -1,4 +1,4 @@ -# Roc installation guide for x86 macOS systems +# Roc installation guide for x86_64 macOS systems ## How to install Roc From 03da41c060d61b36367f7168e67665b389c57443 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Sat, 8 Oct 2022 15:03:03 -0400 Subject: [PATCH 65/65] Format CLI backtraces --- examples/cli/cli-platform/src/lib.rs | 102 +++++++++++++++++++++++++-- 1 file changed, 98 insertions(+), 4 deletions(-) diff --git a/examples/cli/cli-platform/src/lib.rs b/examples/cli/cli-platform/src/lib.rs index 5140d17587..4813f3d39f 100644 --- a/examples/cli/cli-platform/src/lib.rs +++ b/examples/cli/cli-platform/src/lib.rs @@ -3,7 +3,6 @@ mod file_glue; mod glue; -use backtrace::Backtrace; use core::alloc::Layout; use core::ffi::c_void; use core::mem::MaybeUninit; @@ -64,15 +63,110 @@ pub unsafe extern "C" fn roc_panic(c_ptr: *mut c_void, tag_id: u32) { 0 => { let slice = CStr::from_ptr(c_ptr as *const c_char); let string = slice.to_str().unwrap(); - eprintln!("Roc hit a panic: {}", string); - eprintln!("Printing backtrace. If it looks wrong, try rerunning your app without `--optimize` and with `--linker=legacy`"); - eprintln!("{:?}", Backtrace::new()); + eprintln!("Roc crashed with:\n\n\t{}\n", string); + + print_backtrace(); std::process::exit(1); } _ => todo!(), } } +fn print_backtrace() { + eprintln!("Here is the call stack that led to the crash:\n"); + + let mut entries = Vec::new(); + + #[derive(Default)] + struct Entry { + pub fn_name: String, + pub filename: Option, + pub line: Option, + pub col: Option, + } + + backtrace::trace(|frame| { + backtrace::resolve_frame(frame, |symbol| { + if let Some(fn_name) = symbol.name() { + let fn_name = fn_name.to_string(); + + if should_show_in_backtrace(&fn_name) { + let mut entry: Entry = Default::default(); + + entry.fn_name = format_fn_name(&fn_name); + + if let Some(path) = symbol.filename() { + entry.filename = Some(path.to_string_lossy().into_owned()); + }; + + entry.line = symbol.lineno(); + entry.col = symbol.colno(); + + entries.push(entry); + } + } else { + entries.push(Entry { + fn_name: "???".to_string(), + ..Default::default() + }); + } + }); + + true // keep going to the next frame + }); + + for entry in entries { + eprintln!("\t{}", entry.fn_name); + + if let Some(filename) = entry.filename { + eprintln!("\t\t{filename}"); + } + } + + eprintln!("\nOptimizations can make this list inaccurate! If it looks wrong, try running without `--optimize` and with `--linker=legacy`\n"); +} + +fn should_show_in_backtrace(fn_name: &str) -> bool { + let is_from_rust = fn_name.contains("::"); + let is_host_fn = fn_name.starts_with("roc_panic") + || fn_name.starts_with("_Effect_effect") + || fn_name.starts_with("_roc__") + || fn_name.starts_with("rust_main") + || fn_name == "_main"; + + !is_from_rust && !is_host_fn +} + +fn format_fn_name(fn_name: &str) -> String { + // e.g. convert "_Num_sub_a0c29024d3ec6e3a16e414af99885fbb44fa6182331a70ab4ca0886f93bad5" + // to ["Num", "sub", "a0c29024d3ec6e3a16e414af99885fbb44fa6182331a70ab4ca0886f93bad5"] + let mut pieces_iter = fn_name.split("_"); + + if let (_, Some(module_name), Some(name)) = + (pieces_iter.next(), pieces_iter.next(), pieces_iter.next()) + { + display_roc_fn(module_name, name) + } else { + "???".to_string() + } +} + +fn display_roc_fn(module_name: &str, fn_name: &str) -> String { + let module_name = if module_name == "#UserApp" { + "app" + } else { + module_name + }; + + let fn_name = if fn_name.parse::().is_ok() { + "(anonymous function)" + } else { + fn_name + }; + + format!("\u{001B}[36m{module_name}\u{001B}[39m.{fn_name}") +} + #[no_mangle] pub unsafe extern "C" fn roc_memcpy(dst: *mut c_void, src: *mut c_void, n: usize) -> *mut c_void { libc::memcpy(dst, src, n)