diff --git a/.github/workflows/nightly_macos_x86_64.yml b/.github/workflows/nightly_macos_x86_64.yml index bc33f0e475..d1a6f0edff 100644 --- a/.github/workflows/nightly_macos_x86_64.yml +++ b/.github/workflows/nightly_macos_x86_64.yml @@ -1,6 +1,6 @@ on: schedule: - - cron: '0 9 * * 1' # 9=9am utc+0, 1=monday + - cron: '0 9 * * *' # 9=9am utc+0 name: Nightly Release macOS x86_64 @@ -9,8 +9,8 @@ env: LLVM_SYS_130_PREFIX: /usr/local/opt/llvm jobs: - test-and-build: - name: Rust tests, build and package nightly release + test-build-upload: + name: build, test, package and upload nightly release runs-on: [macos-12] timeout-minutes: 90 steps: @@ -24,30 +24,42 @@ jobs: run: zig version - name: Install LLVM run: brew install llvm@13 + # build has to be done before tests #2572 - name: build release uses: actions-rs/cargo@v1 with: command: build args: --release --locked + - name: execute rust tests uses: actions-rs/cargo@v1 with: command: test - args: --locked # no --release yet until #3166 is fixed + args: --release --locked -- --skip opaque_wrap_function --skip bool_list_literal + + - name: get commit SHA + run: echo "SHA=$(git rev-parse --short "$GITHUB_SHA")" >> $GITHUB_ENV + + - name: get date + run: echo "DATE=$(date "+%Y-%m-%d")" >> $GITHUB_ENV + + - name: build file name + env: + DATE: ${{ env.DATE }} + SHA: ${{ env.SHA }} + run: echo "RELEASE_TAR_FILENAME=roc_nightly-macos_x86_64-$DATE-$SHA.tar.gz" >> $GITHUB_ENV + - name: write version to file run: ./ci/write_version.sh + - name: package release - run: ./ci/package_release.sh roc_darwin_x86_64.tar.gz - - name: Create pre-release with test_archive.tar.gz - uses: Anton-4/deploy-nightly@1609d8dfe211b078674801113ab7a2ec2938b2a9 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # automatically provided by github actions + run: ./ci/package_release.sh ${{ env.RELEASE_TAR_FILENAME }} + + - name: Upload artifact. Actually uploading to github releases has to be done manually. + uses: actions/upload-artifact@v3 with: - upload_url: https://uploads.github.com/repos/roc-lang/roc/releases/51880579/assets{?name,label} - release_id: 51880579 - asset_path: ./roc_darwin_x86_64.tar.gz - asset_name: roc_nightly-macos_x86_64-$$.tar.gz # $$ inserts 6 char commit hash and date (YYYY-MM-DD) - asset_content_type: application/gzip - max_releases: 3 + name: ${{ env.RELEASE_TAR_FILENAME }} + path: ${{ env.RELEASE_TAR_FILENAME }} + retention-days: 4 diff --git a/.github/workflows/spellcheck.yml b/.github/workflows/spellcheck.yml index ca7122af00..e26bfb3d37 100644 --- a/.github/workflows/spellcheck.yml +++ b/.github/workflows/spellcheck.yml @@ -12,7 +12,7 @@ env: jobs: spell-check: name: spell check - runs-on: [self-hosted, i7-6700K] + runs-on: [self-hosted] timeout-minutes: 10 env: FORCE_COLOR: 1 @@ -21,8 +21,5 @@ jobs: with: clean: "true" - - name: Earthly version - run: earthly --version - - - name: install spell checker, do spell check - run: ./ci/safe-earthly.sh +check-typos + - name: do spell check with typos-cli 1.0.11 # to reproduce locally: cargo install typos-cli --version 1.0.11 + run: typos diff --git a/.github/workflows/test_nightlies.yml b/.github/workflows/test_nightly_macos_apple_silicon.yml similarity index 90% rename from .github/workflows/test_nightlies.yml rename to .github/workflows/test_nightly_macos_apple_silicon.yml index afe7addb9d..3f2dc315cf 100644 --- a/.github/workflows/test_nightlies.yml +++ b/.github/workflows/test_nightly_macos_apple_silicon.yml @@ -5,7 +5,7 @@ on: name: Test latest nightly release for macOS Apple Silicon jobs: - test-and-build: + test-nightly: name: test nightly macos aarch64 runs-on: [self-hosted, macOS, ARM64] timeout-minutes: 90 @@ -16,7 +16,7 @@ jobs: run: curl https://api.github.com/repos/roc-lang/roc/releases > roc_releases.json - name: get the url of today`s release for macos apple silicon - run: echo "RELEASE_URL=$(./ci/get_latest_release_url.sh)" >> $GITHUB_ENV + run: echo "RELEASE_URL=$(./ci/get_latest_release_url.sh silicon)" >> $GITHUB_ENV - name: get the archive from the url run: curl -OL ${{ env.RELEASE_URL }} diff --git a/.github/workflows/test_nightly_macos_x86_64.yml b/.github/workflows/test_nightly_macos_x86_64.yml new file mode 100644 index 0000000000..d76007f965 --- /dev/null +++ b/.github/workflows/test_nightly_macos_x86_64.yml @@ -0,0 +1,34 @@ +on: + schedule: + - cron: '0 13 * * *' + +name: Test latest nightly release for macOS x86_64 + +jobs: + test-nightly: + name: test nightly macos x86_64 + runs-on: [ macos-12 ] + timeout-minutes: 90 + steps: + - uses: actions/checkout@v3 + + - name: fetch releases data and save to file + run: curl https://api.github.com/repos/roc-lang/roc/releases > roc_releases.json + + - name: get the url of today`s release for macos apple silicon + run: echo "RELEASE_URL=$(./ci/get_latest_release_url.sh macos_x86_64)" >> $GITHUB_ENV + + - name: get the archive from the url + run: curl -OL ${{ env.RELEASE_URL }} + + - name: remove everything in this dir except the tar # we want to test like a user who would have downloaded the release, so we clean up all files from the repo checkout + run: ls | grep -v "roc_nightly.*tar\.gz" | xargs rm -rf + + - name: decompress the tar + run: ls | grep "roc_nightly.*tar\.gz" | xargs tar -xzvf + + - name: test roc hello world + run: ./roc examples/hello-world/main.roc + + + diff --git a/Cargo.lock b/Cargo.lock index f7afd856eb..5a00409bf3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1638,9 +1638,9 @@ dependencies = [ [[package]] name = "glyph_brush" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69c65dd1f1fbb6209aa00f78636e436ad0a55b7d8e5de886d00720dcad9c6e2" +checksum = "ac02497410cdb5062cc056a33f2e1e19ff69fbf26a4be9a02bf29d6e17ea105b" dependencies = [ "glyph_brush_draw_cache", "glyph_brush_layout", diff --git a/Earthfile b/Earthfile index 5310740526..d67866328b 100644 --- a/Earthfile +++ b/Earthfile @@ -52,84 +52,6 @@ copy-dirs: FROM +install-zig-llvm-valgrind COPY --dir crates examples Cargo.toml Cargo.lock version.txt www ./ -test-zig: - FROM +install-zig-llvm-valgrind - COPY --dir crates/compiler/builtins/bitcode ./ - RUN cd bitcode && ./run-tests.sh && ./run-wasm-tests.sh - -build-rust-test: - FROM +copy-dirs - RUN echo "deb http://deb.debian.org/debian testing main contrib non-free" >> /etc/apt/sources.list # to get gcc 10.3 - RUN apt -y update - RUN apt -y install gcc-10 g++-10 && rm /usr/bin/gcc && ln -s /usr/bin/gcc-10 /usr/bin/gcc # gcc-9 maybe causes segfault - RUN gcc --version - RUN --mount=type=cache,target=$SCCACHE_DIR \ - cargo test --locked --release --features with_sound serde --workspace --no-run && sccache --show-stats - -check-typos: - RUN cargo install typos-cli --version 1.0.11 # version set to prevent confusion if the version is updated automatically - COPY --dir .github ci crates examples nightly_benches www *.md LEGAL_DETAILS flake.nix version.txt ./ - RUN typos - -test-rust: - FROM +build-rust-test - ENV ROC_WORKSPACE_DIR=/earthbuild - ENV RUST_BACKTRACE=1 - # for race condition problem with cli test - ENV ROC_NUM_WORKERS=1 - # run one of the benchmarks to make sure the host is compiled - # not pre-compiling the host can cause race conditions - RUN gcc --version - RUN echo "4" | cargo run --release examples/benchmarks/NQueens.roc - RUN --mount=type=cache,target=$SCCACHE_DIR \ - cargo test --locked --release --features with_sound serde --workspace && sccache --show-stats - # test the dev and wasm backend: they require an explicit feature flag. - RUN --mount=type=cache,target=$SCCACHE_DIR \ - cargo test --locked --release --package test_gen --no-default-features --features gen-dev && sccache --show-stats - # gen-wasm has some multithreading problems to do with the wasmer runtime. Run it single-threaded as a separate job - RUN --mount=type=cache,target=$SCCACHE_DIR \ - cargo test --locked --release --package test_gen --no-default-features --features gen-wasm -- --test-threads=1 && sccache --show-stats - # run `roc test` on Str builtins - RUN --mount=type=cache,target=$SCCACHE_DIR \ - cargo run --release -- test crates/compiler/builtins/roc/Str.roc && sccache --show-stats - # repl_test: build the compiler for wasm target, then run the tests on native target - RUN --mount=type=cache,target=$SCCACHE_DIR \ - crates/repl_test/test_wasm.sh && sccache --show-stats - # run i386 (32-bit linux) cli tests - # NOTE: disabled until zig 0.9 - # RUN echo "4" | cargo run --locked --release --features="target-x86" -- --target=x86_32 examples/benchmarks/NQueens.roc - # RUN --mount=type=cache,target=$SCCACHE_DIR \ - # cargo test --locked --release --features with_sound serde --test cli_run i386 --features="i386-cli-run" && sccache --show-stats - # make sure website deployment works (that is, make sure build.sh returns status code 0) - ENV REPL_DEBUG=1 - RUN bash www/build.sh - - -verify-no-git-changes: - FROM +test-rust - # If running tests caused anything to be changed or added (without being - # included in a .gitignore somewhere), fail the build! - # - # How it works: the `git ls-files` command lists all the modified or - # uncommitted files in the working tree, the `| grep -E .` command returns a - # zero exit code if it listed any files and nonzero otherwise (which is the - # opposite of what we want), and the `!` at the start inverts the exit code. - RUN ! git ls-files --deleted --modified --others --exclude-standard | grep -E . - -test-all: - BUILD +test-zig - BUILD +test-rust - BUILD +verify-no-git-changes - -build-nightly-release: - FROM +test-rust - COPY --dir .git LICENSE LEGAL_DETAILS ci ./ - # version.txt is used by the CLI: roc --version - RUN ./ci/write_version.sh - RUN RUSTFLAGS="-C target-cpu=x86-64" cargo build --features with_sound --release - RUN ./ci/package_release.sh roc_linux_x86_64.tar.gz - SAVE ARTIFACT ./roc_linux_x86_64.tar.gz AS LOCAL roc_linux_x86_64.tar.gz - # compile everything needed for benchmarks and output a self-contained dir from which benchmarks can be run. prep-bench-folder: FROM +copy-dirs diff --git a/ci/get_latest_release_url.sh b/ci/get_latest_release_url.sh index 4d060c8834..4fc7f2383d 100755 --- a/ci/get_latest_release_url.sh +++ b/ci/get_latest_release_url.sh @@ -2,7 +2,7 @@ # assumes roc_releases.json is present -LATEST_RELEASE_URL=`cat roc_releases.json | jq --arg today $(date +'%Y-%m-%d') '.[0] | .assets | map(.browser_download_url) | map(select(. | contains("silicon-\($today)"))) | .[0]'` +LATEST_RELEASE_URL=`cat roc_releases.json | jq --arg arch $1 --arg today $(date +'%Y-%m-%d') '.[0] | .assets | map(.browser_download_url) | map(select(. | contains("\($arch)-\($today)"))) | .[0]'` if [[ "$LATEST_RELEASE_URL" == "null" ]] then diff --git a/crates/cli/tests/cli_run.rs b/crates/cli/tests/cli_run.rs index 0ba74833fb..e476148c9a 100644 --- a/crates/cli/tests/cli_run.rs +++ b/crates/cli/tests/cli_run.rs @@ -386,7 +386,7 @@ mod cli_run { // 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/c-platform" => Example { + // platformSwitchingC:"platform-switching" => Example { // filename: "rocLovesC.roc", // executable_filename: "rocLovesC", // stdin: &[], @@ -394,7 +394,7 @@ mod cli_run { // expected_ending:"Roc <3 C!\n", // use_valgrind: true, // }, - platformSwitchingRust:"platform-switching/rust-platform" => Example { + platformSwitchingRust:"platform-switching" => Example { filename: "rocLovesRust.roc", executable_filename: "rocLovesRust", stdin: &[], @@ -402,7 +402,7 @@ mod cli_run { expected_ending:"Roc <3 Rust!\n", use_valgrind: true, }, - platformSwitchingSwift:"platform-switching/swift-platform" => Example { + platformSwitchingSwift:"platform-switching" => Example { filename: "rocLovesSwift.roc", executable_filename: "rocLovesSwift", stdin: &[], @@ -410,7 +410,7 @@ mod cli_run { expected_ending:"Roc <3 Swift!\n", use_valgrind: true, }, - platformSwitchingWebAssembly:"platform-switching/web-assembly-platform" => Example { + platformSwitchingWebAssembly:"platform-switching" => Example { filename: "rocLovesWebAssembly.roc", executable_filename: "rocLovesWebAssembly", stdin: &[], @@ -418,7 +418,7 @@ mod cli_run { expected_ending:"Roc <3 Web Assembly!\n", use_valgrind: true, }, - platformSwitchingZig:"platform-switching/zig-platform" => Example { + platformSwitchingZig:"platform-switching" => Example { filename: "rocLovesZig.roc", executable_filename: "rocLovesZig", stdin: &[], @@ -821,25 +821,6 @@ mod cli_run { if entry.file_type().unwrap().is_dir() { let example_dir_name = entry.file_name().into_string().unwrap(); - // TODO: Improve this with a more-dynamic approach. (Read all subdirectories?) - // Some platform-switching examples live in nested directories - if example_dir_name == "platform-switching" { - for sub_dir in [ - // 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. - // "c-platform", - "rust-platform", - "swift-platform", - "web-assembly-platform", - "zig-platform", - ] { - all_examples.remove(format!("{}/{}", example_dir_name, sub_dir).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, sub_dir); - }); - } - } - // We test benchmarks separately if example_dir_name != "benchmarks" { all_examples.remove(example_dir_name.as_str()).unwrap_or_else(|| { diff --git a/crates/compiler/builtins/bitcode/src/list.zig b/crates/compiler/builtins/bitcode/src/list.zig index aef91ef969..34f79cb3e2 100644 --- a/crates/compiler/builtins/bitcode/src/list.zig +++ b/crates/compiler/builtins/bitcode/src/list.zig @@ -148,9 +148,12 @@ pub const RocList = extern struct { ) RocList { if (self.bytes) |source_ptr| { if (self.isUnique()) { - const new_source = utils.unsafeReallocate(source_ptr, alignment, self.len(), new_length, element_width); - - return RocList{ .bytes = new_source, .length = new_length, .capacity = new_length }; + if (self.capacity >= new_length) { + return RocList{ .bytes = self.bytes, .length = new_length, .capacity = self.capacity }; + } else { + const new_source = utils.unsafeReallocate(source_ptr, alignment, self.len(), new_length, element_width); + return RocList{ .bytes = new_source, .length = new_length, .capacity = new_length }; + } } } @@ -727,17 +730,20 @@ pub fn listConcat(list_a: RocList, list_b: RocList, alignment: u32, element_widt return list_b; } else if (list_b.isEmpty()) { return list_a; - } else if (!list_a.isEmpty() and list_a.isUnique()) { + } else if (list_a.isUnique()) { const total_length: usize = list_a.len() + list_b.len(); if (list_a.bytes) |source| { - const new_source = utils.unsafeReallocate( - source, - alignment, - list_a.len(), - total_length, - element_width, - ); + const new_source = if (list_a.capacity >= total_length) + source + else + utils.unsafeReallocate( + source, + alignment, + list_a.len(), + total_length, + element_width, + ); if (list_b.bytes) |source_b| { @memcpy(new_source + list_a.len() * element_width, source_b, list_b.len() * element_width); diff --git a/crates/compiler/builtins/bitcode/src/str.zig b/crates/compiler/builtins/bitcode/src/str.zig index a8418a64e0..e6996d83a3 100644 --- a/crates/compiler/builtins/bitcode/src/str.zig +++ b/crates/compiler/builtins/bitcode/src/str.zig @@ -215,11 +215,14 @@ pub const RocStr = extern struct { return result; } - // NOTE: returns false for empty string! pub fn isSmallStr(self: RocStr) bool { return @bitCast(isize, self.str_capacity) < 0; } + test "isSmallStr: returns true for empty string" { + try expect(isSmallStr(RocStr.empty())); + } + fn asArray(self: RocStr) [@sizeOf(RocStr)]u8 { const as_ptr = @ptrCast([*]const u8, &self); const slice = as_ptr[0..@sizeOf(RocStr)]; @@ -1652,17 +1655,17 @@ pub fn strToUtf8C(arg: RocStr) callconv(.C) RocList { } inline fn strToBytes(arg: RocStr) RocList { - if (arg.isEmpty()) { + const length = arg.len(); + if (length == 0) { return RocList.empty(); } else if (arg.isSmallStr()) { - const length = arg.len(); const ptr = utils.allocateWithRefcount(length, RocStr.alignment); @memcpy(ptr, arg.asU8ptr(), length); return RocList{ .length = length, .bytes = ptr, .capacity = length }; } else { - return RocList{ .length = arg.len(), .bytes = arg.str_bytes, .capacity = arg.str_capacity }; + return RocList{ .length = length, .bytes = arg.str_bytes, .capacity = arg.str_capacity }; } } diff --git a/crates/compiler/builtins/bitcode/src/utils.zig b/crates/compiler/builtins/bitcode/src/utils.zig index 3783df0c48..818e531165 100644 --- a/crates/compiler/builtins/bitcode/src/utils.zig +++ b/crates/compiler/builtins/bitcode/src/utils.zig @@ -254,7 +254,7 @@ pub fn unsafeReallocate( const old_width = align_width + old_length * element_width; const new_width = align_width + new_length * element_width; - if (old_width == new_width) { + if (old_width >= new_width) { return source_ptr; } diff --git a/crates/compiler/gen_dev/src/generic64/aarch64.rs b/crates/compiler/gen_dev/src/generic64/aarch64.rs index 32309279a4..806b6b765f 100644 --- a/crates/compiler/gen_dev/src/generic64/aarch64.rs +++ b/crates/compiler/gen_dev/src/generic64/aarch64.rs @@ -834,6 +834,33 @@ impl Assembler for AArch64Assembler { fn ret(buf: &mut Vec<'_, u8>) { ret_reg64(buf, AArch64GeneralReg::LR) } + + fn and_reg64_reg64_reg64( + _buf: &mut Vec<'_, u8>, + _dst: AArch64GeneralReg, + _src1: AArch64GeneralReg, + _src2: AArch64GeneralReg, + ) { + todo!("bitwise and for AArch64") + } + + fn or_reg64_reg64_reg64( + _buf: &mut Vec<'_, u8>, + _dst: AArch64GeneralReg, + _src1: AArch64GeneralReg, + _src2: AArch64GeneralReg, + ) { + todo!("bitwise or for AArch64") + } + + fn xor_reg64_reg64_reg64( + _buf: &mut Vec<'_, u8>, + _dst: AArch64GeneralReg, + _src1: AArch64GeneralReg, + _src2: AArch64GeneralReg, + ) { + todo!("bitwise xor for AArch64") + } } impl AArch64Assembler {} diff --git a/crates/compiler/gen_dev/src/generic64/mod.rs b/crates/compiler/gen_dev/src/generic64/mod.rs index a271db6c53..6c0d63f292 100644 --- a/crates/compiler/gen_dev/src/generic64/mod.rs +++ b/crates/compiler/gen_dev/src/generic64/mod.rs @@ -143,6 +143,27 @@ pub trait Assembler: Sized + Copy { src2: GeneralReg, ); + fn and_reg64_reg64_reg64( + buf: &mut Vec<'_, u8>, + dst: GeneralReg, + src1: GeneralReg, + src2: GeneralReg, + ); + + fn or_reg64_reg64_reg64( + buf: &mut Vec<'_, u8>, + dst: GeneralReg, + src1: GeneralReg, + src2: GeneralReg, + ); + + fn xor_reg64_reg64_reg64( + buf: &mut Vec<'_, u8>, + dst: GeneralReg, + src1: GeneralReg, + src2: GeneralReg, + ); + fn call(buf: &mut Vec<'_, u8>, relocs: &mut Vec<'_, Relocation>, fn_name: String); /// Jumps by an offset of offset bytes unconditionally. @@ -1600,6 +1621,66 @@ impl< offset, }); } + + fn build_int_bitwise_and( + &mut self, + dst: &Symbol, + src1: &Symbol, + src2: &Symbol, + int_width: IntWidth, + ) { + let buf = &mut self.buf; + + match int_width { + IntWidth::U128 | IntWidth::I128 => todo!(), + _ => { + let dst_reg = self.storage_manager.claim_general_reg(buf, dst); + let src1_reg = self.storage_manager.load_to_general_reg(buf, src1); + let src2_reg = self.storage_manager.load_to_general_reg(buf, src2); + ASM::and_reg64_reg64_reg64(buf, dst_reg, src1_reg, src2_reg); + } + } + } + + fn build_int_bitwise_or( + &mut self, + dst: &Symbol, + src1: &Symbol, + src2: &Symbol, + int_width: IntWidth, + ) { + let buf = &mut self.buf; + + match int_width { + IntWidth::U128 | IntWidth::I128 => todo!(), + _ => { + let dst_reg = self.storage_manager.claim_general_reg(buf, dst); + let src1_reg = self.storage_manager.load_to_general_reg(buf, src1); + let src2_reg = self.storage_manager.load_to_general_reg(buf, src2); + ASM::or_reg64_reg64_reg64(buf, dst_reg, src1_reg, src2_reg); + } + } + } + + fn build_int_bitwise_xor( + &mut self, + dst: &Symbol, + src1: &Symbol, + src2: &Symbol, + int_width: IntWidth, + ) { + let buf = &mut self.buf; + + match int_width { + IntWidth::U128 | IntWidth::I128 => todo!(), + _ => { + let dst_reg = self.storage_manager.claim_general_reg(buf, dst); + let src1_reg = self.storage_manager.load_to_general_reg(buf, src1); + let src2_reg = self.storage_manager.load_to_general_reg(buf, src2); + ASM::xor_reg64_reg64_reg64(buf, dst_reg, src1_reg, src2_reg); + } + } + } } /// This impl block is for ir related instructions that need backend specific information. diff --git a/crates/compiler/gen_dev/src/generic64/x86_64.rs b/crates/compiler/gen_dev/src/generic64/x86_64.rs index 61d216ded5..fce88a8178 100644 --- a/crates/compiler/gen_dev/src/generic64/x86_64.rs +++ b/crates/compiler/gen_dev/src/generic64/x86_64.rs @@ -916,6 +916,22 @@ fn x86_64_generic_cleanup_stack<'a>( X86_64Assembler::pop_reg64(buf, X86_64GeneralReg::RBP); } +type Reg64 = X86_64GeneralReg; + +fn binop_move_src_to_dst_reg64(buf: &mut Vec<'_, u8>, f: F, dst: Reg64, src1: Reg64, src2: Reg64) +where + F: FnOnce(&mut Vec<'_, u8>, X86_64GeneralReg, X86_64GeneralReg), +{ + if dst == src1 { + f(buf, dst, src2); + } else if dst == src2 { + f(buf, dst, src1); + } else { + mov_reg64_reg64(buf, dst, src1); + f(buf, dst, src2); + } +} + impl Assembler for X86_64Assembler { // These functions should map to the raw assembly functions below. // In some cases, that means you can just directly call one of the direct assembly functions. @@ -954,22 +970,12 @@ impl Assembler for X86_64Assembler { mov_reg64_reg64(buf, dst, src1); add_reg64_imm32(buf, dst, imm32); } + #[inline(always)] - fn add_reg64_reg64_reg64( - buf: &mut Vec<'_, u8>, - dst: X86_64GeneralReg, - src1: X86_64GeneralReg, - src2: X86_64GeneralReg, - ) { - if dst == src1 { - add_reg64_reg64(buf, dst, src2); - } else if dst == src2 { - add_reg64_reg64(buf, dst, src1); - } else { - mov_reg64_reg64(buf, dst, src1); - add_reg64_reg64(buf, dst, src2); - } + fn add_reg64_reg64_reg64(buf: &mut Vec<'_, u8>, dst: Reg64, src1: Reg64, src2: Reg64) { + binop_move_src_to_dst_reg64(buf, add_reg64_reg64, dst, src1, src2) } + #[inline(always)] fn add_freg32_freg32_freg32( buf: &mut Vec<'_, u8>, @@ -1253,31 +1259,20 @@ impl Assembler for X86_64Assembler { #[inline(always)] fn movsx_reg64_base32(buf: &mut Vec<'_, u8>, dst: X86_64GeneralReg, offset: i32, size: u8) { debug_assert!(size <= 8); - if size == 8 { - Self::mov_reg64_base32(buf, dst, offset); - } else if size == 4 { - todo!("sign extending 4 byte values"); - } else if size == 2 { - todo!("sign extending 2 byte values"); - } else if size == 1 { - todo!("sign extending 1 byte values"); - } else { - internal_error!("Invalid size for sign extension: {}", size); + match size { + 8 => Self::mov_reg64_base32(buf, dst, offset), + 4 | 2 | 1 => todo!("sign extending {size} byte values"), + _ => internal_error!("Invalid size for sign extension: {size}"), } } #[inline(always)] fn movzx_reg64_base32(buf: &mut Vec<'_, u8>, dst: X86_64GeneralReg, offset: i32, size: u8) { debug_assert!(size <= 8); - if size == 8 { - Self::mov_reg64_base32(buf, dst, offset); - } else if size == 4 { - todo!("zero extending 4 byte values"); - } else if size == 2 { - todo!("zero extending 2 byte values"); - } else if size == 1 { - movzx_reg64_base8_offset32(buf, dst, X86_64GeneralReg::RBP, offset); - } else { - internal_error!("Invalid size for zero extension: {}", size); + match size { + 8 => Self::mov_reg64_base32(buf, dst, offset), + 4 | 2 => todo!("zero extending {size} byte values"), + 1 => movzx_reg64_base8_offset32(buf, dst, X86_64GeneralReg::RBP, offset), + _ => internal_error!("Invalid size for zero extension: {size}"), } } @@ -1408,6 +1403,18 @@ impl Assembler for X86_64Assembler { fn set_if_overflow(buf: &mut Vec<'_, u8>, dst: X86_64GeneralReg) { seto_reg64(buf, dst); } + + fn and_reg64_reg64_reg64(buf: &mut Vec<'_, u8>, dst: Reg64, src1: Reg64, src2: Reg64) { + binop_move_src_to_dst_reg64(buf, and_reg64_reg64, dst, src1, src2) + } + + fn or_reg64_reg64_reg64(buf: &mut Vec<'_, u8>, dst: Reg64, src1: Reg64, src2: Reg64) { + binop_move_src_to_dst_reg64(buf, or_reg64_reg64, dst, src1, src2) + } + + fn xor_reg64_reg64_reg64(buf: &mut Vec<'_, u8>, dst: Reg64, src1: Reg64, src2: Reg64) { + binop_move_src_to_dst_reg64(buf, xor_reg64_reg64, dst, src1, src2) + } } impl X86_64Assembler { @@ -1511,6 +1518,27 @@ fn add_reg64_reg64(buf: &mut Vec<'_, u8>, dst: X86_64GeneralReg, src: X86_64Gene binop_reg64_reg64(0x01, buf, dst, src); } +/// `AND r/m64,r64` -> Bitwise logical and r64 to r/m64. +#[inline(always)] +fn and_reg64_reg64(buf: &mut Vec<'_, u8>, dst: X86_64GeneralReg, src: X86_64GeneralReg) { + // NOTE: src and dst are flipped by design + binop_reg64_reg64(0x23, buf, src, dst); +} + +/// `OR r/m64,r64` -> Bitwise logical or r64 to r/m64. +#[inline(always)] +fn or_reg64_reg64(buf: &mut Vec<'_, u8>, dst: X86_64GeneralReg, src: X86_64GeneralReg) { + // NOTE: src and dst are flipped by design + binop_reg64_reg64(0x0B, buf, src, dst); +} + +/// `XOR r/m64,r64` -> Bitwise logical exclusive or r64 to r/m64. +#[inline(always)] +fn xor_reg64_reg64(buf: &mut Vec<'_, u8>, dst: X86_64GeneralReg, src: X86_64GeneralReg) { + // NOTE: src and dst are flipped by design + binop_reg64_reg64(0x33, buf, src, dst); +} + /// `ADDSD xmm1,xmm2/m64` -> Add the low double-precision floating-point value from xmm2/mem to xmm1 and store the result in xmm1. #[inline(always)] fn addsd_freg64_freg64(buf: &mut Vec<'_, u8>, dst: X86_64FloatReg, src: X86_64FloatReg) { @@ -2189,13 +2217,6 @@ fn push_reg64(buf: &mut Vec<'_, u8>, reg: X86_64GeneralReg) { } } -/// `XOR r/m64,r64` -> Xor r64 to r/m64. -#[inline(always)] -#[allow(dead_code)] -fn xor_reg64_reg64(buf: &mut Vec<'_, u8>, dst: X86_64GeneralReg, src: X86_64GeneralReg) { - binop_reg64_reg64(0x31, buf, dst, src); -} - // When writing tests, it is a good idea to test both a number and unnumbered register. // This is because R8-R15 often have special instruction prefixes. #[cfg(test)] @@ -2341,11 +2362,31 @@ mod tests { ); } + #[test] + fn test_and_reg64_reg64() { + disassembler_test!( + and_reg64_reg64, + |reg1, reg2| format!("and {reg1}, {reg2}"), + ALL_GENERAL_REGS, + ALL_GENERAL_REGS + ); + } + + #[test] + fn test_or_reg64_reg64() { + disassembler_test!( + or_reg64_reg64, + |reg1, reg2| format!("or {reg1}, {reg2}"), + ALL_GENERAL_REGS, + ALL_GENERAL_REGS + ); + } + #[test] fn test_xor_reg64_reg64() { disassembler_test!( xor_reg64_reg64, - |reg1, reg2| format!("xor {}, {}", reg1, reg2), + |reg1, reg2| format!("xor {reg1}, {reg2}"), ALL_GENERAL_REGS, ALL_GENERAL_REGS ); diff --git a/crates/compiler/gen_dev/src/lib.rs b/crates/compiler/gen_dev/src/lib.rs index 69f7caab19..ea36f1f9b3 100644 --- a/crates/compiler/gen_dev/src/lib.rs +++ b/crates/compiler/gen_dev/src/lib.rs @@ -499,6 +499,27 @@ trait Backend<'a> { ); self.build_num_sub(sym, &args[0], &args[1], ret_layout) } + LowLevel::NumBitwiseAnd => { + if let Layout::Builtin(Builtin::Int(int_width)) = ret_layout { + self.build_int_bitwise_and(sym, &args[0], &args[1], *int_width) + } else { + internal_error!("bitwise and on a non-integer") + } + } + LowLevel::NumBitwiseOr => { + if let Layout::Builtin(Builtin::Int(int_width)) = ret_layout { + self.build_int_bitwise_or(sym, &args[0], &args[1], *int_width) + } else { + internal_error!("bitwise or on a non-integer") + } + } + LowLevel::NumBitwiseXor => { + if let Layout::Builtin(Builtin::Int(int_width)) = ret_layout { + self.build_int_bitwise_xor(sym, &args[0], &args[1], *int_width) + } else { + internal_error!("bitwise xor on a non-integer") + } + } LowLevel::Eq => { debug_assert_eq!(2, args.len(), "Eq: expected to have exactly two argument"); debug_assert_eq!( @@ -750,6 +771,33 @@ trait Backend<'a> { /// build_num_sub stores the `src1 - src2` difference into dst. fn build_num_sub(&mut self, dst: &Symbol, src1: &Symbol, src2: &Symbol, layout: &Layout<'a>); + /// stores the `src1 & src2` into dst. + fn build_int_bitwise_and( + &mut self, + dst: &Symbol, + src1: &Symbol, + src2: &Symbol, + int_width: IntWidth, + ); + + /// stores the `src1 | src2` into dst. + fn build_int_bitwise_or( + &mut self, + dst: &Symbol, + src1: &Symbol, + src2: &Symbol, + int_width: IntWidth, + ); + + /// stores the `src1 ^ src2` into dst. + fn build_int_bitwise_xor( + &mut self, + dst: &Symbol, + src1: &Symbol, + src2: &Symbol, + int_width: IntWidth, + ); + /// build_eq stores the result of `src1 == src2` into dst. fn build_eq(&mut self, dst: &Symbol, src1: &Symbol, src2: &Symbol, arg_layout: &Layout<'a>); diff --git a/crates/compiler/gen_llvm/src/llvm/build.rs b/crates/compiler/gen_llvm/src/llvm/build.rs index 232376ee21..187ef33d5b 100644 --- a/crates/compiler/gen_llvm/src/llvm/build.rs +++ b/crates/compiler/gen_llvm/src/llvm/build.rs @@ -8,7 +8,6 @@ use crate::llvm::build_list::{ list_prepend, list_replace_unsafe, list_reserve, list_sort_with, list_sublist, list_swap, list_symbol_to_c_abi, list_with_capacity, pass_update_mode, }; -use crate::llvm::build_str::dec_to_str; use crate::llvm::compare::{generic_eq, generic_neq}; use crate::llvm::convert::{ self, argument_type_from_layout, basic_type_from_builtin, basic_type_from_layout, zig_str_type, @@ -65,7 +64,7 @@ use std::convert::TryInto; use std::path::Path; use target_lexicon::{Architecture, OperatingSystem, Triple}; -use super::convert::{zig_with_overflow_roc_dec, RocUnion}; +use super::convert::{zig_dec_type, zig_with_overflow_roc_dec, RocUnion}; #[inline(always)] fn print_fn_verification_output() -> bool { @@ -5821,24 +5820,60 @@ fn run_low_level<'a, 'ctx, 'env>( // Str.getScalarUnsafe : Str, Nat -> { bytesParsed : Nat, scalar : U32 } debug_assert_eq!(args.len(), 2); + use roc_target::OperatingSystem::*; + let string = load_symbol(scope, &args[0]); let index = load_symbol(scope, &args[1]); - let result = call_str_bitcode_fn( - env, - &[string], - &[index], - BitcodeReturns::Basic, - bitcode::STR_GET_SCALAR_UNSAFE, - ); + match env.target_info.operating_system { + Windows => { + // we have to go digging to find the return type + let function = env + .module + .get_function(bitcode::STR_GET_SCALAR_UNSAFE) + .unwrap(); - // on 32-bit platforms, zig bitpacks the struct - match env.target_info.ptr_width() { - PtrWidth::Bytes8 => result, - PtrWidth::Bytes4 => { - let to = basic_type_from_layout(env, layout); - complex_bitcast_check_size(env, result, to, "to_roc_record") + let return_type = function.get_type().get_param_types()[0] + .into_pointer_type() + .get_element_type() + .into_struct_type(); + + let result = env.builder.build_alloca(return_type, "result"); + + call_void_bitcode_fn( + env, + &[result.into(), string, index], + bitcode::STR_GET_SCALAR_UNSAFE, + ); + + let return_type = basic_type_from_layout(env, layout); + let cast_result = env.builder.build_pointer_cast( + result, + return_type.ptr_type(AddressSpace::Generic), + "cast", + ); + + env.builder.build_load(cast_result, "load_result") } + Unix => { + let result = call_str_bitcode_fn( + env, + &[string], + &[index], + BitcodeReturns::Basic, + bitcode::STR_GET_SCALAR_UNSAFE, + ); + + // on 32-bit platforms, zig bitpacks the struct + match env.target_info.ptr_width() { + PtrWidth::Bytes8 => result, + PtrWidth::Bytes4 => { + let to = basic_type_from_layout(env, layout); + complex_bitcast_check_size(env, result, to, "to_roc_record") + } + } + } + Wasi => unimplemented!(), } } StrCountUtf8Bytes => { @@ -7323,39 +7358,123 @@ fn build_float_binop<'a, 'ctx, 'env>( } } +fn dec_split_into_words<'a, 'ctx, 'env>( + env: &Env<'a, 'ctx, 'env>, + value: IntValue<'ctx>, +) -> (IntValue<'ctx>, IntValue<'ctx>) { + let int_64 = env.context.i128_type().const_int(64, false); + let int_64_type = env.context.i64_type(); + + let left_bits_i128 = env + .builder + .build_right_shift(value, int_64, false, "left_bits_i128"); + + ( + env.builder.build_int_cast(value, int_64_type, ""), + env.builder.build_int_cast(left_bits_i128, int_64_type, ""), + ) +} + +fn dec_alloca<'a, 'ctx, 'env>( + env: &Env<'a, 'ctx, 'env>, + value: IntValue<'ctx>, +) -> PointerValue<'ctx> { + let dec_type = zig_dec_type(env); + + let alloca = env.builder.build_alloca(dec_type, "dec_alloca"); + + let instruction = alloca.as_instruction_value().unwrap(); + instruction.set_alignment(16).unwrap(); + + let ptr = env.builder.build_pointer_cast( + alloca, + value.get_type().ptr_type(AddressSpace::Generic), + "cast_to_i128_ptr", + ); + + env.builder.build_store(ptr, value); + + alloca +} + +fn dec_to_str<'a, 'ctx, 'env>( + env: &Env<'a, 'ctx, 'env>, + dec: BasicValueEnum<'ctx>, +) -> BasicValueEnum<'ctx> { + use roc_target::OperatingSystem::*; + + let dec = dec.into_int_value(); + + match env.target_info.operating_system { + Windows => { + // + call_str_bitcode_fn( + env, + &[], + &[dec_alloca(env, dec).into()], + BitcodeReturns::Str, + bitcode::DEC_TO_STR, + ) + } + Unix => { + let (low, high) = dec_split_into_words(env, dec); + + call_str_bitcode_fn( + env, + &[], + &[low.into(), high.into()], + BitcodeReturns::Str, + bitcode::DEC_TO_STR, + ) + } + Wasi => unimplemented!(), + } +} + fn dec_binop_with_overflow<'a, 'ctx, 'env>( env: &Env<'a, 'ctx, 'env>, fn_name: &str, lhs: BasicValueEnum<'ctx>, rhs: BasicValueEnum<'ctx>, ) -> StructValue<'ctx> { + use roc_target::OperatingSystem::*; + let lhs = lhs.into_int_value(); let rhs = rhs.into_int_value(); let return_type = zig_with_overflow_roc_dec(env); let return_alloca = env.builder.build_alloca(return_type, "return_alloca"); - let int_64 = env.context.i128_type().const_int(64, false); - let int_64_type = env.context.i64_type(); + match env.target_info.operating_system { + Windows => { + call_void_bitcode_fn( + env, + &[ + return_alloca.into(), + dec_alloca(env, lhs).into(), + dec_alloca(env, rhs).into(), + ], + fn_name, + ); + } + Unix => { + let (lhs_low, lhs_high) = dec_split_into_words(env, lhs); + let (rhs_low, rhs_high) = dec_split_into_words(env, rhs); - let lhs1 = env - .builder - .build_right_shift(lhs, int_64, false, "lhs_left_bits"); - let rhs1 = env - .builder - .build_right_shift(rhs, int_64, false, "rhs_left_bits"); - - call_void_bitcode_fn( - env, - &[ - return_alloca.into(), - env.builder.build_int_cast(lhs, int_64_type, "").into(), - env.builder.build_int_cast(lhs1, int_64_type, "").into(), - env.builder.build_int_cast(rhs, int_64_type, "").into(), - env.builder.build_int_cast(rhs1, int_64_type, "").into(), - ], - fn_name, - ); + call_void_bitcode_fn( + env, + &[ + return_alloca.into(), + lhs_low.into(), + lhs_high.into(), + rhs_low.into(), + rhs_high.into(), + ], + fn_name, + ); + } + Wasi => unimplemented!(), + } env.builder .build_load(return_alloca, "load_dec") @@ -7368,29 +7487,37 @@ pub fn dec_binop_with_unchecked<'a, 'ctx, 'env>( lhs: BasicValueEnum<'ctx>, rhs: BasicValueEnum<'ctx>, ) -> BasicValueEnum<'ctx> { + use roc_target::OperatingSystem::*; + let lhs = lhs.into_int_value(); let rhs = rhs.into_int_value(); - let int_64 = env.context.i128_type().const_int(64, false); - let int_64_type = env.context.i64_type(); + match env.target_info.operating_system { + Windows => { + // windows is much nicer for us here + call_bitcode_fn( + env, + &[dec_alloca(env, lhs).into(), dec_alloca(env, rhs).into()], + fn_name, + ) + } + Unix => { + let (lhs_low, lhs_high) = dec_split_into_words(env, lhs); + let (rhs_low, rhs_high) = dec_split_into_words(env, rhs); - let lhs1 = env - .builder - .build_right_shift(lhs, int_64, false, "lhs_left_bits"); - let rhs1 = env - .builder - .build_right_shift(rhs, int_64, false, "rhs_left_bits"); - - call_bitcode_fn( - env, - &[ - env.builder.build_int_cast(lhs, int_64_type, "").into(), - env.builder.build_int_cast(lhs1, int_64_type, "").into(), - env.builder.build_int_cast(rhs, int_64_type, "").into(), - env.builder.build_int_cast(rhs1, int_64_type, "").into(), - ], - fn_name, - ) + call_bitcode_fn( + env, + &[ + lhs_low.into(), + lhs_high.into(), + rhs_low.into(), + rhs_high.into(), + ], + fn_name, + ) + } + Wasi => unimplemented!(), + } } fn build_dec_binop<'a, 'ctx, 'env>( diff --git a/crates/compiler/gen_llvm/src/llvm/build_str.rs b/crates/compiler/gen_llvm/src/llvm/build_str.rs index 26352a5580..b52639c96a 100644 --- a/crates/compiler/gen_llvm/src/llvm/build_str.rs +++ b/crates/compiler/gen_llvm/src/llvm/build_str.rs @@ -46,30 +46,6 @@ pub(crate) fn decode_from_utf8_result<'a, 'ctx, 'env>( } /// Dec.toStr : Dec -> Str -pub(crate) fn dec_to_str<'a, 'ctx, 'env>( - env: &Env<'a, 'ctx, 'env>, - dec: BasicValueEnum<'ctx>, -) -> BasicValueEnum<'ctx> { - let dec = dec.into_int_value(); - - let int_64 = env.context.i128_type().const_int(64, false); - let int_64_type = env.context.i64_type(); - - let dec_right_shift = env - .builder - .build_right_shift(dec, int_64, false, "dec_left_bits"); - - let right_bits = env.builder.build_int_cast(dec, int_64_type, ""); - let left_bits = env.builder.build_int_cast(dec_right_shift, int_64_type, ""); - - call_str_bitcode_fn( - env, - &[], - &[right_bits.into(), left_bits.into()], - BitcodeReturns::Str, - bitcode::DEC_TO_STR, - ) -} /// Str.equal : Str, Str -> Bool pub(crate) fn str_equal<'a, 'ctx, 'env>( diff --git a/crates/compiler/gen_llvm/src/llvm/convert.rs b/crates/compiler/gen_llvm/src/llvm/convert.rs index 41254d2f1d..e752e98b43 100644 --- a/crates/compiler/gen_llvm/src/llvm/convert.rs +++ b/crates/compiler/gen_llvm/src/llvm/convert.rs @@ -420,6 +420,10 @@ pub fn zig_str_type<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> StructType<'ct env.module.get_struct_type("str.RocStr").unwrap() } +pub fn zig_dec_type<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> StructType<'ctx> { + env.module.get_struct_type("dec.RocDec").unwrap() +} + pub fn zig_has_tag_id_type<'a, 'ctx, 'env>(env: &Env<'a, 'ctx, 'env>) -> StructType<'ctx> { let u8_ptr_t = env.context.i8_type().ptr_type(AddressSpace::Generic); diff --git a/crates/compiler/test_gen/src/gen_num.rs b/crates/compiler/test_gen/src/gen_num.rs index 4e3fd9df00..d6d32c986a 100644 --- a/crates/compiler/test_gen/src/gen_num.rs +++ b/crates/compiler/test_gen/src/gen_num.rs @@ -1299,7 +1299,7 @@ fn tan() { } #[test] -#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))] fn bitwise_and() { assert_evals_to!("Num.bitwiseAnd 20 20", 20, i64); assert_evals_to!("Num.bitwiseAnd 25 10", 8, i64); @@ -1307,7 +1307,7 @@ fn bitwise_and() { } #[test] -#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))] fn bitwise_xor() { assert_evals_to!("Num.bitwiseXor 20 20", 0, i64); assert_evals_to!("Num.bitwiseXor 15 14", 1, i64); @@ -1316,7 +1316,7 @@ fn bitwise_xor() { } #[test] -#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] +#[cfg(any(feature = "gen-llvm", feature = "gen-wasm", feature = "gen-dev"))] fn bitwise_or() { assert_evals_to!("Num.bitwiseOr 1 1", 1, i64); assert_evals_to!("Num.bitwiseOr 1 2", 3, i64); diff --git a/crates/compiler/test_gen/src/gen_records.rs b/crates/compiler/test_gen/src/gen_records.rs index 5d1e67f00a..adb7d0dae5 100644 --- a/crates/compiler/test_gen/src/gen_records.rs +++ b/crates/compiler/test_gen/src/gen_records.rs @@ -536,7 +536,7 @@ fn optional_field_let_no_use_default_nested() { { x ? 10, y } = r x + y - f { x: 4, y: 9 } + f { y: 9, x: 4 } "# ), 13, diff --git a/crates/compiler/test_gen/src/helpers/llvm.rs b/crates/compiler/test_gen/src/helpers/llvm.rs index c30787169e..6e4ea0ccb0 100644 --- a/crates/compiler/test_gen/src/helpers/llvm.rs +++ b/crates/compiler/test_gen/src/helpers/llvm.rs @@ -598,6 +598,14 @@ macro_rules! assert_llvm_evals_to { }; } +// windows testing code +// let mut target = target_lexicon::Triple::host(); +// +// target.operating_system = target_lexicon::OperatingSystem::Windows; +// +// let (_main_fn_name, _delayed_errors, _module) = +// $crate::helpers::llvm::create_llvm_module(&arena, $src, config, &context, &target); + #[allow(unused_macros)] macro_rules! assert_evals_to { ($src:expr, $expected:expr, $ty:ty) => {{ diff --git a/crates/editor/Cargo.toml b/crates/editor/Cargo.toml index 4f620de162..991d1917b9 100644 --- a/crates/editor/Cargo.toml +++ b/crates/editor/Cargo.toml @@ -40,7 +40,7 @@ page_size = "0.4.2" winit = "0.26.0" wgpu = "0.12.0" wgpu_glyph = "0.16.0" -glyph_brush = "0.7.2" +glyph_brush = "0.7.5" log = "0.4.14" env_logger = "0.9.0" futures = "0.3.24" diff --git a/crates/editor/editor-ideas.md b/crates/editor/editor-ideas.md index 6e0ac4d48c..00529894ee 100644 --- a/crates/editor/editor-ideas.md +++ b/crates/editor/editor-ideas.md @@ -313,6 +313,8 @@ e.g. you have a test `calculate_sum_test` that only uses the function `add`, whe * Plugin to translate linux commands like curl to Roc code * Plugin to view diff between two texts * Plugin to present codebase to new developer or walk co-worker through a problem. Records sequence of filenames and line numbers. +* A Logbook plugin. I've found that writing down steps and thoughts when you're implementing or debugging something can be really useful for later. +If we make an integrated terminal, we can automatically add executed commands to this logbook. This plugin could have a publish button so you can produce useful "blogs" for others with minimal effort. ### Inspiration diff --git a/examples/platform-switching/c-platform/rocLovesC.roc b/examples/platform-switching/rocLovesC.roc similarity index 64% rename from examples/platform-switching/c-platform/rocLovesC.roc rename to examples/platform-switching/rocLovesC.roc index 71e366a7b0..43e7f606f6 100644 --- a/examples/platform-switching/c-platform/rocLovesC.roc +++ b/examples/platform-switching/rocLovesC.roc @@ -1,5 +1,5 @@ app "rocLovesC" - packages { pf: "main.roc" } + packages { pf: "c-platform/main.roc" } imports [] provides [main] to pf diff --git a/examples/platform-switching/rust-platform/rocLovesRust.roc b/examples/platform-switching/rocLovesRust.roc similarity index 64% rename from examples/platform-switching/rust-platform/rocLovesRust.roc rename to examples/platform-switching/rocLovesRust.roc index ce0da7a63c..7d9c8da26b 100644 --- a/examples/platform-switching/rust-platform/rocLovesRust.roc +++ b/examples/platform-switching/rocLovesRust.roc @@ -1,5 +1,5 @@ app "rocLovesRust" - packages { pf: "main.roc" } + packages { pf: "rust-platform/main.roc" } imports [] provides [main] to pf diff --git a/examples/platform-switching/swift-platform/rocLovesSwift.roc b/examples/platform-switching/rocLovesSwift.roc similarity index 64% rename from examples/platform-switching/swift-platform/rocLovesSwift.roc rename to examples/platform-switching/rocLovesSwift.roc index 9413607c5a..8dcf22a97f 100644 --- a/examples/platform-switching/swift-platform/rocLovesSwift.roc +++ b/examples/platform-switching/rocLovesSwift.roc @@ -1,5 +1,5 @@ app "rocLovesSwift" - packages { pf: "main.roc" } + packages { pf: "swift-platform/main.roc" } imports [] provides [main] to pf diff --git a/examples/platform-switching/web-assembly-platform/rocLovesWebAssembly.roc b/examples/platform-switching/rocLovesWebAssembly.roc similarity index 64% rename from examples/platform-switching/web-assembly-platform/rocLovesWebAssembly.roc rename to examples/platform-switching/rocLovesWebAssembly.roc index 6a67749d14..ff550ad37a 100644 --- a/examples/platform-switching/web-assembly-platform/rocLovesWebAssembly.roc +++ b/examples/platform-switching/rocLovesWebAssembly.roc @@ -1,5 +1,5 @@ app "rocLovesWebAssembly" - packages { pf: "main.roc" } + packages { pf: "web-assembly-platform/main.roc" } imports [] provides [main] to pf diff --git a/examples/platform-switching/zig-platform/rocLovesZig.roc b/examples/platform-switching/rocLovesZig.roc similarity index 64% rename from examples/platform-switching/zig-platform/rocLovesZig.roc rename to examples/platform-switching/rocLovesZig.roc index ad9bdfa733..fe838c5396 100644 --- a/examples/platform-switching/zig-platform/rocLovesZig.roc +++ b/examples/platform-switching/rocLovesZig.roc @@ -1,5 +1,5 @@ app "rocLovesZig" - packages { pf: "main.roc" } + packages { pf: "zig-platform/main.roc" } imports [] provides [main] to pf diff --git a/examples/platform-switching/web-assembly-platform/README.md b/examples/platform-switching/web-assembly-platform/README.md index 2e77e5a0f0..192ebc7041 100644 --- a/examples/platform-switching/web-assembly-platform/README.md +++ b/examples/platform-switching/web-assembly-platform/README.md @@ -3,8 +3,8 @@ To run this website, first compile either of these identical apps: ```bash -# Option A: Compile examples/platform-switching/web-assembly-platform/rocLovesWebAssembly.roc -cargo run -- build --target=wasm32 examples/platform-switching/web-assembly-platform/rocLovesWebAssembly.roc +# Option A: Compile examples/platform-switching/rocLovesWebAssembly.roc +cargo run -- build --target=wasm32 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 diff --git a/getting_started/linux_x86.md b/getting_started/linux_x86.md index fdedf4853a..7fffcfe88a 100644 --- a/getting_started/linux_x86.md +++ b/getting_started/linux_x86.md @@ -38,9 +38,9 @@ ```sh # Note: If you installed Rust in this terminal session, you'll need to open a new one first! - ./roc examples/platform-switching/rust-platform/rocLovesRust.roc + ./roc examples/platform-switching/rocLovesRust.roc - ./roc examples/platform-switching/zig-platform/rocLovesZig.roc + ./roc examples/platform-switching/rocLovesZig.roc - ./roc examples/platform-switching/c-platform/rocLovesC.roc + ./roc examples/platform-switching/rocLovesC.roc ``` diff --git a/getting_started/macos_apple_silicon.md b/getting_started/macos_apple_silicon.md index de6c2b6332..a3b294e3de 100644 --- a/getting_started/macos_apple_silicon.md +++ b/getting_started/macos_apple_silicon.md @@ -34,9 +34,9 @@ ```sh # Note: If you installed rust in this terminal session, you'll need to open a new one first! - ./roc examples/platform-switching/rust-platform/rocLovesRust.roc + ./roc examples/platform-switching/rocLovesRust.roc - ./roc examples/platform-switching/zig-platform/rocLovesZig.roc + ./roc examples/platform-switching/rocLovesZig.roc - ./roc examples/platform-switching/c-platform/rocLovesC.roc + ./roc examples/platform-switching/rocLovesC.roc ``` diff --git a/getting_started/macos_x86.md b/getting_started/macos_x86.md index fc88823b2f..339f3e80e2 100644 --- a/getting_started/macos_x86.md +++ b/getting_started/macos_x86.md @@ -34,9 +34,9 @@ ```sh # Note: If you installed rust in this terminal session, you'll need to open a new one first! - ./roc examples/platform-switching/rust-platform/rocLovesRust.roc + ./roc examples/platform-switching/rocLovesRust.roc - ./roc examples/platform-switching/zig-platform/rocLovesZig.roc + ./roc examples/platform-switching/rocLovesZig.roc - ./roc examples/platform-switching/c-platform/rocLovesC.roc + ./roc examples/platform-switching/rocLovesC.roc ``` diff --git a/getting_started/other.md b/getting_started/other.md index 69b529c0bd..70f01dd2e5 100644 --- a/getting_started/other.md +++ b/getting_started/other.md @@ -7,11 +7,11 @@ 1. Run examples: ```sh - cargo run examples/platform-switching/rust-platform/rocLovesRust.roc + cargo run examples/platform-switching/rocLovesRust.roc # This requires installing the Zig compiler, too. - cargo run examples/platform-switching/zig-platform/rocLovesZig.roc + cargo run examples/platform-switching/rocLovesZig.roc # This requires installing the `clang` C compiler, too. - cargo run examples/platform-switching/c-platform/rocLovesC.roc + cargo run examples/platform-switching/rocLovesC.roc ``` diff --git a/typos.toml b/typos.toml index 32af51e47b..781867276f 100644 --- a/typos.toml +++ b/typos.toml @@ -1,2 +1,3 @@ [files] extend-exclude = ["crates/vendor/", "examples/static-site-gen/input/"] +