Merge remote-tracking branch 'remote/main' into list-splitting

This commit is contained in:
Luke Boswell 2024-11-13 07:34:03 +11:00
commit 69c2fef943
No known key found for this signature in database
GPG key ID: F6DB3C9DB47377B0
244 changed files with 3601 additions and 5671 deletions

3
.gitattributes vendored
View file

@ -1,4 +1,5 @@
# Require roc files to be checked out with Unix line endings, even on windows # Require roc files to be checked out with Unix line endings, even on windows
*.roc text eol=lf *.roc text eol=lf
* text=auto eol=lf
crates/compiler/test_mono/generated/* linguist-generated=true crates/compiler/test_mono/generated/* linguist-generated=true

View file

@ -2,7 +2,7 @@ on:
#pull_request: #pull_request:
workflow_dispatch: workflow_dispatch:
schedule: schedule:
- cron: '0 9 * * *' - cron: "0 9 * * *"
name: Nightly Release macOS Apple Silicon name: Nightly Release macOS Apple Silicon
@ -30,15 +30,15 @@ jobs:
run: cargo test --locked --release run: cargo test --locked --release
- name: get commit SHA - name: get commit SHA
run: echo "SHA=$(git rev-parse --short "$GITHUB_SHA")" >> $GITHUB_ENV run: echo "SHA=$(git rev-parse --short "$GITHUB_SHA")" >> $GITHUB_ENV
- name: get date - name: get date
run: echo "DATE=$(date "+%Y-%m-%d")" >> $GITHUB_ENV run: echo "DATE=$(date "+%Y-%m-%d")" >> $GITHUB_ENV
- name: build file name - name: build file name
env: env:
DATE: ${{ env.DATE }} DATE: ${{ env.DATE }}
SHA: ${{ env.SHA }} SHA: ${{ env.SHA }}
run: echo "RELEASE_FOLDER_NAME=roc_nightly-macos_apple_silicon-$DATE-$SHA" >> $GITHUB_ENV run: echo "RELEASE_FOLDER_NAME=roc_nightly-macos_apple_silicon-$DATE-$SHA" >> $GITHUB_ENV
- name: write version to file - name: write version to file
@ -56,8 +56,9 @@ jobs:
- name: extract tar for a quick test - name: extract tar for a quick test
run: ls | grep tar | xargs tar -xf run: ls | grep tar | xargs tar -xf
- name: test with rust platform - name: test with zig platform
run: cd ${{ env.RELEASE_FOLDER_NAME }} && ./roc examples/platform-switching/rocLovesRust.roc run: |
cd ${{ env.RELEASE_FOLDER_NAME }} && ./roc --build-host --suppress-build-host-warning crates/cli/tests/test-projects/test-platform-simple-zig/app.roc
- name: print short commit SHA - name: print short commit SHA
run: git rev-parse --short "$GITHUB_SHA" run: git rev-parse --short "$GITHUB_SHA"
@ -66,6 +67,6 @@ jobs:
- name: Upload artifact Actually uploading to github releases has to be done manually - name: Upload artifact Actually uploading to github releases has to be done manually
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: ${{ env.RELEASE_FOLDER_NAME }}.tar.gz name: ${{ env.RELEASE_FOLDER_NAME }}.tar.gz
path: ${{ env.RELEASE_FOLDER_NAME }}.tar.gz path: ${{ env.RELEASE_FOLDER_NAME }}.tar.gz
retention-days: 4 retention-days: 4

View file

@ -23,7 +23,7 @@ jobs:
- name: roc test all builtins - name: roc test all builtins
run: nix develop -c ./ci/roc_test_builtins.sh run: nix develop -c ./ci/roc_test_builtins.sh
- name: test wasm32 cli_run - name: test wasm32 cli_tests
run: nix develop -c cargo test --locked --release --features="wasm32-cli-run" run: nix develop -c cargo test --locked --release --features="wasm32-cli-run"
- name: test the dev backend # these tests require an explicit feature flag - name: test the dev backend # these tests require an explicit feature flag

View file

@ -34,17 +34,11 @@ jobs:
# for skipped tests: see issue 6274 # for skipped tests: see issue 6274
- name: execute tests with --release - name: execute tests with --release
run: nix develop -c cargo test --locked --release -- --skip cli_run::inspect_gui --skip cli_run::hello_gui run: nix develop -c cargo test --locked --release -- --skip cli_tests::inspect_gui --skip cli_tests::hello_gui
- name: roc test all builtins - name: roc test all builtins
run: nix develop -c ./ci/roc_test_builtins.sh run: nix develop -c ./ci/roc_test_builtins.sh
- name: make a libapp.so for the next step
run: nix develop -c cargo run -- gen-stub-lib examples/platform-switching/rocLovesRust.roc
- name: check that the platform`s produced dylib is loadable
run: cd examples/platform-switching/rust-platform && nix develop -c cargo test --release --locked
- name: test aarch64 dev backend - name: test aarch64 dev backend
run: nix develop -c cargo nextest-gen-dev --locked --release --no-fail-fast run: nix develop -c cargo nextest-gen-dev --locked --release --no-fail-fast

View file

@ -16,15 +16,9 @@ jobs:
- uses: cachix/install-nix-action@v22 - uses: cachix/install-nix-action@v22
- name: execute cli_run tests only, the full tests take too long but are run nightly - name: execute cli_tests tests only, the full tests take too long but are run nightly
run: nix develop -c cargo test --locked --release -p roc_cli -- --skip hello_gui run: nix develop -c cargo test --locked --release -p roc_cli -- --skip hello_gui
# see 5932 for hello_gui # see 5932 for hello_gui
- name: roc test all builtins - name: roc test all builtins
run: nix develop -c ./ci/roc_test_builtins.sh run: nix develop -c ./ci/roc_test_builtins.sh
- name: make a libapp.so for the next step
run: nix develop -c cargo run -- gen-stub-lib examples/platform-switching/rocLovesRust.roc
- name: check that the platform`s produced dylib is loadable
run: cd examples/platform-switching/rust-platform && nix develop -c cargo test --release --locked

View file

@ -29,9 +29,6 @@ jobs:
- name: test roc hello world - name: test roc hello world
run: cd roc_nightly && ./roc examples/helloWorld.roc run: cd roc_nightly && ./roc examples/helloWorld.roc
- name: test platform switching rust
run: cd roc_nightly && ./roc examples/platform-switching/rocLovesRust.roc
- name: test platform switching zig - name: test platform switching zig
run: cd roc_nightly && ./roc examples/platform-switching/rocLovesZig.roc run: cd roc_nightly && ./roc examples/platform-switching/rocLovesZig.roc

View file

@ -37,13 +37,10 @@ jobs:
- name: regular rust tests - name: regular rust tests
# see #5904 for skipped test # see #5904 for skipped test
run: cargo test --locked --release -- --skip cli_run::expects_dev_and_test run: cargo test --locked --release -- --skip cli_tests::expects_dev_and_test
- name: tests examples in docs - name: tests examples in docs
run: cargo test --doc --release run: cargo test --doc --release
- name: check that the platform`s produced dylib is loadable
run: cd examples/platform-switching/rust-platform && LD_LIBRARY_PATH=. cargo test --release --locked
- name: test the dev backend # these tests require an explicit feature flag - name: test the dev backend # these tests require an explicit feature flag
run: cargo test --locked --release --package test_gen --no-default-features --features gen-dev run: cargo test --locked --release --package test_gen --no-default-features --features gen-dev

33
Cargo.lock generated
View file

@ -463,20 +463,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961"
[[package]] [[package]]
name = "cli_utils" name = "cli_test_utils"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"bumpalo", "bumpalo",
"const_format",
"criterion", "criterion",
"lazy_static",
"regex", "regex",
"rlimit", "rlimit",
"roc_cli",
"roc_collections", "roc_collections",
"roc_command_utils", "roc_command_utils",
"roc_load", "roc_load",
"roc_module", "roc_module",
"roc_reporting", "roc_reporting",
"serde", "serde",
"serde-xml-rs",
"tempfile", "tempfile",
] ]
@ -2383,13 +2385,14 @@ dependencies = [
"bumpalo", "bumpalo",
"chrono", "chrono",
"clap 4.4.6", "clap 4.4.6",
"cli_utils", "cli_test_utils",
"const_format", "const_format",
"criterion", "criterion",
"distance", "distance",
"errno", "errno",
"indoc", "indoc",
"inkwell", "inkwell",
"insta",
"libc", "libc",
"libloading", "libloading",
"mimalloc", "mimalloc",
@ -2418,10 +2421,8 @@ dependencies = [
"roc_repl_expect", "roc_repl_expect",
"roc_reporting", "roc_reporting",
"roc_target", "roc_target",
"roc_test_utils",
"roc_tracing", "roc_tracing",
"roc_wasm_interp", "roc_wasm_interp",
"serial_test",
"signal-hook", "signal-hook",
"strum", "strum",
"target-lexicon", "target-lexicon",
@ -2626,7 +2627,7 @@ name = "roc_glue"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"bumpalo", "bumpalo",
"cli_utils", "cli_test_utils",
"dircpy", "dircpy",
"fnv", "fnv",
"indexmap", "indexmap",
@ -3445,18 +3446,6 @@ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]]
name = "serde-xml-rs"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb3aa78ecda1ebc9ec9847d5d3aba7d618823446a049ba2491940506da6e2782"
dependencies = [
"log",
"serde",
"thiserror",
"xml-rs",
]
[[package]] [[package]]
name = "serde_cbor" name = "serde_cbor"
version = "0.11.2" version = "0.11.2"
@ -4362,7 +4351,7 @@ name = "valgrind"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"bumpalo", "bumpalo",
"cli_utils", "cli_test_utils",
"indoc", "indoc",
"roc_build", "roc_build",
"roc_command_utils", "roc_command_utils",
@ -4828,12 +4817,6 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "xml-rs"
version = "0.8.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a"
[[package]] [[package]]
name = "yaml-rust" name = "yaml-rust"
version = "0.4.5" version = "0.4.5"

View file

@ -5,7 +5,7 @@ members = [
"crates/fs", "crates/fs",
"crates/glue", "crates/glue",
"crates/cli", "crates/cli",
"crates/cli_utils", "crates/cli_test_utils",
"crates/highlight", "crates/highlight",
"crates/error_macros", "crates/error_macros",
"crates/reporting", "crates/reporting",
@ -19,7 +19,7 @@ members = [
"crates/roc_std", "crates/roc_std",
"crates/test_utils", "crates/test_utils",
"crates/test_utils_dir", "crates/test_utils_dir",
"crates/valgrind", "crates/valgrind_tests",
"crates/tracing", "crates/tracing",
"crates/utils/*", "crates/utils/*",
"crates/soa", "crates/soa",
@ -173,7 +173,6 @@ schemars = "0.8.12"
serde = { version = "1.0.153", features = [ serde = { version = "1.0.153", features = [
"derive", "derive",
] } # update roc_std/Cargo.toml on change ] } # update roc_std/Cargo.toml on change
serde-xml-rs = "0.6.0"
serde_json = "1.0.94" # update roc_std/Cargo.toml on change serde_json = "1.0.94" # update roc_std/Cargo.toml on change
serial_test = "1.0.0" serial_test = "1.0.0"
signal-hook = "0.3.15" signal-hook = "0.3.15"

View file

@ -5,14 +5,14 @@ set -euxo pipefail
# if to prevent unset vars errror # if to prevent unset vars errror
if [ -n "$(ls | grep -v "roc_nightly.*tar\.gz" | grep -v "^ci$")" ]; then if [ -n "$(ls | grep -v "roc_nightly.*tar\.gz" | grep -v "^ci$")" ]; then
# Remove everything in this dir except the tar and ci folder. # Remove everything in this dir except the tar and ci folder.
# We want to test like a user who would have downloaded the release, so we clean up all files from the repo checkout. # We want to test like a user who would have downloaded the release, so we clean up all files from the repo checkout.
to_delete=$(ls | grep -v "roc_nightly.*tar\.gz" | grep -v "^ci$") to_delete=$(ls | grep -v "roc_nightly.*tar\.gz" | grep -v "^ci$")
for file_or_dir in $to_delete for file_or_dir in $to_delete
do do
echo "Removing: $file_or_dir" echo "Removing: $file_or_dir"
rm -rf "$file_or_dir" rm -rf "$file_or_dir"
done done
fi fi
@ -31,7 +31,8 @@ cd roc_nightly
# test roc hello world # test roc hello world
./roc examples/helloWorld.roc ./roc examples/helloWorld.roc
# test rust platform # test rust platform (first prebuild the host)
examples/platform-switching/rust-platform/build.sh
./roc examples/platform-switching/rocLovesRust.roc ./roc examples/platform-switching/rocLovesRust.roc
# test zig platform # test zig platform

View file

@ -12,9 +12,9 @@ cargo doc --package roc_ast --open
The `roc` binary that brings together all functionality in the Roc toolset. The `roc` binary that brings together all functionality in the Roc toolset.
## `cli_utils/` - `cli_utils` ## `cli_test_utils/` - `cli_test_utils`
Provides shared code for cli tests and benchmarks. Provides shared code for cli tests, cli benchmarks, glue tests, valgrind crate.
## `compiler/` ## `compiler/`

View file

@ -32,11 +32,11 @@ target-x86 = ["roc_build/target-x86", "roc_repl_cli/target-x86"]
target-x86_64 = ["roc_build/target-x86_64", "roc_repl_cli/target-x86_64"] target-x86_64 = ["roc_build/target-x86_64", "roc_repl_cli/target-x86_64"]
target-all = [ target-all = [
"target-aarch64", "target-aarch64",
"target-arm", "target-arm",
"target-x86", "target-x86",
"target-x86_64", "target-x86_64",
"target-wasm32", "target-wasm32",
] ]
sanitizers = ["roc_build/sanitizers"] sanitizers = ["roc_build/sanitizers"]
@ -90,15 +90,14 @@ roc_repl_expect = { path = "../repl_expect" }
[dev-dependencies] [dev-dependencies]
cli_utils = { path = "../cli_utils" } cli_test_utils = { path = "../cli_test_utils" }
roc_test_utils = { path = "../test_utils" }
roc_command_utils = { path = "../utils/command" } roc_command_utils = { path = "../utils/command" }
criterion.workspace = true criterion.workspace = true
indoc.workspace = true indoc.workspace = true
parking_lot.workspace = true parking_lot.workspace = true
pretty_assertions.workspace = true pretty_assertions.workspace = true
serial_test.workspace = true insta.workspace = true
[build-dependencies] [build-dependencies]
chrono.workspace = true chrono.workspace = true

View file

@ -1,6 +1,6 @@
use std::time::Duration; use std::time::Duration;
use cli_utils::bench_utils::{ use cli_test_utils::bench_utils::{
bench_cfold, bench_deriv, bench_nqueens, bench_quicksort, bench_rbtree_ck, bench_cfold, bench_deriv, bench_nqueens, bench_quicksort, bench_rbtree_ck,
}; };
use criterion::{measurement::WallTime, BenchmarkGroup, Criterion, SamplingMode}; use criterion::{measurement::WallTime, BenchmarkGroup, Criterion, SamplingMode};

View file

@ -263,7 +263,7 @@ mod tests {
use std::io::Write; use std::io::Write;
use tempfile::{tempdir, TempDir}; use tempfile::{tempdir, TempDir};
const FORMATTED_ROC: &str = r#"app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.16.0/O00IPk-Krg_diNS2dVWlI0ZQP794Vctxzv0ha96mK0E.tar.br" } const FORMATTED_ROC: &str = r#"app [main] { pf: platform "platform/main.roc" }
import pf.Stdout import pf.Stdout
import pf.Stdin import pf.Stdin
@ -273,11 +273,7 @@ main =
name = Stdin.line! name = Stdin.line!
Stdout.line! "Hi $(name)!""#; Stdout.line! "Hi $(name)!""#;
const UNFORMATTED_ROC: &str = r#"app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.16.0/O00IPk-Krg_diNS2dVWlI0ZQP794Vctxzv0ha96mK0E.tar.br" } const UNFORMATTED_ROC: &str = r#"app [main] { pf: platform "platform/main.roc" }
import pf.Stdout
import pf.Stdin
main = main =
Stdout.line! "What's your name?" Stdout.line! "What's your name?"

View file

@ -54,7 +54,6 @@ pub const CMD_VERSION: &str = "version";
pub const CMD_FORMAT: &str = "format"; pub const CMD_FORMAT: &str = "format";
pub const CMD_TEST: &str = "test"; pub const CMD_TEST: &str = "test";
pub const CMD_GLUE: &str = "glue"; pub const CMD_GLUE: &str = "glue";
pub const CMD_GEN_STUB_LIB: &str = "gen-stub-lib";
pub const CMD_PREPROCESS_HOST: &str = "preprocess-host"; pub const CMD_PREPROCESS_HOST: &str = "preprocess-host";
pub const FLAG_EMIT_LLVM_IR: &str = "emit-llvm-ir"; pub const FLAG_EMIT_LLVM_IR: &str = "emit-llvm-ir";
@ -72,7 +71,8 @@ pub const FLAG_VERBOSE: &str = "verbose";
pub const FLAG_NO_COLOR: &str = "no-color"; pub const FLAG_NO_COLOR: &str = "no-color";
pub const FLAG_NO_HEADER: &str = "no-header"; pub const FLAG_NO_HEADER: &str = "no-header";
pub const FLAG_LINKER: &str = "linker"; pub const FLAG_LINKER: &str = "linker";
pub const FLAG_PREBUILT: &str = "prebuilt-platform"; pub const FLAG_BUILD_HOST: &str = "build-host";
pub const FLAG_SUPPRESS_BUILD_HOST_WARNING: &str = "suppress-build-host-warning";
pub const FLAG_CHECK: &str = "check"; pub const FLAG_CHECK: &str = "check";
pub const FLAG_STDIN: &str = "stdin"; pub const FLAG_STDIN: &str = "stdin";
pub const FLAG_STDOUT: &str = "stdout"; pub const FLAG_STDOUT: &str = "stdout";
@ -142,9 +142,15 @@ pub fn build_app() -> Command {
.value_parser(["surgical", "legacy"]) .value_parser(["surgical", "legacy"])
.required(false); .required(false);
let flag_prebuilt = Arg::new(FLAG_PREBUILT) let flag_build_host = Arg::new(FLAG_BUILD_HOST)
.long(FLAG_PREBUILT) .long(FLAG_BUILD_HOST)
.help("Assume the platform has been prebuilt and skip rebuilding the platform\n(This is enabled implicitly when using `roc build` with a --target other than `--target <current machine>`, unless the target is wasm.)") .help("WARNING: platforms are responsible for building hosts, this flag will be removed when internal test platforms have a build script")
.action(ArgAction::SetTrue)
.required(false);
let flag_suppress_build_host_warning = Arg::new(FLAG_SUPPRESS_BUILD_HOST_WARNING)
.long(FLAG_SUPPRESS_BUILD_HOST_WARNING)
.help("WARNING: platforms are responsible for building hosts, this flag will be removed when internal test platforms have a build script")
.action(ArgAction::SetTrue) .action(ArgAction::SetTrue)
.required(false); .required(false);
@ -201,7 +207,8 @@ pub fn build_app() -> Command {
.arg(flag_profiling.clone()) .arg(flag_profiling.clone())
.arg(flag_time.clone()) .arg(flag_time.clone())
.arg(flag_linker.clone()) .arg(flag_linker.clone())
.arg(flag_prebuilt.clone()) .arg(flag_build_host.clone())
.arg(flag_suppress_build_host_warning.clone())
.arg(flag_fuzz.clone()) .arg(flag_fuzz.clone())
.arg(flag_wasm_stack_size_kb) .arg(flag_wasm_stack_size_kb)
.arg( .arg(
@ -253,7 +260,8 @@ pub fn build_app() -> Command {
.arg(flag_profiling.clone()) .arg(flag_profiling.clone())
.arg(flag_time.clone()) .arg(flag_time.clone())
.arg(flag_linker.clone()) .arg(flag_linker.clone())
.arg(flag_prebuilt.clone()) .arg(flag_build_host.clone())
.arg(flag_suppress_build_host_warning.clone())
.arg(flag_fuzz.clone()) .arg(flag_fuzz.clone())
.arg( .arg(
Arg::new(FLAG_VERBOSE) Arg::new(FLAG_VERBOSE)
@ -298,7 +306,8 @@ pub fn build_app() -> Command {
.arg(flag_profiling.clone()) .arg(flag_profiling.clone())
.arg(flag_time.clone()) .arg(flag_time.clone())
.arg(flag_linker.clone()) .arg(flag_linker.clone())
.arg(flag_prebuilt.clone()) .arg(flag_build_host.clone())
.arg(flag_suppress_build_host_warning.clone())
.arg(flag_fuzz.clone()) .arg(flag_fuzz.clone())
.arg(roc_file_to_run.clone()) .arg(roc_file_to_run.clone())
.arg(args_for_app.clone().last(true)) .arg(args_for_app.clone().last(true))
@ -313,7 +322,8 @@ pub fn build_app() -> Command {
.arg(flag_profiling.clone()) .arg(flag_profiling.clone())
.arg(flag_time.clone()) .arg(flag_time.clone())
.arg(flag_linker.clone()) .arg(flag_linker.clone())
.arg(flag_prebuilt.clone()) .arg(flag_build_host.clone())
.arg(flag_suppress_build_host_warning.clone())
.arg(flag_fuzz.clone()) .arg(flag_fuzz.clone())
.arg(roc_file_to_run.clone()) .arg(roc_file_to_run.clone())
.arg(args_for_app.clone().last(true)) .arg(args_for_app.clone().last(true))
@ -404,23 +414,6 @@ pub fn build_app() -> Command {
.default_value(DEFAULT_ROC_FILENAME) .default_value(DEFAULT_ROC_FILENAME)
) )
) )
.subcommand(Command::new(CMD_GEN_STUB_LIB)
.about("Generate a stubbed shared library that can be used for linking a platform binary.\nThe stubbed library has prototypes, but no function bodies.\n\nNote: This command will be removed in favor of just using `roc build` once all platforms support the surgical linker")
.arg(
Arg::new(ROC_FILE)
.help("The .roc file for an app using the platform")
.value_parser(value_parser!(PathBuf))
.required(true)
)
.arg(
Arg::new(FLAG_TARGET)
.long(FLAG_TARGET)
.help("Choose a different target")
.default_value(Into::<&'static str>::into(Target::default()))
.value_parser(build_target_values_parser.clone())
.required(false),
)
)
.subcommand(Command::new(CMD_PREPROCESS_HOST) .subcommand(Command::new(CMD_PREPROCESS_HOST)
.about("Runs the surgical linker preprocessor to generate `.rh` and `.rm` files.") .about("Runs the surgical linker preprocessor to generate `.rh` and `.rm` files.")
.arg( .arg(
@ -465,7 +458,8 @@ pub fn build_app() -> Command {
.arg(flag_profiling) .arg(flag_profiling)
.arg(flag_time) .arg(flag_time)
.arg(flag_linker) .arg(flag_linker)
.arg(flag_prebuilt) .arg(flag_build_host)
.arg(flag_suppress_build_host_warning)
.arg(flag_fuzz) .arg(flag_fuzz)
.arg(roc_file_to_run) .arg(roc_file_to_run)
.arg(args_for_app.trailing_var_arg(true)) .arg(args_for_app.trailing_var_arg(true))
@ -731,7 +725,6 @@ pub fn build(
roc_cache_dir: RocCacheDir<'_>, roc_cache_dir: RocCacheDir<'_>,
link_type: LinkType, link_type: LinkType,
) -> io::Result<i32> { ) -> io::Result<i32> {
use roc_build::program::build_file;
use BuildConfig::*; use BuildConfig::*;
let path = matches.get_one::<PathBuf>(ROC_FILE).unwrap(); let path = matches.get_one::<PathBuf>(ROC_FILE).unwrap();
@ -879,17 +872,10 @@ pub fn build(
LinkingStrategy::Surgical LinkingStrategy::Surgical
}; };
let prebuilt = { // All hosts should be prebuilt, this flag keeps the rebuilding behvaiour
let cross_compile = target != Target::default(); // as required for internal tests
let targeting_wasm = matches!(target.architecture(), Architecture::Wasm32); let build_host = matches.get_flag(FLAG_BUILD_HOST);
let suppress_build_host_warning = matches.get_flag(FLAG_SUPPRESS_BUILD_HOST_WARNING);
matches.get_flag(FLAG_PREBUILT) ||
// When compiling for a different target, assume a prebuilt platform.
// Otherwise compilation would most likely fail because many toolchains
// assume you're compiling for the current machine. We make an exception
// for Wasm, because cross-compiling is the norm in that case.
(cross_compile && !targeting_wasm)
};
let fuzz = matches.get_flag(FLAG_FUZZ); let fuzz = matches.get_flag(FLAG_FUZZ);
if fuzz && !matches!(code_gen_backend, CodeGenBackend::Llvm(_)) { if fuzz && !matches!(code_gen_backend, CodeGenBackend::Llvm(_)) {
@ -917,7 +903,7 @@ pub fn build(
let load_config = standard_load_config(target, build_ordering, threading); let load_config = standard_load_config(target, build_ordering, threading);
let res_binary_path = build_file( let res_binary_path = roc_build::program::build_file(
&arena, &arena,
target, target,
path.to_owned(), path.to_owned(),
@ -925,7 +911,8 @@ pub fn build(
emit_timings, emit_timings,
link_type, link_type,
linking_strategy, linking_strategy,
prebuilt, build_host,
suppress_build_host_warning,
wasm_dev_stack_bytes, wasm_dev_stack_bytes,
roc_cache_dir, roc_cache_dir,
load_config, load_config,

View file

@ -4,17 +4,16 @@ use roc_build::link::LinkType;
use roc_build::program::{check_file, CodeGenBackend}; use roc_build::program::{check_file, CodeGenBackend};
use roc_cli::{ use roc_cli::{
build_app, format_files, format_src, test, BuildConfig, FormatMode, CMD_BUILD, CMD_CHECK, build_app, format_files, format_src, test, BuildConfig, FormatMode, CMD_BUILD, CMD_CHECK,
CMD_DEV, CMD_DOCS, CMD_FORMAT, CMD_GEN_STUB_LIB, CMD_GLUE, CMD_PREPROCESS_HOST, CMD_REPL, CMD_DEV, CMD_DOCS, CMD_FORMAT, CMD_GLUE, CMD_PREPROCESS_HOST, CMD_REPL, CMD_RUN, CMD_TEST,
CMD_RUN, CMD_TEST, CMD_VERSION, DIRECTORY_OR_FILES, FLAG_CHECK, FLAG_DEV, FLAG_LIB, FLAG_MAIN, CMD_VERSION, DIRECTORY_OR_FILES, FLAG_CHECK, FLAG_DEV, FLAG_LIB, FLAG_MAIN, FLAG_NO_COLOR,
FLAG_NO_COLOR, FLAG_NO_HEADER, FLAG_NO_LINK, FLAG_OUTPUT, FLAG_PP_DYLIB, FLAG_PP_HOST, FLAG_NO_HEADER, FLAG_NO_LINK, FLAG_OUTPUT, FLAG_PP_DYLIB, FLAG_PP_HOST, FLAG_PP_PLATFORM,
FLAG_PP_PLATFORM, FLAG_STDIN, FLAG_STDOUT, FLAG_TARGET, FLAG_TIME, GLUE_DIR, GLUE_SPEC, FLAG_STDIN, FLAG_STDOUT, FLAG_TARGET, FLAG_TIME, GLUE_DIR, GLUE_SPEC, ROC_FILE, VERSION,
ROC_FILE, VERSION,
}; };
use roc_docs::generate_docs_html; use roc_docs::generate_docs_html;
use roc_error_macros::user_error; use roc_error_macros::user_error;
use roc_gen_dev::AssemblyBackendMode; use roc_gen_dev::AssemblyBackendMode;
use roc_gen_llvm::llvm::build::LlvmBackendMode; use roc_gen_llvm::llvm::build::LlvmBackendMode;
use roc_load::{FunctionKind, LoadingProblem, Threading}; use roc_load::{LoadingProblem, Threading};
use roc_packaging::cache::{self, RocCacheDir}; use roc_packaging::cache::{self, RocCacheDir};
use roc_target::Target; use roc_target::Target;
use std::fs::{self, FileType}; use std::fs::{self, FileType};
@ -120,21 +119,6 @@ fn main() -> io::Result<()> {
Ok(1) Ok(1)
} }
} }
Some((CMD_GEN_STUB_LIB, matches)) => {
let input_path = matches.get_one::<PathBuf>(ROC_FILE).unwrap();
let target = matches
.get_one::<String>(FLAG_TARGET)
.and_then(|s| Target::from_str(s).ok())
.unwrap_or_default();
let function_kind = FunctionKind::from_env();
roc_linker::generate_stub_lib(
input_path,
RocCacheDir::Persistent(cache::roc_cache_packages_dir().as_path()),
target,
function_kind,
);
Ok(0)
}
Some((CMD_PREPROCESS_HOST, matches)) => { Some((CMD_PREPROCESS_HOST, matches)) => {
let preprocess_host_err = let preprocess_host_err =
{ |msg: String| user_error!("\n\n ERROR PRE-PROCESSING HOST: {}\n\n", msg) }; { |msg: String| user_error!("\n\n ERROR PRE-PROCESSING HOST: {}\n\n", msg) };
@ -169,10 +153,14 @@ fn main() -> io::Result<()> {
let verbose_and_time = matches.get_one::<bool>(roc_cli::FLAG_VERBOSE).unwrap(); let verbose_and_time = matches.get_one::<bool>(roc_cli::FLAG_VERBOSE).unwrap();
let preprocessed_path = platform_path.with_file_name(target.prebuilt_surgical_host());
let metadata_path = platform_path.with_file_name(target.metadata_file_name());
roc_linker::preprocess_host( roc_linker::preprocess_host(
target, target,
host_path, host_path,
platform_path, metadata_path.as_path(),
preprocessed_path.as_path(),
dylib_path, dylib_path,
*verbose_and_time, *verbose_and_time,
*verbose_and_time, *verbose_and_time,

View file

@ -1,11 +1,11 @@
app [main] { pf: platform "platform/main.roc" } app [main] { pf: platform "platform/main.roc" }
# see https://github.com/roc-lang/roc/issues/985
main : Task {} [] main : Task {} []
main = closure1 {} main =
# |> Task.after (\_ -> closure2 {}) closure1 {}
# |> Task.after (\_ -> closure3 {}) |> Task.await (\_ -> closure2 {})
# |> Task.after (\_ -> closure4 {}) |> Task.await (\_ -> closure3 {})
|> Task.await (\_ -> closure4 {})
# --- # ---
closure1 : {} -> Task {} [] closure1 : {} -> Task {} []
closure1 = \_ -> closure1 = \_ ->
@ -17,32 +17,32 @@ toUnitBorrowed = \x -> Str.countUtf8Bytes x
foo = \f, x -> f x foo = \f, x -> f x
# --- # ---
# closure2 : {} -> Task.Task {} [] closure2 : {} -> Task {} []
# closure2 = \_ -> closure2 = \_ ->
# x : Str x : Str
# x = "a long string such that it's malloced" x = "a long string such that it's malloced"
#
# Task.succeed {} Task.ok {}
# |> Task.map (\_ -> x) |> Task.map (\_ -> x)
# |> Task.map toUnit |> Task.map toUnit
#
# toUnit = \_ -> {} toUnit = \_ -> {}
#
# # --- # # ---
# closure3 : {} -> Task.Task {} [] closure3 : {} -> Task {} []
# closure3 = \_ -> closure3 = \_ ->
# x : Str x : Str
# x = "a long string such that it's malloced" x = "a long string such that it's malloced"
#
# Task.succeed {} Task.ok {}
# |> Task.after (\_ -> Task.succeed x |> Task.map (\_ -> {})) |> Task.await (\_ -> Task.ok x |> Task.map (\_ -> {}))
#
# # --- # # ---
# closure4 : {} -> Task.Task {} [] closure4 : {} -> Task {} []
# closure4 = \_ -> closure4 = \_ ->
# x : Str x : Str
# x = "a long string such that it's malloced" x = "a long string such that it's malloced"
#
# Task.succeed {} Task.ok {}
# |> Task.after (\_ -> Task.succeed x) |> Task.await (\_ -> Task.ok x)
# |> Task.map (\_ -> {}) |> Task.map (\_ -> {})

View file

@ -0,0 +1,3 @@
app [main] { pf: platform "main.roc" }
main = Task.ok {}

View file

@ -112,8 +112,6 @@ comptime {
const Unit = extern struct {}; const Unit = extern struct {};
pub fn main() !u8 { pub fn main() !u8 {
const stderr = std.io.getStdErr().writer();
// The size might be zero; if so, make it at least 8 so that we don't have a nullptr // The size might be zero; if so, make it at least 8 so that we don't have a nullptr
const size = @max(@as(usize, @intCast(roc__mainForHost_1_exposed_size())), 8); const size = @max(@as(usize, @intCast(roc__mainForHost_1_exposed_size())), 8);
const raw_output = roc_alloc(@as(usize, @intCast(size)), @alignOf(u64)).?; const raw_output = roc_alloc(@as(usize, @intCast(size)), @alignOf(u64)).?;
@ -123,26 +121,15 @@ pub fn main() !u8 {
roc_dealloc(raw_output, @alignOf(u64)); roc_dealloc(raw_output, @alignOf(u64));
} }
var timer = std.time.Timer.start() catch unreachable;
roc__mainForHost_1_exposed_generic(output); roc__mainForHost_1_exposed_generic(output);
const closure_data_pointer = @as([*]u8, @ptrCast(output)); const closure_data_pointer = @as([*]u8, @ptrCast(output));
call_the_closure(closure_data_pointer); call_the_closure(closure_data_pointer);
const nanos = timer.read();
const seconds = (@as(f64, @floatFromInt(nanos)) / 1_000_000_000.0);
stderr.print("runtime: {d:.3}ms\n", .{seconds * 1000}) catch unreachable;
return 0; return 0;
} }
fn to_seconds(tms: std.os.timespec) f64 {
return @as(f64, @floatFromInt(tms.tv_sec)) + (@as(f64, @floatFromInt(tms.tv_nsec)) / 1_000_000_000.0);
}
fn call_the_closure(closure_data_pointer: [*]u8) void { fn call_the_closure(closure_data_pointer: [*]u8) void {
const allocator = std.heap.page_allocator; const allocator = std.heap.page_allocator;

View file

@ -1,255 +0,0 @@
app [main] { pf: platform "platform/main.roc" }
import pf.PlatformTasks
Color : [Red, Black]
Tree a b : [Leaf, Node Color (Tree a b) a b (Tree a b)]
Map : Tree I64 Bool
ConsList a : [Nil, Cons a (ConsList a)]
main : Task {} []
main =
{ value, isError } = PlatformTasks.getInt!
inputResult =
if isError then
Err GetIntError
else
Ok value
when inputResult is
Ok n ->
m = makeMap n # koka original n = 4_200_000
val = fold (\_, v, r -> if v then r + 1 else r) m 0
val
|> Num.toStr
|> PlatformTasks.putLine
Err GetIntError ->
PlatformTasks.putLine "Error: Failed to get Integer from stdin."
boom : Str -> a
boom = \_ -> boom ""
makeMap : I64 -> Map
makeMap = \n ->
makeMapHelp n n Leaf
makeMapHelp : I64, I64, Map -> Map
makeMapHelp = \total, n, m ->
when n is
0 -> m
_ ->
n1 = n - 1
powerOf10 =
n |> Num.isMultipleOf 10
t1 = insert m n powerOf10
isFrequency =
n |> Num.isMultipleOf 4
key = n1 + ((total - n1) // 5)
t2 = if isFrequency then delete t1 key else t1
makeMapHelp total n1 t2
fold : (a, b, omega -> omega), Tree a b, omega -> omega
fold = \f, tree, b ->
when tree is
Leaf -> b
Node _ l k v r -> fold f r (f k v (fold f l b))
depth : Tree * * -> I64
depth = \tree ->
when tree is
Leaf -> 1
Node _ l _ _ r -> 1 + depth l + depth r
insert : Map, I64, Bool -> Map
insert = \t, k, v -> if isRed t then setBlack (ins t k v) else ins t k v
setBlack : Tree a b -> Tree a b
setBlack = \tree ->
when tree is
Node _ l k v r -> Node Black l k v r
_ -> tree
isRed : Tree a b -> Bool
isRed = \tree ->
when tree is
Node Red _ _ _ _ -> Bool.true
_ -> Bool.false
ins : Tree I64 Bool, I64, Bool -> Tree I64 Bool
ins = \tree, kx, vx ->
when tree is
Leaf ->
Node Red Leaf kx vx Leaf
Node Red a ky vy b ->
when Num.compare kx ky is
LT -> Node Red (ins a kx vx) ky vy b
GT -> Node Red a ky vy (ins b kx vx)
EQ -> Node Red a ky vy (ins b kx vx)
Node Black a ky vy b ->
when Num.compare kx ky is
LT ->
when isRed a is
Bool.true -> balanceLeft (ins a kx vx) ky vy b
Bool.false -> Node Black (ins a kx vx) ky vy b
GT ->
when isRed b is
Bool.true -> balanceRight a ky vy (ins b kx vx)
Bool.false -> Node Black a ky vy (ins b kx vx)
EQ ->
Node Black a kx vx b
balanceLeft : Tree a b, a, b, Tree a b -> Tree a b
balanceLeft = \l, k, v, r ->
when l is
Leaf ->
Leaf
Node _ (Node Red lx kx vx rx) ky vy ry ->
Node Red (Node Black lx kx vx rx) ky vy (Node Black ry k v r)
Node _ ly ky vy (Node Red lx kx vx rx) ->
Node Red (Node Black ly ky vy lx) kx vx (Node Black rx k v r)
Node _ lx kx vx rx ->
Node Black (Node Red lx kx vx rx) k v r
balanceRight : Tree a b, a, b, Tree a b -> Tree a b
balanceRight = \l, k, v, r ->
when r is
Leaf ->
Leaf
Node _ (Node Red lx kx vx rx) ky vy ry ->
Node Red (Node Black l k v lx) kx vx (Node Black rx ky vy ry)
Node _ lx kx vx (Node Red ly ky vy ry) ->
Node Red (Node Black l k v lx) kx vx (Node Black ly ky vy ry)
Node _ lx kx vx rx ->
Node Black l k v (Node Red lx kx vx rx)
isBlack : Color -> Bool
isBlack = \c ->
when c is
Black -> Bool.true
Red -> Bool.false
Del a b : [Del (Tree a b) Bool]
setRed : Map -> Map
setRed = \t ->
when t is
Node _ l k v r ->
Node Red l k v r
_ ->
t
makeBlack : Map -> Del I64 Bool
makeBlack = \t ->
when t is
Node Red l k v r ->
Del (Node Black l k v r) Bool.false
_ ->
Del t Bool.true
rebalanceLeft = \c, l, k, v, r ->
when l is
Node Black _ _ _ _ ->
Del (balanceLeft (setRed l) k v r) (isBlack c)
Node Red lx kx vx rx ->
Del (Node Black lx kx vx (balanceLeft (setRed rx) k v r)) Bool.false
_ ->
boom "unreachable"
rebalanceRight = \c, l, k, v, r ->
when r is
Node Black _ _ _ _ ->
Del (balanceRight l k v (setRed r)) (isBlack c)
Node Red lx kx vx rx ->
Del (Node Black (balanceRight l k v (setRed lx)) kx vx rx) Bool.false
_ ->
boom "unreachable"
delMin = \t ->
when t is
Node Black Leaf k v r ->
when r is
Leaf ->
Delmin (Del Leaf Bool.true) k v
_ ->
Delmin (Del (setBlack r) Bool.false) k v
Node Red Leaf k v r ->
Delmin (Del r Bool.false) k v
Node c l k v r ->
when delMin l is
Delmin (Del lx Bool.true) kx vx ->
Delmin (rebalanceRight c lx k v r) kx vx
Delmin (Del lx Bool.false) kx vx ->
Delmin (Del (Node c lx k v r) Bool.false) kx vx
Leaf ->
Delmin (Del t Bool.false) 0 Bool.false
delete : Tree I64 Bool, I64 -> Tree I64 Bool
delete = \t, k ->
when del t k is
Del tx _ ->
setBlack tx
del : Tree I64 Bool, I64 -> Del I64 Bool
del = \t, k ->
when t is
Leaf ->
Del Leaf Bool.false
Node cx lx kx vx rx ->
if (k < kx) then
when del lx k is
Del ly Bool.true ->
rebalanceRight cx ly kx vx rx
Del ly Bool.false ->
Del (Node cx ly kx vx rx) Bool.false
else if (k > kx) then
when del rx k is
Del ry Bool.true ->
rebalanceLeft cx lx kx vx ry
Del ry Bool.false ->
Del (Node cx lx kx vx ry) Bool.false
else
when rx is
Leaf ->
if isBlack cx then makeBlack lx else Del lx Bool.false
Node _ _ _ _ _ ->
when delMin rx is
Delmin (Del ry Bool.true) ky vy ->
rebalanceLeft cx lx ky vy ry
Delmin (Del ry Bool.false) ky vy ->
Del (Node cx lx ky vy ry) Bool.false

View file

@ -3,7 +3,6 @@ app [main] { pf: platform "platform/main.roc" }
import pf.PlatformTasks import pf.PlatformTasks
import AStar import AStar
#main : Task {} *
main = main =
PlatformTasks.putLine! (showBool test1) PlatformTasks.putLine! (showBool test1)

View file

@ -1,12 +0,0 @@
app [main] {
pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.16.0/O00IPk-Krg_diNS2dVWlI0ZQP794Vctxzv0ha96mK0E.tar.br",
}
import pf.Stdout
import pf.Arg
main =
args = Arg.list! {}
when List.first args is
Ok argv0 -> Stdout.line argv0
Err ListWasEmpty -> Stdout.line "Failed: argv was empty"

View file

@ -1,18 +0,0 @@
app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.16.0/O00IPk-Krg_diNS2dVWlI0ZQP794Vctxzv0ha96mK0E.tar.br" }
import pf.Stdin
import pf.Stdout
main =
Stdout.line! "\nLet's count down from 3 together - all you have to do is press <ENTER>."
_ = Stdin.line!
Task.loop 3 tick
tick = \n ->
if n == 0 then
Stdout.line! "🎉 SURPRISE! Happy Birthday! 🎂"
Task.ok (Done {})
else
Stdout.line! (n |> Num.toStr |> \s -> "$(s)...")
_ = Stdin.line!
Task.ok (Step (n - 1))

View file

@ -1,35 +0,0 @@
app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.16.0/O00IPk-Krg_diNS2dVWlI0ZQP794Vctxzv0ha96mK0E.tar.br" }
import pf.Stdin
import pf.Stdout
main =
Stdout.line! "🗣 Shout into this cave and hear the echo! 👂👂👂"
Task.loop {} tick
tick : {} -> Task [Step {}, Done {}] _
tick = \{} ->
when Stdin.line |> Task.result! is
Ok str -> Stdout.line (echo str) |> Task.map Step
Err (StdinErr EndOfFile) -> Stdout.line (echo "Received end of input (EOF).") |> Task.map Done
Err (StdinErr err) -> Stdout.line (echo "Unable to read input $(Inspect.toStr err)") |> Task.map Done
echo : Str -> Str
echo = \shout ->
silence = \length ->
spaceInUtf8 = 32
List.repeat spaceInUtf8 length
shout
|> Str.toUtf8
|> List.mapWithIndex
(\_, i ->
length = (List.len (Str.toUtf8 shout) - i)
phrase = (List.splitAt (Str.toUtf8 shout) length).before
List.concat (silence (if i == 0 then 2 * length else length)) phrase)
|> List.join
|> Str.fromUtf8
|> Result.withDefault ""

View file

@ -1,30 +0,0 @@
app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.16.0/O00IPk-Krg_diNS2dVWlI0ZQP794Vctxzv0ha96mK0E.tar.br" }
import pf.Stdout
import pf.Stderr
import pf.Env
main =
task =
Env.decode "EDITOR"
|> Task.await (\editor -> Stdout.line "Your favorite editor is $(editor)!")
|> Task.await (\{} -> Env.decode "SHLVL")
|> Task.await
(\lvl ->
when lvl is
1u8 -> Stdout.line "You're running this in a root shell!"
n ->
lvlStr = Num.toStr n
Stdout.line "Your current shell level is $(lvlStr)!")
|> Task.await \{} -> Env.decode "LETTERS"
Task.attempt task \result ->
when result is
Ok letters ->
joinedLetters = Str.joinWith letters " "
Stdout.line "Your favorite letters are: $(joinedLetters)"
Err _ ->
Stderr.line "I couldn't find your favorite letters in the environment variables!"

View file

@ -1,36 +0,0 @@
app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.16.0/O00IPk-Krg_diNS2dVWlI0ZQP794Vctxzv0ha96mK0E.tar.br" }
import pf.Stdout
import pf.File
import pf.Path
import pf.Env
main : Task {} [Exit I32 Str]_
main =
pathStr = "out.txt"
task =
cwdPath = Env.cwd!
cwdStr = Path.display cwdPath
Stdout.line! "Current working directory: $(cwdStr)"
dirEntries = Path.listDir! cwdPath
contentsStr = Str.joinWith (List.map dirEntries Path.display) "\n "
Stdout.line! "Directory contents:\n $(contentsStr)\n"
Stdout.line! "Writing a string to out.txt"
File.writeUtf8! pathStr "a string!"
contents = File.readUtf8! pathStr
Stdout.line! "I read the file back. Its contents: \"$(contents)\""
when Task.result! task is
Ok {} -> Stdout.line! "Successfully wrote a string to out.txt"
Err err ->
msg =
when err is
FileWriteErr _ PermissionDenied -> "PermissionDenied"
FileWriteErr _ Unsupported -> "Unsupported"
FileWriteErr _ (Unrecognized _ other) -> other
FileReadErr _ _ -> "Error reading file"
_ -> "Uh oh, there was an error!"
Task.err (Exit 1 msg)

View file

@ -1,35 +0,0 @@
# A Simple Markdown Example
This file contains `form.roc` embedded as a block in Markdown. It lets us test that `roc check` works with Markdown.
```roc
app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.16.0/O00IPk-Krg_diNS2dVWlI0ZQP794Vctxzv0ha96mK0E.tar.br" }
import pf.Stdin
import pf.Stdout
main =
Stdout.line! "What's your first name?"
firstName = Stdin.line!
Stdout.line! "What's your last name?"
lastName = Stdin.line!
Stdout.line "Hi, $(firstName) $(lastName)! 👋"
```
Excitingly, we can have another block of Roc code as well! (In this case it is the same one...)
```roc
app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.16.0/O00IPk-Krg_diNS2dVWlI0ZQP794Vctxzv0ha96mK0E.tar.br" }
import pf.Stdin
import pf.Stdout
main =
Stdout.line! "What's your first name?"
firstName = Stdin.line!
Stdout.line! "What's your last name?"
lastName = Stdin.line!
Stdout.line "Hi, $(firstName) $(lastName)! 👋"
```

View file

@ -1,12 +0,0 @@
app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.16.0/O00IPk-Krg_diNS2dVWlI0ZQP794Vctxzv0ha96mK0E.tar.br" }
import pf.Stdin
import pf.Stdout
main =
Stdout.line! "What's your first name?"
firstName = Stdin.line!
Stdout.line! "What's your last name?"
lastName = Stdin.line!
Stdout.line "Hi, $(firstName) $(lastName)! 👋"

View file

@ -1,23 +0,0 @@
app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.16.0/O00IPk-Krg_diNS2dVWlI0ZQP794Vctxzv0ha96mK0E.tar.br" }
import pf.Http
import pf.Stdout
main =
request = {
method: Get,
headers: [],
url: "http://www.example.com",
mimeType: "",
body: [],
timeout: TimeoutMilliseconds 5000,
}
resp = Http.send! request
output =
when resp |> Http.handleStringResponse is
Err err -> crash (Http.errorToString err)
Ok body -> body
Stdout.line output

View file

@ -1,12 +0,0 @@
app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.16.0/O00IPk-Krg_diNS2dVWlI0ZQP794Vctxzv0ha96mK0E.tar.br" }
import pf.Stdout
import "test-file.txt" as testFile
main =
# Due to the functions we apply on testFile, it will be inferred as a List U8.
testFile
|> List.map Num.toU64
|> List.sum
|> Num.toStr
|> Stdout.line!

View file

@ -1,12 +0,0 @@
app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.16.0/O00IPk-Krg_diNS2dVWlI0ZQP794Vctxzv0ha96mK0E.tar.br" }
import pf.Stdout
import "test-file.txt" as testFile : _ # the _ is optional
main =
# Due to the functions we apply on testFile, it will be inferred as a List U8.
testFile
|> List.map Num.toU64
|> List.sum
|> Num.toStr
|> Stdout.line!

View file

@ -1,7 +0,0 @@
app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.16.0/O00IPk-Krg_diNS2dVWlI0ZQP794Vctxzv0ha96mK0E.tar.br" }
import pf.Stdout
import "ingested-file.roc" as ownCode : Str
main =
Stdout.line! "\nThis roc file can print its own source code. The source is:\n\n$(ownCode)"

View file

@ -1,85 +0,0 @@
app [main] {
pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.16.0/O00IPk-Krg_diNS2dVWlI0ZQP794Vctxzv0ha96mK0E.tar.br",
}
import pf.Stdout
main =
file = strParam { name: "file" }
argParser =
{ cliBuild <-
file,
count: numParam { name: "count" },
doubled: numParam { name: "doubled" }
|> cliMap \d -> d * 2,
}
args = ["parse-args", "file.txt", "5", "7"]
when argParser |> parseArgs args is
Ok data -> Stdout.line "Success: $(Inspect.toStr data)"
Err (FailedToParse message) -> Stdout.line "Failed: $(message)"
ArgParseErr : [NoMoreArgs, InvalidParam ParamConfig]
ParamConfig : {
name : Str,
type : [Num, Str],
}
ArgParser out : {
params : List ParamConfig,
parser : List Str -> Result (out, List Str) ArgParseErr,
}
strParam : { name : Str } -> ArgParser Str
strParam = \{ name } ->
parser = \args ->
when args is
[] -> Err NoMoreArgs
[first, .. as rest] -> Ok (first, rest)
{ params: [{ name, type: Str }], parser }
numParam : { name : Str } -> ArgParser U64
numParam = \{ name } ->
param = { name, type: Num }
parser = \args ->
when args is
[] -> Err NoMoreArgs
[first, .. as rest] ->
when Str.toU64 first is
Ok num -> Ok (num, rest)
Err InvalidNumStr -> Err (InvalidParam param)
{ params: [param], parser }
cliMap : ArgParser a, (a -> b) -> ArgParser b
cliMap = \{ params, parser }, mapper ->
mappedParser = \args ->
(data, afterData) = parser? args
Ok (mapper data, afterData)
{
params,
parser: mappedParser,
}
cliBuild : ArgParser a, ArgParser b, (a, b -> c) -> ArgParser c
cliBuild = \firstWeaver, secondWeaver, combine ->
allParams = List.concat firstWeaver.params secondWeaver.params
combinedParser = \args ->
(firstValue, afterFirst) = firstWeaver.parser? args
(secondValue, afterSecond) = secondWeaver.parser? afterFirst
Ok (combine firstValue secondValue, afterSecond)
{ params: allParams, parser: combinedParser }
parseArgs : ArgParser a, List Str -> Result a [FailedToParse Str]
parseArgs = \{ params: _, parser }, args ->
when parser (List.dropFirst args 1) is
Ok (data, []) -> Ok data
Ok (_data, extraArgs) -> Err (FailedToParse "Got $(List.len extraArgs |> Inspect.toStr) extra args")
Err NoMoreArgs -> Err (FailedToParse "I needed more args")
Err (InvalidParam param) -> Err (FailedToParse "Parameter '$(param.name)' needed a $(Inspect.toStr param.type)")

View file

@ -1,51 +0,0 @@
app [main] {
cli: platform "https://github.com/roc-lang/basic-cli/releases/download/0.16.0/O00IPk-Krg_diNS2dVWlI0ZQP794Vctxzv0ha96mK0E.tar.br",
parser: "https://github.com/lukewilliamboswell/roc-parser/releases/download/0.5.2/9VrPjwfQQ1QeSL3CfmWr2Pr9DESdDIXy97pwpuq84Ck.tar.br",
}
import cli.Stdout
import cli.Stderr
import parser.Core exposing [Parser, buildPrimitiveParser, many]
import parser.String exposing [parseStr]
main =
lettersInput = "AAAiBByAABBwBtCCCiAyArBBx"
ifLetterA = \l -> l == A
when parseStr (many letterParser) lettersInput is
Ok letters ->
letters
|> List.keepIf ifLetterA
|> List.map \_ -> 1
|> List.sum
|> Num.toStr
|> \countLetterA -> Stdout.line "I counted $(countLetterA) letter A's!"
Err _ -> Stderr.line "Ooops, something went wrong parsing letters"
Letter : [A, B, C, Other]
letterParser : Parser (List U8) Letter
letterParser =
buildPrimitiveParser \input ->
valResult =
when input is
[] -> Err (ParsingFailure "Nothing to parse")
['A', ..] -> Ok A
['B', ..] -> Ok B
['C', ..] -> Ok C
_ -> Ok Other
valResult
|> Result.map \val -> { val, input: List.dropFirst input 1 }
expect
input = "B"
parser = letterParser
result = parseStr parser input
result == Ok B
expect
input = "BCXA"
parser = many letterParser
result = parseStr parser input
result == Ok [B, C, Other, A]

View file

@ -1,63 +0,0 @@
app [main] {
pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.16.0/O00IPk-Krg_diNS2dVWlI0ZQP794Vctxzv0ha96mK0E.tar.br",
parser: "https://github.com/lukewilliamboswell/roc-parser/releases/download/0.5.2/9VrPjwfQQ1QeSL3CfmWr2Pr9DESdDIXy97pwpuq84Ck.tar.br",
}
import pf.Stdout
import pf.Stderr
import parser.Core exposing [map, keep]
import parser.String exposing [strFromUtf8]
import parser.CSV
input : Str
input = "Airplane!,1980,\"Robert Hays,Julie Hagerty\"\r\nCaddyshack,1980,\"Chevy Chase,Rodney Dangerfield,Ted Knight,Michael O'Keefe,Bill Murray\""
main =
when CSV.parseStr movieInfoParser input is
Ok movies ->
moviesString =
movies
|> List.map movieInfoExplanation
|> Str.joinWith ("\n")
nMovies = List.len movies |> Num.toStr
Stdout.line "$(nMovies) movies were found:\n\n$(moviesString)\n\nParse success!\n"
Err problem ->
when problem is
ParsingFailure failure ->
Stderr.line "Parsing failure: $(failure)\n"
ParsingIncomplete leftover ->
leftoverStr = leftover |> List.map strFromUtf8 |> List.map (\val -> "\"$(val)\"") |> Str.joinWith ", "
Stderr.line "Parsing incomplete. Following leftover fields while parsing a record: $(leftoverStr)\n"
SyntaxError error ->
Stderr.line "Parsing failure. Syntax error in the CSV: $(error)"
MovieInfo := { title : Str, releaseYear : U64, actors : List Str }
movieInfoParser =
CSV.record (\title -> \releaseYear -> \actors -> @MovieInfo { title, releaseYear, actors })
|> keep (CSV.field CSV.string)
|> keep (CSV.field CSV.u64)
|> keep (CSV.field actorsParser)
actorsParser =
CSV.string
|> map \val -> Str.split val ","
movieInfoExplanation = \@MovieInfo { title, releaseYear, actors } ->
enumeratedActors = enumerate actors
releaseYearStr = Num.toStr releaseYear
"The movie '$(title)' was released in $(releaseYearStr) and stars $(enumeratedActors)"
enumerate : List Str -> Str
enumerate = \elements ->
{ before: inits, others: last } = List.splitAt elements (List.len elements - 1)
last
|> List.prepend (inits |> Str.joinWith ", ")
|> Str.joinWith " and "

View file

@ -1 +0,0 @@
Used by ingested-file-bytes.roc and ingested-file-bytes-no-ann.roc

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,9 +0,0 @@
interface Transitive
exposes [
add,
]
imports []
add = \num1, num2 -> (num1 + num2)
expect add 1 2 == 3

View file

@ -1,5 +0,0 @@
package "transitive-tests"
exposes [
Direct,
]
packages {}

View file

@ -1,4 +0,0 @@
interface Dep1 exposes [str1] imports [Dep2]
str1 : Str
str1 = Dep2.str2

View file

@ -1,4 +0,0 @@
interface Dep2 exposes [str2] imports []
str2 : Str
str2 = "I am Dep2.str2"

View file

@ -1,7 +0,0 @@
app "multi-dep-str"
packages { pf: "platform/main.roc" }
imports [Dep1]
provides [main] to pf
main : Str
main = Dep1.str1

View file

@ -1,119 +0,0 @@
const std = @import("std");
const builtin = @import("builtin");
const str = @import("glue").str;
const RocStr = str.RocStr;
const testing = std.testing;
const expectEqual = testing.expectEqual;
const expect = testing.expect;
const mem = std.mem;
const Allocator = mem.Allocator;
extern fn roc__mainForHost_1_exposed_generic(*RocStr) void;
const Align = 2 * @alignOf(usize);
extern fn malloc(size: usize) callconv(.C) ?*align(Align) anyopaque;
extern fn realloc(c_ptr: [*]align(Align) u8, size: usize) callconv(.C) ?*anyopaque;
extern fn free(c_ptr: [*]align(Align) u8) callconv(.C) void;
extern fn memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void;
extern fn memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void;
export fn roc_alloc(size: usize, alignment: u32) callconv(.C) ?*anyopaque {
_ = alignment;
return malloc(size);
}
export fn roc_realloc(c_ptr: *anyopaque, new_size: usize, old_size: usize, alignment: u32) callconv(.C) ?*anyopaque {
_ = old_size;
_ = alignment;
return realloc(@as([*]align(Align) u8, @alignCast(@ptrCast(c_ptr))), new_size);
}
export fn roc_dealloc(c_ptr: *anyopaque, alignment: u32) callconv(.C) void {
_ = alignment;
free(@as([*]align(Align) u8, @alignCast(@ptrCast(c_ptr))));
}
export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void {
return memset(dst, value, size);
}
export fn roc_panic(msg: *RocStr, tag_id: u32) callconv(.C) void {
const stderr = std.io.getStdErr().writer();
switch (tag_id) {
0 => {
stderr.print("Roc standard library crashed with message\n\n {s}\n\nShutting down\n", .{msg.asSlice()}) catch unreachable;
},
1 => {
stderr.print("Application crashed with message\n\n {s}\n\nShutting down\n", .{msg.asSlice()}) catch unreachable;
},
else => unreachable,
}
std.process.exit(1);
}
export fn roc_dbg(loc: *RocStr, msg: *RocStr, src: *RocStr) callconv(.C) void {
const stderr = std.io.getStdErr().writer();
stderr.print("[{s}] {s} = {s}\n", .{ loc.asSlice(), src.asSlice(), msg.asSlice() }) catch unreachable;
}
extern fn kill(pid: c_int, sig: c_int) c_int;
extern fn shm_open(name: *const i8, oflag: c_int, mode: c_uint) c_int;
extern fn mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) *anyopaque;
extern fn getppid() c_int;
fn roc_getppid() callconv(.C) c_int {
return getppid();
}
fn roc_getppid_windows_stub() callconv(.C) c_int {
return 0;
}
fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int {
return shm_open(name, oflag, mode);
}
fn roc_mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) callconv(.C) *anyopaque {
return mmap(addr, length, prot, flags, fd, offset);
}
comptime {
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
@export(roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong });
@export(roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong });
@export(roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong });
}
if (builtin.os.tag == .windows) {
@export(roc_getppid_windows_stub, .{ .name = "roc_getppid", .linkage = .Strong });
}
}
const Unit = extern struct {};
pub export fn main() i32 {
const stdout = std.io.getStdOut().writer();
const stderr = std.io.getStdErr().writer();
var timer = std.time.Timer.start() catch unreachable;
// actually call roc to populate the callresult
var callresult = RocStr.empty();
roc__mainForHost_1_exposed_generic(&callresult);
const nanos = timer.read();
const seconds = (@as(f64, @floatFromInt(nanos)) / 1_000_000_000.0);
// stdout the result
stdout.print("{s}\n", .{callresult.asSlice()}) catch unreachable;
callresult.decref();
stderr.print("runtime: {d:.3}ms\n", .{seconds * 1000}) catch unreachable;
return 0;
}
fn to_seconds(tms: std.os.timespec) f64 {
return @as(f64, @floatFromInt(tms.tv_sec)) + (@as(f64, @floatFromInt(tms.tv_nsec)) / 1_000_000_000.0);
}

View file

@ -1,9 +0,0 @@
platform "multi-module"
requires {}{ main : Str }
exposes []
packages {}
imports []
provides [mainForHost]
mainForHost : Str
mainForHost = main

View file

@ -1,7 +0,0 @@
app "multi-dep-thunk"
packages { pf: "platform/main.roc" }
imports [Dep1]
provides [main] to pf
main : Str
main = Dep1.value1 {}

View file

@ -1,119 +0,0 @@
const std = @import("std");
const builtin = @import("builtin");
const str = @import("glue").str;
const RocStr = str.RocStr;
const testing = std.testing;
const expectEqual = testing.expectEqual;
const expect = testing.expect;
const mem = std.mem;
const Allocator = mem.Allocator;
extern fn roc__mainForHost_1_exposed_generic(*RocStr) void;
const Align = 2 * @alignOf(usize);
extern fn malloc(size: usize) callconv(.C) ?*anyopaque;
extern fn realloc(c_ptr: [*]align(@alignOf(u128)) u8, size: usize) callconv(.C) ?*anyopaque;
extern fn free(c_ptr: [*]align(@alignOf(u128)) u8) callconv(.C) void;
extern fn memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void;
extern fn memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void;
export fn roc_alloc(size: usize, alignment: u32) callconv(.C) ?*anyopaque {
_ = alignment;
return malloc(size);
}
export fn roc_realloc(c_ptr: *anyopaque, new_size: usize, old_size: usize, alignment: u32) callconv(.C) ?*anyopaque {
_ = old_size;
_ = alignment;
return realloc(@as([*]align(Align) u8, @alignCast(@ptrCast(c_ptr))), new_size);
}
export fn roc_dealloc(c_ptr: *anyopaque, alignment: u32) callconv(.C) void {
_ = alignment;
free(@as([*]align(Align) u8, @alignCast(@ptrCast(c_ptr))));
}
export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void {
return memset(dst, value, size);
}
export fn roc_panic(msg: *RocStr, tag_id: u32) callconv(.C) void {
const stderr = std.io.getStdErr().writer();
switch (tag_id) {
0 => {
stderr.print("Roc standard library crashed with message\n\n {s}\n\nShutting down\n", .{msg.asSlice()}) catch unreachable;
},
1 => {
stderr.print("Application crashed with message\n\n {s}\n\nShutting down\n", .{msg.asSlice()}) catch unreachable;
},
else => unreachable,
}
std.process.exit(1);
}
export fn roc_dbg(loc: *RocStr, msg: *RocStr, src: *RocStr) callconv(.C) void {
const stderr = std.io.getStdErr().writer();
stderr.print("[{s}] {s} = {s}\n", .{ loc.asSlice(), src.asSlice(), msg.asSlice() }) catch unreachable;
}
extern fn kill(pid: c_int, sig: c_int) c_int;
extern fn shm_open(name: *const i8, oflag: c_int, mode: c_uint) c_int;
extern fn mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) *anyopaque;
extern fn getppid() c_int;
fn roc_getppid() callconv(.C) c_int {
return getppid();
}
fn roc_getppid_windows_stub() callconv(.C) c_int {
return 0;
}
fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int {
return shm_open(name, oflag, mode);
}
fn roc_mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) callconv(.C) *anyopaque {
return mmap(addr, length, prot, flags, fd, offset);
}
comptime {
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
@export(roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong });
@export(roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong });
@export(roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong });
}
if (builtin.os.tag == .windows) {
@export(roc_getppid_windows_stub, .{ .name = "roc_getppid", .linkage = .Strong });
}
}
const Unit = extern struct {};
pub export fn main() i32 {
const stdout = std.io.getStdOut().writer();
const stderr = std.io.getStdErr().writer();
var timer = std.time.Timer.start() catch unreachable;
// actually call roc to populate the callresult
var callresult = RocStr.empty();
roc__mainForHost_1_exposed_generic(&callresult);
const nanos = timer.read();
const seconds = (@as(f64, @floatFromInt(nanos)) / 1_000_000_000.0);
// stdout the result
stdout.print("{s}\n", .{callresult.asSlice()}) catch unreachable;
callresult.decref();
stderr.print("runtime: {d:.3}ms\n", .{seconds * 1000}) catch unreachable;
return 0;
}
fn to_seconds(tms: std.os.timespec) f64 {
return @as(f64, @floatFromInt(tms.tv_sec)) + (@as(f64, @floatFromInt(tms.tv_nsec)) / 1_000_000_000.0);
}

View file

@ -1,9 +0,0 @@
platform "multi-dep-thunk"
requires {}{ main : Str }
exposes []
packages {}
imports []
provides [mainForHost]
mainForHost : Str
mainForHost = main

View file

@ -1,6 +0,0 @@
app "packages-test"
packages { pf: "platform/main.roc", json: "json/main.roc", csv: "csv/main.roc" }
imports [json.JsonParser, csv.Csv]
provides [main] to pf
main = "Hello, World! $(JsonParser.example) $(Csv.example)"

View file

@ -1,6 +0,0 @@
interface Csv
exposes [example]
imports []
example : Str
example = "This text came from a CSV package!"

View file

@ -1,6 +0,0 @@
interface JsonParser
exposes [example]
imports []
example : Str
example = "This text came from a package!"

View file

@ -1,9 +0,0 @@
platform "multi-module"
requires {}{ main : Str }
exposes []
packages {}
imports []
provides [mainForHost]
mainForHost : Str
mainForHost = main

View file

@ -1,10 +0,0 @@
app [main] {
pf: platform "../packages/platform/main.roc",
one: "one/main.roc",
two: "two/main.roc",
}
import one.One
import two.Two
main = "$(One.example) | $(Two.example)"

View file

@ -1,8 +0,0 @@
app [main] {
pf: platform "../packages/platform/main.roc",
one: "one/main.roc",
}
import one.One
main = One.example

View file

@ -1,8 +0,0 @@
app [main] {
pf: platform "../packages/platform/main.roc",
zero: "zero/main.roc",
}
import zero.Zero
main = Zero.example

View file

@ -1,3 +0,0 @@
package [Zero] {
one: "../one/main.roc"
}

View file

@ -1,3 +0,0 @@
interface ExposedNotDefined
exposes [bar]
imports []

View file

@ -1,7 +0,0 @@
interface UnusedImport
exposes [plainText, emText]
imports [Symbol.{ Ident }]
plainText = \str -> PlainText str
emText = \str -> EmText str

View file

@ -1,7 +0,0 @@
interface UnusedImportButWithALongFileNameForTesting
exposes [plainText, emText]
imports [Symbol.{ Ident }]
plainText = \str -> PlainText str
emText = \str -> EmText str

View file

@ -0,0 +1,17 @@
# A Simple Markdown Example
This file contains `form.roc` embedded as a block in Markdown. It lets us test that `roc check` works with Markdown.
```roc
module [foo]
foo = "Foo"
```
Excitingly, we can have another block of Roc code as well! (In this case it is the same one...)
```roc
module [bar]
bar = "Bar"
```

View file

@ -1,8 +0,0 @@
module {
sendHttpReq,
getEnvVar
} -> [hi]
hi : Str
hi =
"hi"

View file

@ -1,8 +0,0 @@
app [main] {
pf: platform "../fixtures/multi-dep-str/platform/main.roc",
}
import BadAnn { appId: "one" }
main =
""

View file

@ -1,6 +0,0 @@
app [main] {
pf: platform "./platform/main.roc"
}
main =
"from app"

View file

@ -1,129 +0,0 @@
const std = @import("std");
const builtin = @import("builtin");
const str = @import("glue").str;
const RocStr = str.RocStr;
const testing = std.testing;
const expectEqual = testing.expectEqual;
const expect = testing.expect;
const Align = 2 * @alignOf(usize);
extern fn malloc(size: usize) callconv(.C) ?*align(Align) anyopaque;
extern fn realloc(c_ptr: [*]align(Align) u8, size: usize) callconv(.C) ?*anyopaque;
extern fn free(c_ptr: [*]align(Align) u8) callconv(.C) void;
extern fn memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void;
extern fn memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void;
const DEBUG: bool = false;
export fn roc_alloc(size: usize, alignment: u32) callconv(.C) ?*anyopaque {
if (DEBUG) {
var ptr = malloc(size);
const stdout = std.io.getStdOut().writer();
stdout.print("alloc: {d} (alignment {d}, size {d})\n", .{ ptr, alignment, size }) catch unreachable;
return ptr;
} else {
return malloc(size);
}
}
export fn roc_realloc(c_ptr: *anyopaque, new_size: usize, old_size: usize, alignment: u32) callconv(.C) ?*anyopaque {
if (DEBUG) {
const stdout = std.io.getStdOut().writer();
stdout.print("realloc: {d} (alignment {d}, old_size {d})\n", .{ c_ptr, alignment, old_size }) catch unreachable;
}
return realloc(@as([*]align(Align) u8, @alignCast(@ptrCast(c_ptr))), new_size);
}
export fn roc_dealloc(c_ptr: *anyopaque, alignment: u32) callconv(.C) void {
if (DEBUG) {
const stdout = std.io.getStdOut().writer();
stdout.print("dealloc: {d} (alignment {d})\n", .{ c_ptr, alignment }) catch unreachable;
}
free(@as([*]align(Align) u8, @alignCast(@ptrCast(c_ptr))));
}
export fn roc_panic(msg: *RocStr, tag_id: u32) callconv(.C) void {
_ = tag_id;
const stderr = std.io.getStdErr().writer();
stderr.print("Application crashed with message\n\n {s}\n\nShutting down\n", .{msg.asSlice()}) catch unreachable;
std.process.exit(1);
}
export fn roc_dbg(loc: *RocStr, msg: *RocStr, src: *RocStr) callconv(.C) void {
// This platform uses stdout for testing purposes instead of the normal stderr.
const stdout = std.io.getStdOut().writer();
stdout.print("[{s}] {s} = {s}\n", .{ loc.asSlice(), src.asSlice(), msg.asSlice() }) catch unreachable;
}
export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void {
return memset(dst, value, size);
}
extern fn kill(pid: c_int, sig: c_int) c_int;
extern fn shm_open(name: *const i8, oflag: c_int, mode: c_uint) c_int;
extern fn mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) *anyopaque;
extern fn getppid() c_int;
fn roc_getppid() callconv(.C) c_int {
return getppid();
}
fn roc_getppid_windows_stub() callconv(.C) c_int {
return 0;
}
fn roc_send_signal(pid: c_int, sig: c_int) callconv(.C) c_int {
return kill(pid, sig);
}
fn roc_shm_open(name: *const i8, oflag: c_int, mode: c_uint) callconv(.C) c_int {
return shm_open(name, oflag, mode);
}
fn roc_mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) callconv(.C) *anyopaque {
return mmap(addr, length, prot, flags, fd, offset);
}
comptime {
if (builtin.os.tag == .macos or builtin.os.tag == .linux) {
@export(roc_getppid, .{ .name = "roc_getppid", .linkage = .Strong });
@export(roc_mmap, .{ .name = "roc_mmap", .linkage = .Strong });
@export(roc_send_signal, .{ .name = "roc_send_signal", .linkage = .Strong });
@export(roc_shm_open, .{ .name = "roc_shm_open", .linkage = .Strong });
}
if (builtin.os.tag == .windows) {
@export(roc_getppid_windows_stub, .{ .name = "roc_getppid", .linkage = .Strong });
}
}
const mem = std.mem;
const Allocator = mem.Allocator;
extern fn roc__mainForHost_1_exposed_generic(*RocStr) void;
const Unit = extern struct {};
pub fn main() u8 {
const stdout = std.io.getStdOut().writer();
const stderr = std.io.getStdErr().writer();
var timer = std.time.Timer.start() catch unreachable;
// actually call roc to populate the callresult
var callresult = RocStr.empty();
roc__mainForHost_1_exposed_generic(&callresult);
const nanos = timer.read();
const seconds = (@as(f64, @floatFromInt(nanos)) / 1_000_000_000.0);
// stdout the result
stdout.print("{s}", .{callresult.asSlice()}) catch unreachable;
callresult.decref();
stderr.print("runtime: {d:.3}ms\n", .{seconds * 1000}) catch unreachable;
return 0;
}

View file

@ -0,0 +1,15 @@
---
source: crates/cli/tests/cli_tests.rs
expression: cli_check_out.normalize_stdout_and_stderr()
---
── MISSING DEFINITION in tests/test-projects/known_bad/ExposedNotDefined.roc ───
bar is listed as exposed, but it isn't defined in this module.
You can fix this by adding a definition for bar, or by removing it
from exposes.
────────────────────────────────────────────────────────────────────────────────
1 error and 0 warning found in <ignored for test> ms

View file

@ -0,0 +1,28 @@
---
source: crates/cli/tests/cli_tests.rs
expression: cli_check_out.normalize_stdout_and_stderr()
---
── TYPE MISMATCH in tests/test-projects/known_bad/TypeError.roc ────────────────
Something is off with the body of the main definition:
3│ main : Str -> Task {} []
4│ main = \_ ->
5│ "this is a string, not a Task {} [] function like the platform expects."
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The body is a string of type:
Str
But the type annotation on main says it should be:
Task {} []
Tip: Add type annotations to functions or values to help you figure
this out.
────────────────────────────────────────────────────────────────────────────────
1 error and 0 warning found in <ignored for test> ms

View file

@ -0,0 +1,17 @@
---
source: crates/cli/tests/cli_tests.rs
expression: cli_check_out.normalize_stdout_and_stderr()
---
── UNUSED IMPORT in ...nown_bad/UnusedImportButWithALongFileNameForTesting.roc ─
Symbol is imported but not used.
3│ import Symbol exposing [Ident]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Since Symbol isn't used, you don't need to import it.
────────────────────────────────────────────────────────────────────────────────
0 error and 1 warning found in <ignored for test> ms

View file

@ -0,0 +1,18 @@
---
source: crates/cli/tests/cli_tests.rs
expression: cli_test_out.normalize_stdout_and_stderr()
---
── UNRECOGNIZED PACKAGE in tests/test-projects/module_imports_pkg/Module.roc ───
This module is trying to import from `pkg`:
3│ import pkg.Foo
^^^^^^^
A lowercase name indicates a package shorthand, but I don't know which
packages are available.
When checking a module directly, I look for a `main.roc` app or
package to resolve shorthands from.
You can create it, or specify an existing one with the --main flag.

View file

@ -0,0 +1,21 @@
---
source: crates/cli/tests/cli_tests.rs
expression: cli_test_out.normalize_stdout_and_stderr()
---
── UNRECOGNIZED PACKAGE in ...rojects/module_imports_pkg/ImportsUnknownPkg.roc ─
This module is trying to import from `cli`:
3│ import cli.Foo
^^^^^^^
A lowercase name indicates a package shorthand, but I don't recognize
this one. Did you mean one of these?
pkg
Note: I'm using the following module to resolve package shorthands:
tests/test-projects/module_imports_pkg/app.roc
You can specify a different one with the --main flag.

View file

@ -0,0 +1,5 @@
---
source: crates/cli/tests/cli_tests.rs
expression: out.normalize_stdout_and_stderr()
---
(@Community {friends: [{2}, {2}, {0, 1}], people: [(@Person {age: 27, favoriteColor: Blue, firstName: \"John\", hasBeard: Bool.true, lastName: \"Smith\"}), (@Person {age: 47, favoriteColor: Green, firstName: \"Debby\", hasBeard: Bool.false, lastName: \"Johnson\"}), (@Person {age: 33, favoriteColor: (RGB (255, 255, 0)), firstName: \"Jane\", hasBeard: Bool.false, lastName: \"Doe\"})]})

View file

@ -0,0 +1,24 @@
---
source: crates/cli/tests/cli_tests.rs
expression: cli_dev_out.normalize_stdout_and_stderr()
---
── EXPECT FAILED in tests/test-projects/expects/expects.roc ────────────────────
This expectation failed:
25│ expect words == []
^^^^^^^^^^^
When it failed, these variables had these values:
words : List Str
words = ["this", "will", "for", "sure", "be", "a", "large", "string", "so", "when", "we", "split", "it", "it", "will", "use", "seamless", "slices", "which", "affect", "printing"]
Program finished!
[<ignored for tests>:28] x = 42
[<ignored for tests>:30] "Fjoer en ferdjer frieten oan dyn geve lea" = "Fjoer en ferdjer frieten oan dyn geve lea"
[<ignored for tests>:32] "this is line 24" = "this is line 24"
[<ignored for tests>:18] x = "abc"
[<ignored for tests>:18] x = 10
[<ignored for tests>:18] x = (A (B C))

View file

@ -0,0 +1,48 @@
---
source: crates/cli/tests/cli_tests.rs
expression: cli_test_out.normalize_stdout_and_stderr()
---
── EXPECT FAILED in tests/test-projects/expects/expects.roc ────────────────────
This expectation failed:
6│ expect a == 2
^^^^^^
When it failed, these variables had these values:
a : Num *
a = 1
── EXPECT FAILED in tests/test-projects/expects/expects.roc ────────────────────
This expectation failed:
7│ expect a == 3
^^^^^^
When it failed, these variables had these values:
a : Num *
a = 1
── EXPECT FAILED in tests/test-projects/expects/expects.roc ────────────────────
This expectation failed:
11│> expect
12│> a = makeA
13│> b = 2i64
14│>
15│> a == b
When it failed, these variables had these values:
a : Int Signed64
a = 1
b : I64
b = 2
1 failed and 0 passed in <ignored for test> ms.

View file

@ -0,0 +1,33 @@
---
source: crates/cli/tests/cli_tests.rs
expression: cli_dev_out.normalize_stdout_and_stderr()
---
App1.baseUrl: https://api.example.com/one
App2.baseUrl: http://api.example.com/two
App3.baseUrl: https://api.example.com/three
App1.getUser 1: https://api.example.com/one/users/1
App2.getUser 2: http://api.example.com/two/users/2
App3.getUser 3: https://api.example.com/three/users/3
App1.getPost 1: https://api.example.com/one/posts/1
App2.getPost 2: http://api.example.com/two/posts/2
App3.getPost 3: https://api.example.com/three/posts/3
App1.getPosts [1, 2]: ["https://api.example.com/one/posts/1", "https://api.example.com/one/posts/2"]
App2.getPosts [3, 4]: ["http://api.example.com/two/posts/3", "http://api.example.com/two/posts/4"]
App2.getPosts [5, 6]: ["http://api.example.com/two/posts/5", "http://api.example.com/two/posts/6"]
App1.getPostComments 1: https://api.example.com/one/posts/1/comments
App2.getPostComments 2: http://api.example.com/two/posts/2/comments
App2.getPostComments 3: http://api.example.com/two/posts/3/comments
App1.getCompanies [1, 2]: ["https://api.example.com/one/companies/1", "https://api.example.com/one/companies/2"]
App2.getCompanies [3, 4]: ["http://api.example.com/two/companies/3", "http://api.example.com/two/companies/4"]
App2.getCompanies [5, 6]: ["http://api.example.com/two/companies/5", "http://api.example.com/two/companies/6"]
App1.getPostAliased 1: https://api.example.com/one/posts/1
App2.getPostAliased 2: http://api.example.com/two/posts/2
App3.getPostAliased 3: https://api.example.com/three/posts/3
App1.baseUrlAliased: https://api.example.com/one
App2.baseUrlAliased: http://api.example.com/two
App3.baseUrlAliased: https://api.example.com/three
App1.getUserSafe 1: https://api.example.com/one/users/1
Prod.getUserSafe 2: http://api.example.com/prod_1/users/2?safe=true
usersApp1: ["https://api.example.com/one/users/1", "https://api.example.com/one/users/2", "https://api.example.com/one/users/3"]
getUserApp3Nested 3: https://api.example.com/three/users/3
usersApp3Passed: ["https://api.example.com/three/users/1", "https://api.example.com/three/users/2", "https://api.example.com/three/users/3"]

View file

@ -0,0 +1,43 @@
---
source: crates/cli/tests/cli_tests.rs
assertion_line: 429
expression: cli_dev_out.normalize_stdout_and_stderr()
---
── TOO MANY ARGS in tests/test-projects/module_params/arity_mismatch.roc ───────
The getUser function expects 1 argument, but it got 2 instead:
12│ $(Api.getUser 1 2)
^^^^^^^^^^^
Are there any missing commas? Or missing parentheses?
── TOO MANY ARGS in tests/test-projects/module_params/arity_mismatch.roc ───────
This value is not a function, but it was given 1 argument:
13│ $(Api.baseUrl 1)
^^^^^^^^^^^
Are there any missing commas? Or missing parentheses?
── TOO FEW ARGS in tests/test-projects/module_params/arity_mismatch.roc ────────
The getPostComment function expects 2 arguments, but it got only 1:
16│ $(Api.getPostComment 1)
^^^^^^^^^^^^^^^^^^
Roc does not allow functions to be partially applied. Use a closure to
make partial application explicit.
────────────────────────────────────────────────────────────────────────────────
3 error and 0 warning found in <ignored for test> ms
.
You can run <ignored for tests>

View file

@ -0,0 +1,48 @@
---
source: crates/cli/tests/cli_tests.rs
assertion_line: 445
expression: cli_dev_out.normalize_stdout_and_stderr()
---
── TYPE MISMATCH in tests/test-projects/module_params/BadAnn.roc ───────────────
Something is off with the body of the fnAnnotatedAsValue definition:
3│ fnAnnotatedAsValue : Str
4│> fnAnnotatedAsValue = \postId, commentId ->
5│> "/posts/$(postId)/comments/$(Num.toStr commentId)"
The body is an anonymous function of type:
Str, Num * -> Str
But the type annotation on fnAnnotatedAsValue says it should be:
Str
── TYPE MISMATCH in tests/test-projects/module_params/BadAnn.roc ───────────────
Something is off with the body of the missingArg definition:
7│ missingArg : Str -> Str
8│> missingArg = \postId, _ ->
9│> "/posts/$(postId)/comments"
The body is an anonymous function of type:
(Str, ? -> Str)
But the type annotation on missingArg says it should be:
(Str -> Str)
Tip: It looks like it takes too many arguments. I'm seeing 1 extra.
────────────────────────────────────────────────────────────────────────────────
2 error and 1 warning found in <ignored for test> ms
.
You can run <ignored for tests>

View file

@ -0,0 +1,28 @@
---
source: crates/cli/tests/cli_tests.rs
assertion_line: 476
expression: cli_dev_out.normalize_stdout_and_stderr()
---
── TYPE MISMATCH in tests/test-projects/module_params/unexpected_fn.roc ────────
This argument to this string interpolation has an unexpected type:
11│ $(Api.getPost)
^^^^^^^^^^^
The argument is an anonymous function of type:
U32 -> Str
But this string interpolation needs its argument to be:
Str
────────────────────────────────────────────────────────────────────────────────
1 error and 0 warning found in <ignored for test> ms
.
You can run <ignored for tests>

View file

@ -0,0 +1,11 @@
---
source: crates/cli/tests/cli_tests.rs
expression: cli_test_out.normalize_stdout_and_stderr()
---
Compiled in <ignored for test> ms.
Direct.roc:
0 failed and 2 passed in <ignored for test> ms.
Transitive.roc:
0 failed and 1 passed in <ignored for test> ms.

View file

@ -0,0 +1,17 @@
---
source: crates/cli/tests/cli_tests.rs
expression: cli_check_out.normalize_stdout_and_stderr()
---
── UNUSED IMPORT in tests/test-projects/known_bad/UnusedImport.roc ─────────────
Symbol is imported but not used.
3│ import Symbol exposing [Ident]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Since Symbol isn't used, you don't need to import it.
────────────────────────────────────────────────────────────────────────────────
0 error and 1 warning found in <ignored for test> ms

View file

@ -110,18 +110,10 @@ comptime {
pub export fn main() u8 { pub export fn main() u8 {
const stdout = std.io.getStdOut().writer(); const stdout = std.io.getStdOut().writer();
var timer = std.time.Timer.start() catch unreachable;
const result = roc__mainForHost_1_exposed(10); const result = roc__mainForHost_1_exposed(10);
const nanos = timer.read();
const seconds = (@as(f64, @floatFromInt(nanos)) / 1_000_000_000.0);
stdout.print("{d}\n", .{result}) catch unreachable; stdout.print("{d}\n", .{result}) catch unreachable;
const stderr = std.io.getStdErr().writer();
stderr.print("runtime: {d:.3}ms\n", .{seconds * 1000}) catch unreachable;
return 0; return 0;
} }

View file

@ -127,8 +127,6 @@ pub export fn main() u8 {
var roc_list = RocList{ .elements = numbers, .length = NUM_NUMS, .capacity = NUM_NUMS }; var roc_list = RocList{ .elements = numbers, .length = NUM_NUMS, .capacity = NUM_NUMS };
var timer = std.time.Timer.start() catch unreachable;
// actually call roc to populate the callresult // actually call roc to populate the callresult
const callresult: RocList = roc__mainForHost_1_exposed(roc_list); const callresult: RocList = roc__mainForHost_1_exposed(roc_list);
@ -136,9 +134,6 @@ pub export fn main() u8 {
const length = @min(20, callresult.length); const length = @min(20, callresult.length);
var result = callresult.elements[0..length]; var result = callresult.elements[0..length];
const nanos = timer.read();
const seconds = (@as(f64, @floatFromInt(nanos)) / 1_000_000_000.0);
for (result, 0..) |x, i| { for (result, 0..) |x, i| {
if (i == 0) { if (i == 0) {
stdout.print("[{}, ", .{x}) catch unreachable; stdout.print("[{}, ", .{x}) catch unreachable;
@ -149,12 +144,5 @@ pub export fn main() u8 {
} }
} }
const stderr = std.io.getStdErr().writer();
stderr.print("runtime: {d:.3}ms\n", .{seconds * 1000}) catch unreachable;
return 0; return 0;
} }
fn to_seconds(tms: std.os.timespec) f64 {
return @as(f64, @floatFromInt(tms.tv_sec)) + (@as(f64, @floatFromInt(tms.tv_nsec)) / 1_000_000_000.0);
}

View file

@ -1,7 +1,4 @@
app "quicksort" app [quicksort] { pf: platform "quicksort-platform/main.roc" }
packages { pf: "quicksort-platform/main.roc" }
imports []
provides [quicksort] to pf
quicksort = \originalList -> quicksort = \originalList ->
n = List.len originalList n = List.len originalList

View file

@ -1,4 +1,4 @@
app [main!] { pf: platform "../../../../examples/cli/effects-platform/main.roc" } app [main!] { pf: platform "../test-platform-effects-zig/main.roc" }
import pf.Effect import pf.Effect

View file

@ -1,4 +1,4 @@
app [main!] { pf: platform "../../../../examples/cli/effects-platform/main.roc" } app [main!] { pf: platform "../test-platform-effects-zig/main.roc" }
import pf.Effect import pf.Effect

View file

@ -1,4 +1,4 @@
app [main!] { pf: platform "../../../../examples/cli/effects-platform/main.roc" } app [main!] { pf: platform "../test-platform-effects-zig/main.roc" }
import pf.Effect import pf.Effect

View file

@ -1,12 +1,12 @@
# #
# Shows how Roc values can be logged # Shows how Roc values can be logged
# #
app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.16.0/O00IPk-Krg_diNS2dVWlI0ZQP794Vctxzv0ha96mK0E.tar.br" } app [main!] { pf: platform "../test-platform-effects-zig/main.roc" }
import pf.Stdout import pf.Effect
import Community import Community
main = main! = \{} ->
Community.empty Community.empty
|> Community.addPerson { |> Community.addPerson {
firstName: "John", firstName: "John",
@ -32,4 +32,4 @@ main =
|> Community.addFriend 0 2 |> Community.addFriend 0 2
|> Community.addFriend 1 2 |> Community.addFriend 1 2
|> Inspect.toStr |> Inspect.toStr
|> Stdout.line! |> Effect.putLine!

View file

@ -1,4 +1,4 @@
app [main!] { pf: platform "../../../../examples/cli/effects-platform/main.roc" } app [main!] { pf: platform "../test-platform-effects-zig/main.roc" }
import pf.Effect import pf.Effect

View file

@ -1,4 +1,4 @@
app [main!] { pf: platform "effects-platform/main.roc" } app [main!] { pf: platform "../test-platform-effects-zig/main.roc" }
import pf.Effect import pf.Effect

View file

@ -1,4 +1,4 @@
app [main!] { pf: platform "../../../../examples/cli/effects-platform/main.roc" } app [main!] { pf: platform "../test-platform-effects-zig/main.roc" }
import pf.Effect import pf.Effect

View file

@ -1,7 +1,4 @@
app "expects-test" app [main] { pf: platform "../test-platform-simple-zig/main.roc" }
packages { pf: "zig-platform/main.roc" }
imports []
provides [main] to pf
makeA = makeA =
a = 1 a = 1

View file

@ -1,10 +1,8 @@
interface Direct module [
exposes [ addAndStringify,
addAndStringify, ]
]
imports [ import Transitive
Transitive,
]
addAndStringify = \num1, num2 -> addAndStringify = \num1, num2 ->
Num.toStr (Transitive.add num1 num2) Num.toStr (Transitive.add num1 num2)

View file

@ -0,0 +1,7 @@
module [
add,
]
add = \num1, num2 -> (num1 + num2)
expect add 1 2 == 3

View file

@ -0,0 +1,3 @@
package [
Direct,
] {}

Some files were not shown because too many files have changed in this diff Show more